web-dev-qa-db-ja.com

モンゴの大きなチャンクは分割されません

3つのシャードをセットアップしていて容量が不足したため、さらに3つのシャードを追加しました。 (各シャードはレプリカセットです)。しかし、データはクラスター全体に均等に分散されていません。 chunkSizeを標準の64MBに設定しています。

mongos> db.settings.find( { _id:"chunksize" } )
{ "_id" : "chunksize", "value" : 64 }

これは、チャンクが64MBに達すると、サイズが32MBの2つの等しいチャンクに分割されることを意味すると思いました。それが実例です here 。違いますか?

これが私のシャーディングディストリビューションです:

mongos> db.accounts.getShardDistribution()
Shard rs_0 at rs_0/mongo_rs_0_member_1:27018,mongo_rs_0_member_2:27019,mongo_rs_0_member_3:27020
 data : 137.62GiB docs : 41991598 chunks : 1882
 estimated data per chunk : 74.88MiB
 estimated docs per chunk : 22312

Shard rs_1 at rs_1/mongo_rs_1_member_1:27018,mongo_rs_1_member_2:27019,mongo_rs_1_member_3:27020
 data : 135.2GiB docs : 41159069 chunks : 1882
 estimated data per chunk : 73.56MiB
 estimated docs per chunk : 21869

Shard rs_2 at rs_2/mongo_rs_2_member_1:27018,mongo_rs_2_member_2:27019,mongo_rs_2_member_3:27020
 data : 219.92GiB docs : 69739096 chunks : 1882
 estimated data per chunk : 119.66MiB
 estimated docs per chunk : 37055

Shard rs_3 at rs_3/mongo_rs_3_member_1:27018,mongo_rs_3_member_2:27019,mongo_rs_3_member_3:27020
 data : 101.52GiB docs : 30650628 chunks : 1882
 estimated data per chunk : 55.23MiB
 estimated docs per chunk : 16286

Shard rs_4 at rs_4/mongo_rs_4_member_1:27018,mongo_rs_4_member_2:27019,mongo_rs_4_member_3:27020
 data : 103.38GiB docs : 31071379 chunks : 1883
 estimated data per chunk : 56.22MiB
 estimated docs per chunk : 16500

Shard rs_5 at rs_5/mongo_rs_5_member_1:27018,mongo_rs_5_member_2:27019,mongo_rs_5_member_3:27020
 data : 101.1GiB docs : 30516395 chunks : 1881
 estimated data per chunk : 55.04MiB
 estimated docs per chunk : 16223

Totals
 data : 798.77GiB docs : 245128165 chunks : 11292
 Shard rs_0 contains 17.23% data, 17.13% docs in cluster, avg obj size on shard : 3KiB
 Shard rs_1 contains 16.92% data, 16.79% docs in cluster, avg obj size on shard : 3KiB
 Shard rs_2 contains 27.53% data, 28.45% docs in cluster, avg obj size on shard : 3KiB
 Shard rs_3 contains 12.7% data, 12.5% docs in cluster, avg obj size on shard : 3KiB
 Shard rs_4 contains 12.94% data, 12.67% docs in cluster, avg obj size on shard : 3KiB
 Shard rs_5 contains 12.65% data, 12.44% docs in cluster, avg obj size on shard : 3KiB

これどうしたの? chunkSizeに設定されている場合、最初の3つのシャード/レプリカセットの平均サイズが64 MBを超えるにはどうすればよいですか? Rs_2は119mbです! Rs_2には16.6%のはずのデータが27.53%あります。

シャードキーのカーディナリティは非常に高く、単調に増加するものではありません。

ここで何をすればいいですか?大きなチャンクを手動で見つけて分割することはできますが、それは面倒です。 chunkSizeを小さくしますか?これを自動的に行うために実行する必要があるサービス/呼び出しはありますか?

3
Landon

ここで説明することはたくさんあるので、まずは分割して、少しずつ説明します。

これは、チャンクが64MBに達すると、サイズが32MBの2つの等しいチャンクに分割されることを意味すると考えました。それがここで示されていることです。違いますか?

それはそれがどのように機能するかということではありません。 64MBのチャンクがあり、手動で splitFind コマンドを実行すると、中間点で(デフォルトで)2つのチャンクが分割されます。自動分割は別の方法で行われますが、詳細は実際にはかなり複雑ですが、経験則として私が説明するものを使用すると、十分に近くなります。

mongosは、各チャンクについて挿入/更新されたデータの量を追跡します(およそ)。最大チャンクサイズの20%(デフォルトでは12-13MiB)が特定のチャンクに書き込まれたことがわかると、そのチャンクの自動分割が試行されます。 splitVector コマンドをチャンクを所有するプライマリに送信して、チャンク範囲を評価し、潜在的な分割ポイントを返すように要求します。プライマリが有効なポイントで応答した場合、mongosはそれらのポイントで分割を試みます。有効な分割ポイントがない場合、mongosは、更新/書き込みが最大チャンクサイズの40%、60%に達すると、このプロセスを再試行します。

ご覧のとおり、これは分割前にチャンクが最大サイズに到達するのを待たず、実際にはそれよりもずっと前に発生するはずであり、通常動作しているクラスターでは、一般にそのような大きなチャンクは表示されません。

これどうしたの? chunkSizeに設定されている場合、最初の3つのシャード/レプリカセットの平均サイズが64 MBを超えるにはどうすればよいですか? Rs_2は119mbです!

大きなチャンクの発生を防ぐ唯一のことは、上記の自動分割機能です。チャンクの平均サイズは、何かがチャンクの分割を妨げていることを示しています。これにはいくつかの理由が考えられますが、最も一般的なのは、シャードキーの粒度が十分でないことです。

チャンクの範囲が1つのキー値まで下がった場合、それ以上分割できず、「ジャンボ」チャンクが取得されます。確実に範囲を確認する必要がありますが、おそらくsh.status(true)から簡単に手動で範囲を調べることができますが、より簡単に消化できるバージョンについては this Q&A を参照してくださいチャンク分布の決定について。

それが問題である場合、本当に2つの選択肢しかありません-ジャンボチャンクと一緒に住む(そして、最大チャンクサイズを増やして移動できるようにする-上限を超えるものはすべて中止され、mongosによって「ジャンボ」としてタグ付けされます)または、単一のキーチャンクの作成を防ぐ、よりきめ細かいシャードキーでデータを再シャーディングします。

Rs_2は16.6%であるはずのデータの27.53%を持っています。

これは、バランサーに関するかなり一般的な誤解です。データサイズに基づいてバランスをとるのではなく、チャンクの数のバランスをとるだけです(見た目はうまく分散されています)。その観点から、ドキュメントが0のチャンクは、 250kドキュメントの場合と同じです。したがって、データに関する不均衡の理由は、チャンク自体の不均衡が原因です(一部のチャンクは他のデータよりも多くのデータを含んでいます)。

ここで何をしますか?大きなチャンクを手動で見つけて分割することはできますが、それは面倒です。 chunkSizeを小さくしますか?

チャンクサイズを小さくすると、モンゴはスプリットポイントをより頻繁にチェックするようになりますが、スプリットが失敗している場合(チャンクサイズの平均がそうであるように)は役に立ちません。失敗する頻度が増えるだけです。最初のステップとして、最大のチャンク(上記のQ&Aリンクを参照)を見つけ、それらを優先度として最初に分割します。

手動で分割または移動する場合は、バランサーをオフにすることをお勧めします。これにより、バランサーがメタデータロックを保持せず、分割を開始してもすぐに動作しなくなります。また、通常はトラフィックの少ない時間に実行することをお勧めします。そうしないと、上記で説明した自動分割が干渉する可能性があるためです。

簡単な検索の後、すぐに手に入る一般的なものはありませんが、過去にこのプロセスを自動化するために使用されたスクリプトを見てきました。特定の問題に合わせてカスタマイズする必要がある傾向があります(たとえば、単調なシャードキーとチャンクデータ密度の問題による不均衡を想像してください)。

8
Adam C