読み込み設定 (read preference) のユースケース
項目一覧
次のドキュメントでは、さまざまな読み込み設定(read preference) モードの一般的なユースケースと、読み込み設定(read preference)をデフォルトの primary
から変更してはいけない場合についてまとめた禁止事項について説明しています。
読み込み設定(read preference)モード
読み込み設定(read preference)モード | 説明 |
---|---|
デフォルトモード。すべての操作は、現在のレプリカセットのプライマリから読み取られます。 読み取り操作を含む分散トランザクションでは、読み込み設定(read preference) | |
すべての操作はレプリカセットのセカンダリ ノードを対象に読み込みを行います。 | |
ノードがプライマリであるか、セカンダリであるかに関係なく、指定されたレイテンシのしきい値に基づいて、操作は、ランダムに選択された適格なレプリカセット ノードから読み取ります。この操作は、レイテンシを計算するときに次の点を考慮します。
|
非プライマリ読み込み設定(read preference)を使用するための表示
以下は、primary
以外の読み込み設定(read preference)モードを使用する一般的な使用例です。
フロントエンド アプリケーションに影響を与えないシステム操作を実行します。
地理的に分散されたアプリケーションにローカル読み取りを提供します。
複数のデータセンターにアプリケーション サーバーがある場合は、地理的に分散されたレプリカセットを用意し、非プライマリまたは
nearest
読み込み設定(read preference)を使用することを検討してください。これにより、クライアントは常にプライマリから読み取るのではなく、レイテンシーが最も低いノードから読み取ることができます。フェイルオーバー中の可用性の維持。
primaryPreferred
アプリケーションが通常の状況ではプライマリから読み取り、プライマリが使用できない場合にセカンダリからの 古い読み取り を許可する場合は、 を使用します。
非プライマリ読み込み設定(read preference)のカウンター表示
一般に、読み取り用の追加容量を提供するために secondary
と secondaryPreferred
を使用しないでください。その理由は次のとおりです。
レプリカのすべてのノードの書込みトラフィックはほぼ同等です。その結果、セカンダリはプライマリとほぼ同じ速度で読み取りを処理します。
レプリケーションは非同期であり、書込み操作の成功とセカンダリへのレプリケーションの間にはある程度の遅延が発生します。セカンダリからの読み取りでは古いデータが返される可能性があり、異なるセカンダリからの読み取りでは非単調な読み取りが発生する可能性があります。
注意
クライアントは、クライアント セッションと因果整合性保証を使用して、単調読み取りを保証できます。
読み取り操作をセカンダリに分散すると、セットの いずれかのノードが使用できなくなった場合に、セットの残りのノードがすべてのアプリケーションリクエストを処理できる必要があるため、可用性が損なわれる可能性があります。
シャーディングは、読み取りおよび書込み操作をマシンのグループ全体に分散することで読み取りおよび書込み容量を増加させるため、多くの場合、容量を追加するためのより優れた戦略となります。
読み込み設定(read preference)の内部適用の詳細については、「サーバー選択アルゴリズム」を参照してください。
整合性を最大化する
古い読み取りを回避するには、primary
読み込み設定(read preference)と "majority"
readConcern
を使用します。プライマリが使用できない場合(たとえば、選出中やレプリカセットの大部分にアクセスできない場合)、primary
読み込み設定(read preference)を使用した読み取り操作ではエラーが生成されるか、例外がスローされます。
状況によっては、レプリカセットに一時的に 2 つのプライマリが存在する可能性がありますが、"majority"
書込み保証(write concern)で書込みを確認できるプライマリは 1 つだけです。
部分的なネットワーク パーティションにより、プライマリ(
P
old)が少数のノードを含むパーティションに分離され、パーティションの反対側には大多数のノードが含まれる場合があります。多数派のパーティションは新しいプライマリ(P
new)を選出しますが、レプリカセット内の少数のノードしか認識できないことをまだ検出していないため、しばらくの間、古いプライマリ(P
old)が引き続き読み取りと書込みを処理する可能性があります。この期間中、古いプライマリ(P
old)がプライマリとしてクライアントにまだ表示されている場合は、このプライマリからの読み取りで古いデータが反映される可能性があります。プライマリ(
P
old)が応答しなくなると選出がトリガーされ、新しいプライマリ(P
new)が選出されて読み取りと書込みを処理できるようになります。応答しないプライマリ(P
old)が再び応答し始めると、2 つのプライマリが短時間表示されます。この短い表示期間は、P
old が終わると終了します。ただし、短期間の間に、クライアントは古いプライマリP
old から読み取りを行う可能性があり、これにより古いデータが提供される場合があります。
整合性を高めるために、自動 フェイルオーバーを無効にすることができます。ただし、自動フェイルオーバーを無効にすると可用性が低下します。
可用性を最大化する
可能な場合、読み取り操作を許可するには、 primaryPreferred
を使用します。 プライマリがある場合、 一貫性のある読み取り[ 1 ]が得られますが、プライマリがない場合はセカンダリをクエリできます。 ただし、この読み取りモードを使用する場合は、 secondary
とsecondaryPreferred
で説明されている状況を考慮してください。
[1] | 状況によっては、 replica set内の 2 つのノードが一時的に自分たちがプライマリであると認識することがありますが、最大でそのうちの 1 つが{ w:
"majority" } の書き込み懸念で書き込みを完了できます。 { w: "majority" } 書き込みを完了できるノードは現在のプライマリであり、もう一方のノードは、通常はネットワークパーティションが原因で降格をまだ認識していない以前のプライマリです。これが発生すると、以前のプライマリに接続するクライアントは、読み取り設定primary を要求したにもかかわらず、古いデータを検出する可能性があり、以前のプライマリへの新しい書き込みは最終的にロールバックされます。 |
レイテンシを最小限に抑える
常に低レイテンシノードから読み取るには、nearest
を使用します。ドライバーまたは mongos
は、最も近いノードと、最も近いノードから 15 ミリ秒以内の [2] 離れたノードから読み取ります。
nearest
は整合性を保証するものではありません。アプリケーション サーバーに最も近いノードがレプリケーション ラグのあるセカンダリである場合、クエリによって古いデータが返される可能性があります。nearest
はネットワーク距離のみを反映し、I/O または CPU 負荷は反映しません。
[2] | このしきい値は構成可能です。適切な設定については、localPingThresholdMs の mongos を参照するか、ドライバーのドキュメントを参照してください。 |
地理的に分散したノードからのクエリ
レプリカセットのノードが地理的に分散している場合は、インスタンスの場所を反映するレプリカ タグを作成し、近くのノードを照会するようにアプリケーションを構成できます。
たとえば、「east」および「west」データセンターのノードに タグ {'dc': 'east'}
および {'dc': 'west'}
が付けられている場合、east データセンターのアプリケーション サーバーは、次の読み込み設定(read preference)を使用して近くのノードから読み取ることができます。
db.collection.find().readPref('nearest', [ { 'dc': 'east' } ])
nearest
はすでにネットワーク遅延の少ないノードを優先していますが、タグを含めることで選択がより予測可能になります。
secondary
vs secondaryPreferred
特定の専用クエリ(例: ETL、レポートなど)の場合は、secondary
読み込み設定(read preference)モードを使用して、プライマリから読み取り負荷をシフトできます。このユースケースでは、secondary
モードが secondaryPreferred
モードよりも推奨されます。これは、secondaryPreferred
では次の状況が発生するリスクがあるためです。すべてのセカンダリが使用できず、レプリカセットにプライマリの停止を防ぐのに十分な アービタ [3] がある場合、プライマリはクライアントからのすべてのトラフィックを受信します。プライマリがこの負荷を処理できない場合、クエリは書き込みと競合します。このため、これらの特定の専用クエリを分散するには、secondaryPreferred
ではなく、読み込み設定(read preference)secondary
を使用します。
[3] | 一般に、レプリカセットにアービタを配置することは避け、代わりに奇数のデータ保持ノードを使用します。アービタを配置する必要がある場合は、レプリカセットごとに複数のアービタを配置しないようにしてください。 |