これはシステムに非常に依存しますが、可能性はほぼ確実で、任意の崖を越えてスケールし、リアルトラブルに陥ります。 RAMとディスク領域の比率)にはどのような経験則があるのか知りたいです。次のシステムのラウンドを計画しており、RAMに関するいくつかの選択を行う必要があります、SSD、およびそれぞれの新しいノードが取得する量。
しかし、パフォーマンスの詳細については今すぐ!
単一のプロジェクト実行の通常のワークフロー中に、MongoDBは非常に高い割合の書き込み(70〜80%)に見舞われます。処理パイプラインの第2ステージに到達すると、処理の前半で識別されたレコードを重複排除する必要があるため、読み取りは非常に多くなります。これは、「ワーキングセットをRAMに保持する」ためのワークフローであり、その前提に基づいて設計しています。
データセット全体は、エンドユーザーから派生したソースからのランダムなクエリで継続的にヒットされます。頻度は不規則ですが、サイズは通常かなり小さいです(10ドキュメントのグループ)。これはユーザー向けであるため、応答は「退屈な今」のしきい値である3秒未満である必要があります。このアクセスパターンはキャッシュに存在する可能性がはるかに低いため、ディスクヒットが発生する可能性が非常に高くなります。
二次処理ワークフローとは、数日、数週間、または数か月前の可能性がある以前の処理実行の大量の読み取りであり、頻繁に実行されませんが、それでもなお実行する必要があります。前の処理実行のドキュメントの最大100%がアクセスされます。キャッシュウォーミングはこれには役立ちません。
完成したドキュメントのサイズは大きく異なりますが、中央値のサイズは約8Kです。
通常のプロジェクト処理の高読み取り部分は、読み取りトラフィックの分散に役立つレプリカの使用を強く示唆しています。私は読んだ 他の場所 1:10 RAM-GBからHD-GBは、遅いディスクの良い経験則であることを示しています。はるかに高速なSSDの使用を真剣に検討しているので、高速ディスクにも同様の経験則があるかどうかを確認してください。
私たちは、Mongoをキャッシュのすべてが実際には機能しない方法で使用していることを知っています。そのため、このような使用に耐えられるシステムを設計する方法を検討しています。 全体データセットは、半年以内にTBのほとんどであり、成長し続けるでしょう。
これは小さな点の集まりになるでしょう。残念ながら、あなたの質問に対する答えは1つではありません。
MongoDBにより、OSカーネルはメモリ管理を処理できます。問題にできるだけ多くのRAM=を投げることを除いて、ワーキングセットを「アクティブに管理」するために実行できることはほんのわずかです。
書き込みを最適化するためにできることの1つは、最初にそのレコードをクエリする(読み取りを行う)ことです。これにより、そのレコードは作業メモリ内にあります。これにより、プロセス全体のグローバルロックに関連するパフォーマンスの問題が回避されます(v2.2ではdbごとになることになっています)。
RAM対SSDの比率には厳密な規則はありませんが、SSDの未加工のIOPSを使用すると、はるかに低い比率で移動できるはずです。頭上から、1:3はおそらく最も低いレベルですが、コストが高く容量が少ないことを考えると、とにかくその比率を低く保つ必要があるでしょう。
「書き込みと読み取りのフェーズ」に関して、レコードが書き込まれると、めったに更新されない(「更新」される)ことを正しく読み取っていますか?その場合は、2つのクラスターをホストする価値があります。通常の書き込みクラスター、および[X time period]で変更されていない「古い」データ用の読み取り最適化クラスター。私は間違いなくこのクラスターでスレーブ読み取りを有効にします。 (個人的には、dbのオブジェクトドキュメントに日付変更値を含めることで管理します。)
製品版に移行する前に負荷テストを行う機能がある場合、perfはそれを完全に監視します。 MongoDBは、VMにデプロイされることが多い(それらの参照システムはEC2にある)ことを前提に作成されているため、VMに分割することを恐れないでください。
これは、ここで検討される関連要素の多くを議論する、ここに投稿された他の回答への補遺として意図されています。しかし、効率的なRAMランダムアクセスタイプシステムでの使用率-先読み)となると、見過ごされがちな別の要因があります。
先読み(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未満に設定することは決してできません。一般的には、現在の設定から始めて半分にしてから、RAM使用率とIOを再評価して、そこから先に進みます。
エンドユーザーのクエリにレプリカを使用し、ワークフローを他のマシンで実行することを検討する必要があります。
1:10の経験則を使用すると、約128GBのRAMが1TBのディスクストレージに対応します。手ごろな価格のSSDの一部は、今日60K IOPSを超えると主張していますが、実際の数SSDでRAIDを使用しているかどうかだけでなく、かなり異なる場合があります。使用している場合は、RAIDカードも非常に重要です。
この投稿の時点では、128 GBのDDR3 ECC RAMから256 GBにすると、1U Intelサーバーで約2000ドル余分にかかるようです。これにより、1 TBのデータで1:5の比率が得られます。さらに良い比率。ワークロードを可能な限り早く終了させる必要がある場合は、さらにRAM=が役に立ちますが、本当に緊急ですか?
同様に、ext4で「noatime、data = writeback、nobarrier」などのファイルシステムのチューニングを行う必要があります。また、カーネル設定を調整して、最大限のパフォーマンスを引き出す必要がある場合もあります。システム。
RAIDを使用する場合、RAID-10はかなり良い選択です。適切なRAIDコントローラーを使用すると、パフォーマンスが大幅に向上しますが、使用可能なスペースが半分になります。使用可能なスペースを半分にせずにまともなパフォーマンスを向上させたい場合は、RAID50を調べることもできます。 RAIDを実行するリスクは、ドライブ上のTRIMにアクセスできなくなることです。つまり、データを移動し、RAIDを分割し、ドライブをTRIMし、RAIDを再作成する必要があるということです。
最終的には、必要な複雑さ、費やす金額、ワークロードの処理速度を決定する必要があります。また、MongoDBが使用に最適なデータベースであるかどうかも評価します。迅速な応答を必要とするエンドユーザークエリにMongoを使用できますが、数秒で準備する必要のない何かを使用してデータを処理できます。また、ワークロードを複数のマシンに簡単に分散させることもできます。