MongoDBとRAMに収まらないデータセットは、いくら突き詰めても


12

これはシステムに大きく依存しますが、任意の崖を越えてスケールし、実際のトラブルに陥る可能性はほぼ確実です。RAMとディスク領域の比率を適切にするには、どのような経験則が存在するのか興味があります。次のラウンドのシステムを計画しており、RAM、SSD、および各新規ノードの取得量に関していくつかの選択を行う必要があります。

しかし、今度はパフォーマンスの詳細について説明します!

単一のプロジェクト実行の通常のワークフロー中に、MongoDBは非常に高い割合の書き込み(70〜80%)でヒットします。処理パイプラインの2番目のステージがヒットすると、処理の前半で識別されたレコードを重複排除する必要があるため、読み取りが非常に高くなります。これは、「ワーキングセットをRAMに保持する」ためのワークフローであり、その前提に基づいて設計しています。

データセット全体は、エンドユーザーから派生したソースからのランダムクエリで継続的にヒットします。頻度は不規則ですが、サイズは通常かなり小さい(10個のドキュメントのグループ)。これはユーザー向けであるため、返信は「退屈」しきい値の3秒未満である必要があります。このアクセスパターンはキャッシュ内にある可能性がはるかに低いため、ディスクヒットが発生する可能性が非常に高くなります。

二次処理ワークフローは、数日、数週間、さらには数か月前に実行された前の処理実行の読み取り値が高く、実行頻度は低いですが、依然としてジッピーである必要があります。前の処理実行で最大100%のドキュメントにアクセスします。これを助けることができるキャッシュウォーミングの量はないと思います。

完成したドキュメントのサイズは大きく異なりますが、サイズの中央値は約8Kです。

通常のプロジェクト処理の読み取り率が高い部分は、読み取りトラフィックの分散に役立つレプリカの使用を強く示唆しています。私は別の場所で、1/10のRAM-GBからHD-GBが低速ディスクの経験則あることを読んだことがあります。高速ディスクの大まかな目安。

私は、キャッシュのすべてが実際に飛行しない方法でMongoを使用していることを知っています。そのため、このような使用に耐えられるシステムを設計する方法を検討しています。全体のデータセットは、おそらく半年以内TBの最も可能と成長を維持します。


よく聞かれる難しい質問。
グワルド

正直に言って、IOを大幅に調整する前に、おそらく書き込みロックの問題が発生するようです。書き込みでDBを叩くと、基本的なIOの速度に関係なく、クエリが停止するほど書き込みロックを長く保持する可能性があります。Fusion IOのようなものは書き込みロックを少し減らすことができますが、少し時間がかかるだけで、実際の修正ではありません。
-MrKurt

@MrKurt私が理解しようとしていることの一部は、個々のレプリカノードを作成する方法に加えて、シャードする必要がある場合です。私の暫定仕様には、PCIeベースのSSDカードが関係しています。
sysadmin1138

ああ、わかった。シャーディングを最初から検討することもできますが、単一サーバーのシャーディングを頻繁に行います。これにより、書き込みロックを回避し、書き込みをコア全体に効果的に拡張できます。さらに、後でサーバー間でシャードを簡単に移動できます。
-MrKurt

回答:


5

これは小さなポイントの集まりになるでしょう。ただし、あなたの質問に対する唯一の答えはありません。

MongoDBでは、OSカーネルがメモリ管理を処理できます。問題にできる限り多くのRAMを投入することを除けば、ワーキングセットを「アクティブに管理」するためにできることはごくわずかです。

書き込みを最適化するためにできることの1つは、最初にそのレコードを照会(読み取りを実行)して、作業メモリに格納することです。これにより、プロセス全体のグローバルロック(v2.2でdbごとになると想定されている)に関連するパフォーマンスの問題を回避できます。

RAMとSSDの比率に関する厳格なルールはありませんが、SSDの未加工のIOPSにより、はるかに低い比率で移行できるはずです。私の頭の上では、おそらくあなたが行きたい最低の1:3です。しかし、コストが高く容量が小さい場合は、とにかくその比率を低く抑える必要があります。

「書き込みフェーズと読み取りフェーズ」に関して、レコードが書き込まれた後、それがめったに更新されない(「アップサート」)ことを正しく読んでいますか?その場合は、2つのクラスターをホストする価値があります。通常の書き込みクラスター、および[X time period]で変更されていない「エージングされた」データ用の読み取り最適化クラスター。このクラスターでスレーブ読み取りを確実に有効にします。(個人的には、データベースのオブジェクトドキュメントに日付が変更された値を含めることで管理します。)

Prodに移行する前にロードテストを実行できる場合は、perfがそれを監視します。MongoDBは、VMにデプロイされることが多い(EC2にあるリファレンスシステム)という前提で書かれているため、VMにシャードアウトすることを恐れないでください。


処理中に初期ドキュメントスタブが作成され、その後、処理の最初の部分のさまざまなサブステージによって継続的に更新されます。最初の作成時に手動でパディングを行う可能性を考慮して、実行している拡張の量を減らしましたが、現在の書き込みロックの割合は幸い低いです。
sysadmin1138

レコードを書き込んでからRAMに入れるというアドバイスは、良いアドバイスではありません。2.0(2011年半ば)以降、アクセスするデータがRAMにない場合はMongoDBが譲歩していたため、ロックが行われないため、正当な理由なくサーバーへの余分な読み取りと余分なラウンドトリップを引き起こしているだけです。とにかくその期間は開催されません。
アシャカムスキー14年

13

これは、ここに掲載されている他の回答への補遺として意図されており、ここで考慮される関連要素の多くについて議論しています。ただし、ランダムアクセスタイプシステムでのRAMの効率的な使用に関しては、見過ごされがちな別の要素があります。先読みです。

readahead(Linux)の現在の設定を確認するには、実行しますblockdev --report(通常はsudo / root権限が必要です)。これにより、ディスクデバイスごとに1行のテーブルが出力されます。RA列には、先読みの値が含まれています。その値は512バイトセクターの数です(セクターサイズがデフォルトではない場合-この投稿を書いている時点で、サイズの大きいディスクでもカーネルによって512バイトセクターとして扱われることに注意してください)ディスクアクセス。

次を実行することにより、特定のディスクデバイスの先読み設定を設定できます。

blockdev --setra <value> <device name>

ソフトウェアベースのRAIDシステムを使用する場合、各ディスクデバイスとRAIDコントローラに対応するデバイスで先読みを設定してください。

何でこれが大切ですか?さて、先読みは、MongoDBがシーケンシャルアクセスの読み取りを最適化するために使用しようとしているのと同じリソース(RAM)を使用します。回転するディスク(または、とにかく回転するディスクのように動作するデバイス-EBSをご覧ください)で順次読み取りを行う場合、近くのデータをRAMにフェッチすると、パフォーマンスが大幅に向上し、シークが減り、先読み設定が高くなります適切な環境でいくつかの印象的な結果を得ることができます。

MongoDBのようなシステムでは、通常、データセット全体でランダムアクセスになりますが、これはメモリを浪費するだけであり、他の場所で使用する方が適切です。他の場所で述べたように、MongoDBのメモリも管理するシステムは、要求時にメモリのチャンクを先読みに割り当て、MongoDBが効果的に使用するRAMを少なくします。

正しい先読みサイズを選択するのは難しく、ハードウェア、構成、ブロックサイズ、ストライプサイズ、およびデータ自体に依存します。たとえば、SSDに移行する場合、低い設定が必要になりますが、どれだけ低いかはデータによって異なります。

説明するために、先読みは、完全な単一ドキュメントを取り込むのに十分な高さであり、ディスクに戻る必要がないことを確認する必要があります。前述のメジアンサイズの8kを考えてみましょう。ディスク上のセクターは通常512バイトなので、先読みなしでドキュメント全体を読み取るには16ディスクアクセスが必要です。16セクタ以上の先読みがある場合は、ディスクへの1回のトリップでドキュメント全体を読むことになります。

実際、MongoDBインデックスバケットは8kであるため、先読みを16未満に設定したり、1つのインデックスバケットを読み込むために2つのディスクアクセスが必要になることはありません。一般的には、現在の設定から始めて半分に設定してから、RAM使用率とIOを再評価し、そこから先に進むことをお勧めします。


1
ハードウェアを社内に導入すれば、間違いなく役立つ貴重な情報。ありがとう!
sysadmin1138

3

エンドユーザーのクエリにレプリカを使用し、他のマシンでワークフローを実行することを検討する必要があります。

1:10の経験則を使用すると、1 TBのディスクストレージに約128 GBのRAMが表示されます。現在手頃な価格のSSDの中には60K IOPSを超えると主張しているものもありますが、実際の数値はかなり異なる場合があり、SSDでRAIDを使用しているかどうか、そしてもしそうなら、RAIDカードも非常に重要です。

この投稿の時点で、128GBのDDR3 ECC RAMから256GBに移行することは、1U Intelサーバー上で約2000ドル余分にあるようです。これにより、1TBのデータで1:5の比率が得られます。さらに良い比率。ワークロードをできるだけ早く終了する必要がある場合は、RAMを増やすと間違いなく役立ちますが、本当に緊急なのでしょうか?

ext4の "noatime、data = writeback、nobarrier"のようなファイルシステムのチューニングも行う必要があります。また、最大限のパフォーマンスを引き出すために、いくつかのカーネル設定の調整も必要になる場合があります。システム。

RAIDを使用する場合は、RAID-10を選択するのが適切です。適切なRAIDコントローラーを使用すると、パフォーマンスが大幅に向上しますが、使用可能なスペースが半分になります。使用可能なスペースを半分にせずに適切なパフォーマンスを向上させたい場合は、RAID50を調べることもできます。RAIDを実行するリスクは、ドライブ上のTRIMにアクセスできなくなることです。つまり、データを移動し、RAIDを分割し、ドライブをTRIMし、RAIDを再作成する必要がある場合があります。

最終的には、必要な複雑さ、費やす金額、およびワークロードの処理速度を決定する必要があります。また、MongoDBを使用するのが理想的なデータベースであるかどうかを評価します。これは、迅速な応答が必要なエンドユーザークエリにMongoを使用できますが、データを処理するために他の何かを使用できるためです。 、また、より簡単に複数のマシンにワークロードを分散させることができます。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.