Overview
このガイドでは、Scala ドライバーがレプリカセットに対して読み取りおよび書き込み操作を実行する方法を変更するために、書込み保証 (write concern)、読み取り保証 (read concern)、および読み込み設定 (read preference)オプションを構成する方法を学習できます。
読み取り設定と書込み設定の優先順位
次のレベルで、書込み保証、読み取り保証、読み込み設定(read preference)のオプションを設定できます。
クライアント(オーバーライドされない限り、すべての操作実行にデフォルトを設定します)
トランザクション
Database
コレクション
このリストは、オプション設定の優先順位の増加順も示しています。例、トランザクションに読み取り保証 (read concern)を設定すると、クライアントから継承された読み取り保証 (read concern)設定が上書きされます。
書込み保証 (write concern) 、読み取り保証 (read concern)) 、読み込み設定 (read preference)オプションを使用すると、レプリカセット内のデータの因果整合性と可用性をカスタマイズできます。 これらのオプションの完全なリストについては、 MongoDB Serverマニュアルの次のガイドを参照してください。
読み取り操作と書込み操作の設定
読み込み設定(読み込み設定 (read preference)を設定することで、ドライバーがレプリカセットメンバー間で読み取り操作をルーティングする方法を制御できます。 また、読み取りおよび書込み保証を設定して、ドライバーがレプリカセットに対する読み取りおよび書込み操作の確認を待機する方法も制御できます。
次のセクションでは、さまざまなレベルでこれらの読み取りと書込み設定を構成する方法を示します。
クライアント構成
この例では、MongoClientSettingsインスタンスを コンストラクターに渡すことで、MongoClientインスタンスの読み込み設定 (read preference)、読み取り保証 (read concern))、書込み保証 (write concern)を設定する方法を示しています。このコードは、次の設定を構成します。
secondary読み込み設定 (read preference): 読み取り操作は、 セカンダリレプリカセットメンバーからデータを取得します。LOCAL読み取り保証 (read concern) : 読み取り操作は、インスタンスの最新データを返しますが、そのデータがレプリカセットのノードの過半数に書き込まれたことを保証します。W2書込み保証 (write concern)) : プライマリレプリカセットノードと 1 つのセカンダリ ノードは、書込み (write)操作を確認する必要があります。
val mongoClient = MongoClient(MongoClientSettings.builder() .applyConnectionString(ConnectionString("mongodb://localhost:27017/")) .readPreference(ReadPreference.secondary()) .readConcern(ReadConcern.LOCAL) .writeConcern(WriteConcern.W2) .build())
あるいは、接続 URI で読み取り設定と書込み設定を指定することもできます。これはMongoClientコンストラクターにパラメーターとして渡されます。
val uriClient = MongoClient("mongodb://localhost:27017/?readPreference=secondary&w=2&readConcernLevel=local")
トランザクション構成
この例では、 TransactionOptionsインスタンスをstartTransaction() メソッドに渡すことで、トランザクションの 読み込み設定(読み込み設定 (read preference)、読み取り保証 (read concern)、書込み保証 (write concern)を設定する方法を示しています。トランザクションは セッション 内で実行されます。これは、順番に実行されるよう関連付けられた読み取り操作または書込み操作のグループです。
Tip
セッションの詳細については、 MongoDB Serverマニュアルの「 サーバー セッション 」を参照してください。
この例では、次の設定を構成しています。
primary読み込み設定 (read preference): 読み取り操作は、 プライマリレプリカセットメンバーからデータを取得します。MAJORITY読み取り保証 (read concern) : 読み取り操作は、レプリカセットノードの過半数に書き込まれたインスタンスの最新データを返します。W1書込み保証 (write concern)) : プライマリレプリカセットノードは書込み (write)操作を確認する必要があります。
val clientSessionFuture = mongoClient.startSession().toFuture() val clientSession = Await.result(clientSessionFuture, Duration(10, TimeUnit.SECONDS)) val tOptions: TransactionOptions = TransactionOptions.builder() .readPreference(ReadPreference.primary()) .readConcern(ReadConcern.MAJORITY) .writeConcern(WriteConcern.W1) .build() clientSession.startTransaction(tOptions)
データベース構成
この例では、セッター メソッドを getDatabase() メソッドに連鎖させることで、test_database というデータベースの読み込み設定(読み込み設定 (read preference)、読み取り保証 (read concern)、書込み保証 (write concern)を設定する方法を示しています。 このコードは、次の設定を構成します。
primaryPreferred読み込み設定 (read preference): 読み取り操作は、プライマリレプリカセットメンバーからデータを取得します。プライマリが使用できない場合は セカンダリ メンバーからデータが取得されます。AVAILABLE読み取り保証 (read concern) : 読み取り操作は、インスタンスの最新データを返しますが、そのデータがレプリカセットのノードの過半数に書き込まれたことを保証します。MAJORITY書込み保証 (write concern) ) : すべてのレプリカセットのノードの過半数が書込み (write)操作を確認する必要があります。
val database = mongoClient.getDatabase("test_database") .withReadPreference(ReadPreference.primaryPreferred()) .withReadConcern(ReadConcern.AVAILABLE) .withWriteConcern(WriteConcern.MAJORITY)
コレクション構成
この例では、セッター メソッドを getCollection() メソッドに連鎖させることで、test_collection というコレクションの読み込み設定(読み込み設定 (read preference)、読み取り保証 (read concern)、書込み保証 (write concern)を設定する方法を示しています。 このコードは、次の設定を構成します。
secondaryPreferred読み込み設定 (read preference): 読み取り操作は、セカンダリ レプリカセット メンバーからデータを取得します。セカンダリ メンバーが使用できない場合は、プライマリ メンバーからデータが取得されます。AVAILABLE読み取り保証 (read concern) : 読み取り操作は、インスタンスの最新データを返しますが、そのデータがレプリカセットのノードの過半数に書き込まれたことを保証します。UNACKNOWLEDGED書込み保証 (write concern)) : レプリカセット ノードは書込み (write)操作を確認する必要はありません。
val collection = database.getCollection("test_collection") .withReadPreference(ReadPreference.secondaryPreferred()) .withReadConcern(ReadConcern.AVAILABLE) .withWriteConcern(WriteConcern.UNACKNOWLEDGED)
高度な読み取り構成
次のセクションでは、Scalaドライバーが読み取り操作をルーティングする方法をさらにカスタマイズする方法について説明します。
シャーディングされたクラスター
シャーディングされたクラスターに接続する 際に、読み込み設定 (read preference)を指定できます。MongoDB はシャーディングを使用して、データセットをキー範囲ごとに分割し、複数のデータベースインスタンスにデータを分散します。シャーディングされたクラスター、またはシャーディングされた配置内のノードのセットには、次のコンポーネントが含まれます。
シャード : シャーディングされたデータのサブセットを含むレプリカセット。
Mongos :アプリケーションとシャーディングされたクラスター間のインターフェースを提供するクエリ ルーター。
コンフィギュレーションサーバー : クラスターの構成設定とメタデータを保存するサーバー。
Tip
シャーディングされたクラスターの詳細については、 MongoDB Serverマニュアルのシャーディングを参照してください。
レプリカセットシャードから読み取る場合、mongos は指定された読み込み設定 (read preference)を適用します。読み込み設定 (read preference)は、操作ごとに再評価されます。
次の例は、シャーディングされたクラスターに接続し、接続文字列で secondary読み込み設定 (read preference)を指定する方法を示しています。
val mongosClient = MongoClient("mongodb://user:password@mongos1.example.com,mongos2.example.com/?readPreference=secondary")
タグセット
MongoDB Serverでは、選択した任意の基準に従ってレプリカセットメンバーにキーと値のタグを適用できます。次に、それらのタグを使用して、1 つ以上のノードを 読み取り操作の対象にすることができます。
デフォルトでは 、 Scalaドライバーは、読み取り元ノードを選択するときに タグを無視します。 特定のタグを優先するようにScalaドライバーに指定するには、タグをリストとして 読み込み設定(読み込み設定 (read preference)セッター メソッドに渡します。
米国の複数のデータセンターでホストされているノードを含むレプリカセットに接続しているとします。 ドライバーが次の順序でセカンダリレプリカセットメンバーからの読み取りを優先するようにします。
タグ付けされた ニューヨークデータセンターのメンバー
("dc", "ny")サンフランシスコデータセンターのメンバー( でタグ付け)
("dc", "sf")セカンダリ ノード
このコード例では、前述のレプリカセットメンバーを表すタグのリストを ReadPreference.secondary() セッター メソッドに渡します。 次に、コードは読み込み設定 (read preference)情報を withReadPreference() メソッドに渡して、データベースに読み取り順序を設定します。
val tag1 = new TagSet(new Tag("dc", "ny")) val tag2 = new TagSet(new Tag("dc", "sf")) val tag3 = new TagSet() val readPreference = ReadPreference.secondary(List(tag1, tag2, tag3).asJava) val database = mongoClient.getDatabase("test_database") .withReadPreference(readPreference)
ロード バランシング
シャーディングされたクラスターまたはレプリカセットに接続する場合、 Scalaドライバーは負荷分散を使用して読み取りおよび書込みリクエストを処理します。負荷分散により、ドライバーはこれらのリクエストを複数のサーバーに分散できるため、1 つのサーバーが過負荷になるのを回避し、最適なパフォーマンスを確保します。
シャーディングされたクラスターに接続する場合、Scala ドライバーはネットワークのラウンドトリップ時間が最も短いインスタンスを計算することで、最も近い mongos インスタンスを決定します。その後、ドライバーはこの mongos インスタンスの平均ラウンドトリップ時間を localThresholdMS 値 に追加することで、レイテンシ ウィンドウを決定します。ドライバーは、レイテンシー ウィンドウ内に収まる最大 2 つのランダムな mongos インスタンスにわたってリクエストのロードバランスを行います。リクエストごとに、ドライバーは operationCount 値を決定することで、操作ロードが低いサーバーを選択します。
レプリカセットに接続する場合、Scala ドライバーはまず、読み込み設定 (read preference) に従ってレプリカセットのノードを選択します。その後、ドライバーは前の段落で述べたと同じプロセスに従います。レイテンシウィンドウを計算した後、ドライバーはウィンドウ内に収まる最大 2 つのランダムなレプリカセットを選択し、リクエストを受け取るノードとして値が低い operationCount ノードを選択します。
Tip
負荷分散の詳細については、 MongoDB Serverマニュアルのシャードクラスタのバランサーを参照してください。
LocalThreshold
プライマリ以外の読み込み設定 (read preference) を持つレプリカセットに接続すると、ドライバーはレイテンシーウィンドウ内の最も近い適格なレプリカセットから読み込みます。シャーディングされたクラスターに接続すると、ドライバーはレイテンシーウィンドウ内のアクセス可能なすべての mongos インスタンスから選択します。読み込み設定 (read preference) モードの詳細については、「読み込み設定 (read preference)」を参照してください。
デフォルトで、ドライバーは最も近い適格なサーバーの ping 時間が 15 ミリ秒以内であるサーバーのみを使用します。
例えば、レプリカセットに 5 つのノードがあり、最も近いノードの ping 時間が 5 ミリ秒であるとします。デフォルトの localThresholdMS が 15 ミリ秒の場合、次の表に示すように、ping 時間が 20 ミリ秒以下のノードのみがレイテンシ ウィンドウ内にあります。
Host | タイプ | ping 時間 | レイテンシ ウィンドウ内 |
|---|---|---|---|
| 原発 | 5ミリ秒 | はい |
| セカンダリ | 9ミリ秒 | はい |
| セカンダリ | 13ミリ秒 | はい |
| セカンダリ | 24ミリ秒 | No |
| セカンダリ | 42ミリ秒 | No |
レイテンシ ウィンドウを調整するには、MongoClientSettings インスタンスで localThreshold オプションを設定するか、接続 URI で localThresholdMS オプションを設定します。
次の例ではレプリカセットに接続し、35 ミリ秒のローカルしきい値を指定しています。各アプローチに対応するコードを確認するには、MongoClientSettings タブまたは Connection URIタブを選択します。
val client = MongoClient(MongoClientSettings.builder() .applyConnectionString(ConnectionString("mongodb://localhost:27017/")) .applyToClusterSettings(builder => builder .localThreshold(35, TimeUnit.MILLISECONDS) ) .build())
val connectionString = "mongodb://localhost:27017/?replicaSet=repl0&localThresholdMS=35" val client = MongoClient(connectionString)
前の例では、 Scalaドライバーは、最も近いメンバーのping時間の 35 ミリ秒以内に、一致するメンバーに読み取りを分散します。
再試行可能な読み取りと書込み
Scala ドライバーは、ネットワークまたはサーバーエラーにより失敗した場合、特定の読み取り操作と書き込み操作を 1 回自動的に再試行します。
MongoClientSettingsインスタンスで retryReads または retryWrites オプションを false に設定することで、再試行可能な読み取りまたは再試行可能な書込みを明示的に無効にすることができます。接続 URI で retryReads または retryWrites オプションを設定することもできます。
次の例では、再試行可能な読み取りと再試行可能な書込みの両方を false に設定しています。各アプローチに対応するコードを確認するには、MongoClientSettings タブまたは Connection URIタブを選択します。
val retryClient = MongoClient(MongoClientSettings.builder() .applyConnectionString(ConnectionString("mongodb://localhost:27017/")) .retryReads(false) .retryWrites(false) .build())
val retryUriClient = MongoClient("mongodb://localhost:27017/?retryReads=false&retryWrites=false")
サポートされている再試行可能な読み取り操作の詳細については、 MongoDB Serverマニュアルの「 再試行可能な読み取り 」を参照してください。サポートされている再試行可能な書込み操作の詳細については、 MongoDB Serverマニュアルの「 再試行可能な書込み 」を参照してください。
注意
インテリジェント ワークロード管理(IWM)におけるロード シャーディング
SystemOverloadedError または RetryableError ラベルの付いたエラーがアプリケーションに障害を引き起こすか、アプリケーションログに表示される場合は、クラスターでロード シードがアクティブになっており、ドライバーがそれをサポートするバージョンにアップグレードされていない可能性があります。 MongoDB Scalaドライバーのバージョン 5.8 以降にアップグレードすることをお勧めします。アップグレードした後もこれらのエラーが引き続き発生する場合は、 ロード制御 構成の確認などのサーバー側の変更、またはカスタム エラー処理やクライアント側のリクエストスロットリングの実装などのアプリケーション側の変更で対処できます。状況によっては、アプリケーション側の変更が望ましい場合や必要な場合もあります。
ロード シードは IWM の機能であり、持続的な過負荷時に過剰な操作を拒否することで、サーバーの負荷を管理するのに役立ちます。この機能はMongoDB 9.0 以降で利用できます。
IWM や過負荷エラーの処理の詳細については、Atlas ドキュメントの インテリジェント ワークロード管理 ページまたは 過負荷エラー ページを参照してください。
API ドキュメント
このガイドで説明したメソッドや型の詳細については、次の API ドキュメントを参照してください。