ウェブサイト検索

Ubuntu 12.04 VPSを使用してMongoDBでシャードクラスタを作成する方法


ステータス: 廃止された

この記事では、もはやサポートされていないUbuntuのバージョンについて説明しています。現在、Ubuntu 12.04を実行しているサーバーを運営している場合は、サポートされているバージョンのUbuntuにアップグレードまたは移行することを強くお勧めします。

  • Ubuntu 14.04にアップグレードします。
  • Ubuntu 14.04からUbuntu 16.04へのアップグレード
  • サーバーデータをサポートされているバージョンに移行する

理由: Ubuntu 12.04は2017年4月28日にサポートが終了(EOL)し、もはやセキュリティパッチやアップデートを受けることはありません。このガイドはもはや維持されていません。

代わりに見る: このガイドは参考としてまだ役立つかもしれませんが、他のUbuntuリリースでは機能しない可能性があります。もし可能であれば、使用しているUbuntuのバージョンに対して書かれたガイドを使用することを強くお勧めします。ページの上部にある検索機能を使って、より新しいバージョンを見つけることができます。

紹介

MongoDBは、水平に優れたスケーラビリティを持つNoSQLドキュメントデータベースシステムであり、キー・バリューシステムを通じてデータストレージを実装しています。ウェブアプリケーションやウェブサイトに人気の選択肢であるMongoDBは、プログラムで簡単に実装およびアクセスできます。

MongoDBは「シャーディング」と呼ばれる手法を用いてスケーリングを実現します。シャーディングは、読み込みと書き込みの負荷およびデータストレージの要件を分散させるために、データを異なるサーバーに書き込むプロセスです。

以前のチュートリアルでは、Ubuntu 12.04 VPSにMongoDBをインストールする方法を説明しました。これを出発点として、複数のノードにわたってシャーディングを実装する方法について話し合います。

MongoDB シャーディング トポロジー

シャーディングは三つの別々のコンポーネントを通じて実装されています。各部分は特定の機能を果たします:

  • 構成サーバー: 各生産シャーディング実装は、正確に3つの構成サーバーを含む必要があります。これは冗長性と高可用性を確保するためです。

    構成サーバーは、要求されたデータとそれを含むシャードをリンクするメタデータを保存するために使用されます。これにより、情報が信頼性高く一貫して取得できるようにデータが整理されます。

  • クエリルーター: クエリルーターは、アプリケーションが実際に接続するマシンです。これらのマシンは、設定サーバーと通信して、要求されたデータがどこに保存されているかを特定する責任があります。次に、適切なシャードからデータにアクセスし、返します。

    各クエリルーターは「mongos」コマンドを実行します。

  • シャードサーバー: シャードは実際のデータストレージ操作を担当しています。本番環境では、通常、単一のシャードは単一のマシンではなくレプリカセットで構成されています。これは、プライマリシャードサーバーがオフラインになった場合でも、データにアクセスできることを確保するためです。

    レプリカセットの実装はこのチュートリアルの範囲外なので、シャードをレプリカセットではなく単一のマシンとして構成します。ご自身の設定でレプリカセットを設定したい場合は、簡単に変更できます。

初期設定

上記に注意を払っていたなら、この構成にはかなりの数のマシンが必要であることに気づいたことでしょう。このチュートリアルでは、次のものを含む例のシャーディングクラスターを構成します:

  • 3つの構成サーバー(本番環境では必須)
  • 2つのクエリルーター(最低1つが必要)
  • 4つのシャードサーバー(最低2つが必要)

これは、正確に従うためには9つのVPSインスタンスが必要であることを意味します。実際には、これらの機能のいくつかは重複することがあります(例えば、クエリルーターを構成サーバーとして使用するのと同じVPS上で実行できます)ので、クエリルーターは1つ、シャードサーバーは最小2つだけあれば十分です。

各タイプの複数のコンポーネントを追加することを示すために、この最小値を超えます。 また、これらすべてのコンポーネントをディスクリートマシンとして扱い、明確さとシンプルさを追求します。

初期ベースイメージを設定する

始めるには、このガイドを使用してUbuntuに初期のMongoDBサーバーをインストールし、設定します。これを使用して、残りのシャーディングコンポーネントをブートストラップします。

最初のサーバーのチュートリアルが終了したら、このコマンドでインスタンスをシャットダウンしてください:

sudo shutdown -h now

さて、設定されたドロップレットのスナップショットを取り、それを使って他のVPSインスタンスを立ち上げることにしましょう。稼働中のシステムのスナップショットを取ることも可能ですが、シャットダウンすることでファイルシステムが一貫した状態になることが保証されます。スナップショットのコストは、ファイルシステム内で使用されているスペースに基づいて、1ギガバイトあたり月0.05ドルですので、作業が終わったらスナップショットを削除するのが最善かもしれません。

DigitalOcean コントロールパネルで、ドロップレットを選択します。「スナップショット」タブをクリックします。スナップショットの名前を入力し、「スナップショットを作成」をクリックします。

あなたのスナップショットが撮影され、初期サーバーが再起動されます。

スナップショットに基づいてVPSインスタンスを起動する

スナップショットプロセスを通じて画像を保存したので、これをMongoDBコンポーネントの残りの部分のベースとして使用できます。

コントロールパネルから「作成」ボタンをクリックします。シャーディング構成において、ドロップレットの目的を説明する名前を入力してください:

雫のサイズと地域を選択してください。すべてのコンポーネントに同じ地域を選ぶのが最適です。

「画像を選択」セクションで、「マイ画像」タブをクリックし、先ほど作成したMongoDBスナップショットを選択してください。

必要なSSHキーを追加し、使用したい設定を選択してください。新しいVPSインスタンスを作成するには「ドロップレットを作成」をクリックしてください。

このステップを各シャーディングコンポーネントに対して繰り返してください。このチュートリアルに正確に従うためには(必須ではありませんが、デモンストレーションのため)、3つの設定サーバー、2つのクエリーサーバー、および4つのシャードサーバーが必要です。

各コンポーネントのためにDNSサブドメインエントリを設定する(オプション)

MongoDBのドキュメントでは、特定のIPアドレスではなく、すべてのコンポーネントをDNS解決可能な名前で参照することを推奨しています。これは、サーバーを変更したり、特定のコンポーネントを再デプロイした際に、それに関連するすべてのサーバーを再起動する必要がなくなるため、重要です。

使いやすさのために、各サーバーに使用したいドメインの独自のサブドメインを付けることをお勧めします。このガイドを使って、DigitalOceanのコントロールパネルを使用してDNSサブドメインを設定する方法を学ぶことができます。

このチュートリアルの目的のために、私たちはこれらのサブドメインでコンポーネントが利用可能であると呼びます。

  • 設定サーバー

    • config0.example.com
    • config1.example.com
    • config2.example.com
  • クエリルーター

    • query0.example.com
    • query1.example.com
  • シャードサーバー

    • shard0.example.com
    • shard1.example.com
    • shard2.example.com
    • shard3.example.com

サブドメインを設定しない場合でも、引き続き作業を行うことはできますが、設定はそれほど強固ではありません。この方法を選択する場合は、サブドメインの仕様をドロップレットのIPアドレスに置き換えるだけです。

構成サーバーを初期化する

最初に設定する必要があるコンポーネントは、構成サーバです。これらは、クエリルーターやシャードを構成する前に、オンラインで稼働している必要があります。

最初の構成サーバーにrootとしてログインしてください。

最初に行う必要があるのは、データディレクトリを作成することです。ここが構成サーバーが位置とコンテンツを関連付けるメタデータを保存する場所になります。

mkdir /mongo-metadata

さて、適切なパラメータで構成サーバーを起動する必要があります。この構成サーバーを提供するサービスは mongod と呼ばれています。このコンポーネントのデフォルトのポート番号は 27019 です。

次のコマンドで構成サーバーを起動できます:

mongod --configsvr --dbpath /mongo-metadata --port 27019

サーバーは情報の出力を開始し、他のコンポーネントからの接続を待ち始めます。

このプロセスを他の2つの構成サーバーで正確に繰り返してください。ポート番号は3つのサーバーすべてで同じである必要があります。

クエリルーターインスタンスを設定する

この時点で、3つの構成サーバーがすべて稼働して接続を待機している必要があります。 続行する前に、これらが動作している必要があります。

最初のクエリルーターにrootとしてログインしてください。

最初に行うべきことは、このインスタンス上で既に実行中である場合、mongodbプロセスを停止することです。クエリルーターは、メインのMongoDBプロセスと競合するデータロックを使用します。

service mongodb stop

次に、特定の設定文字列を使用してクエリルータサービスを起動する必要があります。設定文字列は、設定するすべてのクエリルータで完全に同じでなければならず(引数の順序も含む)、各設定サーバーのアドレスとその動作しているポート番号をカンマで区切って構成されています。

彼らのクエリルーターサービスはmongosと呼ばれています。このプロセスのデフォルトポート番号は27017です(ただし、設定内のポート番号は設定サーバーのポート番号を指し、これはデフォルトで27019です)。

最終的な結果は、クエリルーターサービスが次のような文字列で開始されることです:

 mongos --configdb config0.example.com:27019,config1.example.com:27019,config2.example.com:27019 

最初のクエリルーターは、3つの構成サーバーに接続を開始する必要があります。他のクエリルーターでもこれらの手順を繰り返してください。コマンドを入力する前に、mongodbサービスを停止する必要があることを忘れないでください。

また、各クエリルーターを起動するには正確に同じコマンドを使用する必要があることを忘れないでください。そうしないとエラーが発生します。

クラスターにシャードを追加する

私たちは構成サーバーとクエリルーターを設定したので、実際のシャードサーバーをクラスタに追加し始めることができます。これらのシャードはそれぞれ、全体のデータの一部を保持します。

ルートとしてシャードサーバーの1つにログインします。

冒頭で言及したように、このガイドではレプリカセットの代わりに単一のマシンシャードのみを使用します。これは、簡潔さとデモの単純さのためです。本番環境では、データの完全性と可用性を確保するためにレプリカセットの使用が強く推奨されます。MongoDBでレプリカセットを構成するには、このガイドに従ってください。

クラスターにシャードを実際に追加するには、現在クラスターとのインターフェースとして機能するように設定されたクエリルーターを通過する必要があります。これを行うには、次のようにして任意のクエリルーターに接続します:

 mongo --host query0.example.com --port 27017 

これにより、適切なクエリルーターに接続され、Mongoのプロンプトが開かれます。このプロンプトからすべてのシャードサーバーを追加します。

最初のシャードを追加するには、次のように入力してください:

 sh.addShard( "shard0.example.com:27017 " ) 

それから、残りのシャードドロップレットをこの同じインターフェースに追加できます。各シャードサーバーに個別にログインする必要はありません。

 sh.addShard( “<span class=“highlight ”>shard1.example.com</span>:27017 ” ) sh.addShard( “<span class=“highlight ”>shard2.example.com</span>:27017 ” ) sh.addShard( “<span class=“highlight ”>shard3.example.com</span>:27017 ” ) </pre>

本番クラスターを設定している場合、レプリケーションセットを含めて、各セットを別々のシャードとして確立するために、代わりにレプリケーションセット名とレプリケーションセットメンバーを指定しなければなりません。構文は次のようになります:

sh.addShard("rep_set_name/rep_set_member:27017")

データベースコレクションのシャーディングを有効にする方法

MongoDBは情報をデータベースに整理します。それぞれのデータベース内で、データは「コレクション」によってさらに区分けされます。コレクションは、従来のリレーショナルデータベースモデルにおけるテーブルに似ています。

このセクションでは、再びクエリルーターを使用して操作します。もしまだクエリルーターに接続していない場合は、前のセクションで使用した同じmongoコマンドを使って再度アクセスできます。

 mongo --host config0.example.com --port 27017 

データベースレベルでシャーディングを有効にする

まず、データベースレベルでシャーディングを有効にします。これを行うために、適切に名付けられたテストデータベースtest_dbを作成します。

このデータベースを作成するには、単にそれに切り替える必要があります。それは私たちの現在のデータベースとしてマークされ、最初にデータを入力する際に動的に作成されます。

use test_db

私たちは、次のように入力することで、現在作成したデータベースを使用していることを確認できます:

db
test_db

利用可能なデータベースをすべて見るには、次のように入力します:

show dbs

作成したばかりのデータベースが表示されないことに気付くかもしれません。これは、データを含んでいないため、まだ実際のものではないからです。

このデータベースでシャーディングを有効にするには、次のコマンドを実行します:

sh.enableSharding("test_db")

再度、show dbs コマンドを入力しても、新しいデータベースは表示されません。ただし、自動的に生成される config データベースに切り替え、find() コマンドを発行すると、新しいデータベースが返されます:

use config
db.databases.find()
{ "_id" : "admin", "partitioned" : false, "primary" : "config" }
{ "_id" : "test_db", "partitioned" : true, "primary" : "shard0003" }

MongoDB が新しいデータベースにデータを追加すると、show dbs コマンドを使用すると、あなたのデータベースが表示されます。

コレクションレベルでシャーディングを有効にする

私たちのデータベースがシャーディング可能としてマークされたので、特定のコレクションでシャーディングを有効にすることができます。

この時点で、シャーディング戦略を決定する必要があります。シャーディングは、保存しているドキュメントの特定のフィールドとして指定されたシャードキーに基づいてデータを異なるカテゴリに整理することで機能します。それは、マッチするシャードキーを持つすべてのドキュメントを同じシャードに配置します。

例えば、あなたのデータベースが会社の従業員を保存していて、シャードキーが好きな色に基づいている場合、MongoDBは好きな色のフィールドに青を持つすべての従業員を単一のシャードに配置します。これにより、みんながいくつかの色を好む場合、不均衡なストレージが生じる可能性があります。

シャードキーとしてより良い選択は、より均等に分散されることが保証されている何かです。たとえば、大企業では、誕生日(年月日)フィールドはおそらくかなり均等に分散されているでしょう。

物事がどのように分配されるかわからない場合や、適切なフィールドがない場合は、既存のフィールドに基づいて「ハッシュ化」されたシャードキーを作成することができます。これが私たちのデータに対して行うことです。

私たちはtest_collectionというコレクションを作成し、その「_id」フィールドをハッシュ化することができます。私たちのtest_dbデータベースを使用していることを確認し、その後コマンドを発行します:

use test_db
db.test_collection.ensureIndex( { _id : "hashed" } )

次に、このコマンドを発行してコレクションをシャーディングできます:

sh.shardCollection("test_db.test_collection", { "_id": "hashed" } )

これにより、コレクションは利用可能なすべてのシャードに分散されます。

コレクションにテストデータを挿入する

オブジェクトを作成するためにループを使用することで、シャーディングの動作を確認できます。このループは、テストデータを生成するためのMongoDBのウェブサイトから直接来ています。

このような簡単なループを使って、コレクションにデータを挿入することができます:

use test_db
for (var i = 1; i <= 500; i++) db.test_collection.insert( { x : i } )

これにより、500のシンプルなドキュメント(IDフィールドと数字を含む「x」フィールドのみ)が作成され、異なるシャードに配布されます。 結果は次のように入力することで確認できます:

db.test_collection.find()
{ "_id" : ObjectId("529d082c488a806798cc30d3"), "x" : 6 }
{ "_id" : ObjectId("529d082c488a806798cc30d0"), "x" : 3 }
{ "_id" : ObjectId("529d082c488a806798cc30d2"), "x" : 5 }
{ "_id" : ObjectId("529d082c488a806798cc30ce"), "x" : 1 }
{ "_id" : ObjectId("529d082c488a806798cc30d6"), "x" : 9 }
{ "_id" : ObjectId("529d082c488a806798cc30d1"), "x" : 4 }
{ "_id" : ObjectId("529d082c488a806798cc30d8"), "x" : 11 }
. . .

より多くの値を取得するには、次のように入力してください:

it
{ "_id" : ObjectId("529d082c488a806798cc30cf"), "x" : 2 }
{ "_id" : ObjectId("529d082c488a806798cc30dd"), "x" : 16 }
{ "_id" : ObjectId("529d082c488a806798cc30d4"), "x" : 7 }
{ "_id" : ObjectId("529d082c488a806798cc30da"), "x" : 13 }
{ "_id" : ObjectId("529d082c488a806798cc30d5"), "x" : 8 }
{ "_id" : ObjectId("529d082c488a806798cc30de"), "x" : 17 }
{ "_id" : ObjectId("529d082c488a806798cc30db"), "x" : 14 }
{ "_id" : ObjectId("529d082c488a806798cc30e1"), "x" : 20 }
. . .

特定のシャードに関する情報を取得するには、次のように入力できます:

sh.status()
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "version" : 3,
    "minCompatibleVersion" : 3,
    "currentVersion" : 4,
    "clusterId" : ObjectId("529cae0691365bef9308cd75")
}
  shards:
    {  "_id" : "shard0000",  "host" : "162.243.243.156:27017" }
    {  "_id" : "shard0001",  "host" : "162.243.243.155:27017" }
. . .

これは、MongoDBがシャード間で分散したチャンクに関する情報を提供します。

結論

このガイドの終わりまでには、自分自身のMongoDBシャーディング設定を実装できるようになるはずです。サーバーの具体的な設定や、各コレクションのために選択するシャードキーは、クラスターのパフォーマンスに大きな影響を与えます。

データベースクエリに反映される論理的なグルーピングを最もよく表す分布特性を持つフィールドを選択してください。MongoDBがデータを取得するために単一のシャードにしかアクセスしない場合、より迅速に返されます。

ジャスティン・エリングウッドによる

関連記事: