web-dev-qa-db-ja.com

シャードMongoDBでシャードバランサーをアクティブ化する方法

私は非常にシンプルなMongoDBデータベース構造を持っています。また、5つのシャードが含まれています(そのうち3つはレプリカセットです)。しかし、DBの読み込みをテストしており、シャードバランシングが現在有効になっていないようです。

mongosで次を確認しました:

mongos> sh.getBalancerState()
true
mongos> sh.isBalancerRunning()
false

BalancerRunningをtrueに設定できません。私は試した:

sh.startBalancer()

すべてのシャードで開始するのを手伝ってください。ありがとうございました。

3
bronze

基本的に、ここではいくつかの誤解があります。1つ目は、バランサーがロードバランサーであることです。そうではありません-シャードのチャンク数の不均衡に対処するためだけに見えます。これは、チャンクを移動するときにトラフィックのバランスをとるという副作用がありますが、厳密にはロードバランサーではありません。また、継続的に実行されるのではなく、実行する作業があり、対処すべき不均衡がある場合に実行されます。それ以外の場合は、休止状態です。

コマンドから得られる出力を説明するために、一度に1つずつ見ていきましょう。まず、sh.getBalancerState()の機能を見てみましょう(mongoシェルで括弧なしで関数を実行すると、その背後にあるコードが表示されます):

_mongos> sh.getBalancerState
function () {
    var x = db.getSisterDB( "config" ).settings.findOne({ _id: "balancer" } )
    if ( x == null )
        return true;
    return ! x.stopped;
}
_

したがって、そのコマンドが実行しているのは、構成データベースの設定コレクションをチェックして、バランサーが有効になっているかどうかを判断することです。バランサーを停止すると、設定の変更が表示されます。

_mongos> sh.stopBalancer()
Waiting for active hosts...
Waiting for the balancer lock...
Waiting again for active hosts after balancer is off...
mongos> sh.getBalancerState()
false
_

有効に戻すと、trueが再び返されます。

_mongos> sh.startBalancer()
mongos> sh.getBalancerState()
true
_

したがって、sh.getBalancerState()は基本的に設定を確認し、バランサーが有効になっているかどうかを通知するためのものです。それが話していないことは、バランサーが現在アクティブに実行されているかどうかです(つまり、不均衡をチェックし、見つかった不均衡に対処するために移行します)。それがsh.isBalancerRunning()の出番です。

ただし、バランサーが現在作業を行っていない場合、「実行中」ではないため、falseを返します。

_mongos> sh.isBalancerRunning()
false
_

したがって、やらなければならないことがいくつかあります。 この答え の例を再利用し、バランサーがオフのときに不均衡を作成します。事前分割が完了すると、sh.status()sh.getBalancerState()の出力は次のようになります。

_mongos> sh.getBalancerState()
false
mongos> sh.status()
--- Sharding Status --- 
  sharding version: {
    "_id" : 1,
    "version" : 3,
    "minCompatibleVersion" : 3,
    "currentVersion" : 4,
    "clusterId" : ObjectId("53b5d3b5d95df3a66a597548")
}
  shards:
    {  "_id" : "shard0000",  "Host" : "localhost:30000" }
    {  "_id" : "shard0001",  "Host" : "localhost:30001" }
    {  "_id" : "shard0002",  "Host" : "localhost:30002" }
  databases:
    {  "_id" : "admin",  "partitioned" : false,  "primary" : "config" }
    {  "_id" : "test",  "partitioned" : false,  "primary" : "shard0001" }
    {  "_id" : "users",  "partitioned" : true,  "primary" : "shard0001" }
        users.userInfo
            shard key: { "_id" : 1 }
            chunks:
                shard0001   2049
            too many chunks to print, use verbose if you want to force print
_

バランサーを再び有効にすると、2049(空の)チャンクを3つのシャードに均等に再配布するために行うべき多くの作業が必要になるため、sh.isBalancerRunning()を実行して取得する機会がたくさんありますポジティブ。興味深いことに、これをtrueに戻すために数回の試行が必要でした(簡潔にするために2つだけ示しています)。

_mongos> sh.isBalancerRunning()
false
mongos> sh.isBalancerRunning()
true
_

何故ですか?さて、もう一度関数を見てみましょう:

_mongos> sh.isBalancerRunning
function () {
    var x = db.getSisterDB("config").locks.findOne({ _id: "balancer" });
    if (x == null) {
        print("config.locks collection empty or missing. be sure you are connected to a mongos");
        return false;
    }
    return x.state > 0;
}
_

これは、今度もロックコレクションに対する、構成データベースに対するクエリです。バランサーに属するロックを探し、状態が0より大きい場合にtrueを返します。ドキュメントの2つの例を次に示します。1つはfalseを返し、もう1つはtrueを返します。

_db.getSisterDB("config").locks.findOne({ _id: "balancer" });
{
    "_id" : "balancer",
    "process" : "adamc-mbp:30999:1404425140:16807",
    "state" : 2,
    "ts" : ObjectId("53b5d86fd95df3a66a5975ff"),
    "when" : ISODate("2014-07-03T22:25:51.574Z"),
    "who" : "adamc-mbp:30999:1404425140:16807:Balancer:1622650073",
    "why" : "doing balance round"
}
db.getSisterDB("config").locks.findOne({ _id: "balancer" });
{
    "_id" : "balancer",
    "process" : "adamc-mbp:30999:1404425140:16807",
    "state" : 0,
    "ts" : ObjectId("53b5d86ed95df3a66a5975fe"),
    "when" : ISODate("2014-07-03T22:25:50.528Z"),
    "who" : "adamc-mbp:30999:1404425140:16807:Balancer:1622650073",
    "why" : "doing balance round"
}
_

よく見ると、tsフィールドが本質的に連続しており、空のチャンクで表示されるのは、ゼロ以外の状態が非常に過渡的であることがわかります。チャンクをデータで満たすと、ポジティブを生成するのがはるかに簡単になります。

そこにあります-実行していたコマンドの完全な説明と、表示した結果が得られた理由。質問の根本は実際にはトラフィックの不均衡に関連していると思いますが、一般的にそのタイプの問題を引き起こすのはバランサーではありません(前述のように、ロードバランサーではありません)。

  • 貧弱なシャードキー(おそらく非常に貧弱)
  • データベース/コレクションのバランスが有効になっていません(手順については、前の分割前の回答を参照してください)
  • 何かがバランサーの動作を妨げています(構成サーバーのダウン、バランサーウィンドウ、移行の中止)
4
Adam C

MongoDB Docs:

バランサーを有効または無効にします。 sh.getBalancerState()を使用してバランサーが現在有効か無効かを判断し、sh.isBalancerRunning()を使用して現在の状態を確認します。

シャードコレクションの分散: http://docs.mongodb.org/manual/core/sharding-balancing/

しかし、あなたの質問は dba.stackexchange.com に入るはずです

0
skozz