1. ホーム
  2. データベース
  3. モンゴルディーブ

MongoDB にシャードレプリカセットを追加する方法

2022-01-19 08:59:32

   その背景はこうだ。LINEのMongoDBクラスタでは、過去のデータを大量に保持しており、時間フィールドごとにシャーディングされているのですが、最近2021年に一部のシャードに期限が迫っているため、より多くのデータを保持するために、現在のシャードに適切なシャードを追加する必要があるのです。

   オンライン環境では、各スライス自体が3コピーのレプリカセットになっているため、追加する際に注意すべき特有の処理があり、テスト環境で簡単に計測してドキュメント化しました。

    全体のおおよその流れとしては

1. 新しいシャーデッドレプリカセットを作成する

2. addShardコマンドを使用して、シャードレプリカセットをクラスタに追加します。

3. addShardTag コマンドを使用して、シャードにタグを付けます。

4. addTagRangeコマンドを使用して、タグ付けされたスライスのスライス・キーの値間隔を設定します。

   現在のテスト環境のアーキテクチャは

01 新しいコピーセットを作成する

   これからクラスタに追加するスライスはレプリカセットなので、このレプリカセットを事前に作成しておく必要があります。作成方法は比較的簡単で、これまでの手順で構築してください。リンクはこちらです。

MongoDB レプリカセットの構築

02 既存のクラスタにレプリカセットを追加する(addShard)

   このステップも比較的簡単で、mongosの管理データベースから直接addShardというコマンドを使って行うことができます。

db.runCommand({addShard:"sharding_yeyz1/127.0.0.1:27024,127.0.0.1:27025,127.0.0.1:27026"})

もちろん、db.runCommandコマンドの代わりに、db.adminCommandコマンドをそのまま使うことも可能です。2つのコマンドの違いは、adminCommandコマンドはデフォルトで管理者データベースの下で実行され、runCommandは現在のデータベースをデフォルトとすることです。

上記のコマンドで、ローカルを取る。

ポート27024、27025、27026がクラスタに追加されます。この時点で、アーキテクチャは次のようになります。

03 シャードタイムタグの追加(addShardTag)

     シャードがクラスタに追加された後、シャードにタグを追加する必要もあります。Tagを追加する目的は、現在のシャードでどの期間のビジネスデータを保持しているかを知らせることです。テスト環境では、以下のコマンドで1_1000と1000_2000というTagを使用してテストしています。

sh.addShardTag("sharding_yeyz", "1_1000")
sh.addShardTag("sharding_yeyz1", "1000_2000")

上記のコマンドの簡単な説明、ところ。

sharding_yeyzとsharding_yeyz1は、シャーディングされたレプリカセットの名前です。

1_1000 と 1000_2000 はタグの名前です。

追加されたタグは、システムのconfigライブラリのタグテーブルを通じて、以下のように確認することができます。

mongos> db.shards.find()
{ "_id" : "sharding_yeyz", "host" : "sharding_yeyz/127.0.0.1:27018,127.0.0.1:27019,127.0.0.1:27020& quot;, "state" : 1, "tags" : [ "1_1000" ] }
{ "_id" : "sharding_yeyz1", "host" : "sharding_yeyz1/127.0.0.1:27024,127.0.0.1:27025,127.0.0.1:27026& quot;, "state" : 1, "tags" : [ "1000_2000" ] }

04 型付きタグに特定の値域を追加する(addTagRange)

   タグを設定した後、各タグが表すスライスに特定の値域を設定する必要がありますが、これにはaddTagRange関数が必要で、次のように使用します。

sh.addTagRange( "new.test",
  { number: 1},
  { number: 1000},
  "1_1000"
  )
sh.addTagRange( "new.test",
  { number: 1000},
  { number: 2000},
  "1000_2000"
  )

ここでの値の範囲は、スライスされるそのコレクションのスライスキーの値の範囲であることに注意してください。

スライシングは常にコレクションに対して言われています。

上記のコマンドは、データベース new の下にある test コレクションをスライスし、そのスライスキー値がフィールド番号: であることを示しています。

numberが[1,1000]に属する場合、文書はこのスライスの"1_1000"、つまりsharding_yyzというタグに格納されます。

1000,2000)に属する場合、このスライス(sharding_yeyz1)の "1000_2000"のタグに格納されます。

なお、この区間は左閉じ、右開きである。

05 結果を見る

    スライスを追加し、スライスの値の範囲を設定した後、使用することができます。

db.printShardingStatus() コマンドまたは sh.status() コマンドを使用して、クラスタの現在のシャーディングの状態を確認します。

mongos> sh.status()
--- Sharding Status --- 
 sharding version: {
 "_id" : 1,
 "minCompatibleVersion" : 5,
 "currentVersion" : 6,
 "clusterId" : ObjectId("5fafaf4f5785d9965548f687")
 }
 shards:
 { "_id" : "sharding_yeyz", "host" : "sharding_yeyz/127.0.0.1:27018,127.0.0.1:27019,127.0.0.1:27020& quot;, "state" : 1, "tags" : [ "1_1000" ] }
 { "_id" : "sharding_yeyz1", "host" : "sharding_yeyz1/127.0.0.1:27024,127.0.0.1:27025,127.0.0.1:27026& quot;, "state" : 1, "tags" : [ "1000_", "1000_2000" ] }
 active mongoses:
 "4.0.6" : 1
 autosplit:
 Currently enabled: yes
 balancer:
 Currently enabled: yes
 Currently running: no
 Failed balancer rounds in last 5 attempts: 0
 Migration Results for the last 24 hours: 
  No recent migrations
 databases:
 { "_id" : "config", "primary" : "config", "partitioned" : true }
  config.system.sessions
   shard key: { "_id" : 1 }
   unique: false
   balancing: true
   chunks:
    sharding_yeyz 1
   { "_id" : { "$minKey" : 1 } } -->> { "_id" : { "$maxKey" : 1 } } on : sharding_yeyz Timestamp(1, 0) 
 { "_id" : "new", "primary" : "sharding_yeyz", "partitioned" : true, "version" : { "uuid" : { "$maxKey" : 1 } on : sharding_yeyz "uuid" : UUID("68c70c64-f732-4478-8851-06dad4b94d6b"), "lastMod" : 1 } }
  new.test
   shard key: { "number" : 1 }
   unique: false
   balancing: true
   chunks:
    sharding_yeyz 3
    sharding_yeyz1 1
   { "number" : { "$minKey" : 1 } } -->> { "number" : 1 } on : sharding_yeyz Timestamp(2, 1) 
   { "number" : 1 } -->> { "number" : 1000 } on : sharding_yeyz Timestamp(1, 2) 
   { "number" : 1000 } -->> { "number" : 2000 } on : sharding_yeyz1 Timestamp(2, 0) 
   { "number" : 2000 } -->> { "number" : { "$maxKey" : 1 } } on : sharding_yeyz Timestamp(1, 5) 
    tag: 1_1000 { "number" : 1 } -->> { "number" : 1000 }
    tag: 1000_2000 { "number" : 1000 } -->> { "number" : 2000 }

この時点で、まず以下のようなコマンドでテストデータ一式を生成し、最終的な結果の検証を開始します。

for (var i=1 ;i<=2000 ; i++){ db.test.insert({"number":i})}

各スライスのコンテンツを見に行くと、以下のことがわかります。

シャーディング

sharding_yeyz:PRIMARY> db.test.find().sort({"number":-1})
{ "_id" : ObjectId("5ffc051dd4c416daac620af5"), "number" : 2000 }
{ "_id" : ObjectId("5ffc0511d4c416daac620325"), "number" : 2000 }
{ "_id" : ObjectId("5ffc051bd4c416daac62070c"), "number" : 999 }
{ "_id" : ObjectId("5ffc050fd4c416daac61ff3c"), "number" : 999 }
{ "_id" : ObjectId("5ffc051bd4c416daac62070b"), "number" : 998 }
{ "_id" : ObjectId("5ffc050fd4c416daac61ff3b"), "number" : 998 }
{ "_id" : ObjectId("5ffc051bd4c416daac62070a"), "number" : 997 }
{ "_id" : ObjectId("5ffc050fd4c416daac61ff3a"), "number" : 997 }
{ "_id" : ObjectId("5ffc051bd4c416daac620709"), "number" : 996 }
{ "_id" : ObjectId("5ffc050fd4c416daac61ff39"), "number"