

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# リードレプリカの使用に関するベストプラクティス
<a name="ReadReplicas"></a>

セッションストア、リーダーボード、レコメンデーションエンジンなど多くのアプリケーションは、高可用性を必要とし、書き込みオペレーションよりも大幅に多くの読み取りオペレーションを処理します。これらのアプリケーションでは、多少古いデータ (結果整合性) が許容されることがよくあります。つまり、異なるユーザーが同じデータのわずかに異なるバージョンを一時的に表示しても許容されるということです。例えば、次のようになります。
+ キャッシュされたクエリ結果は、特に信頼できるソースが外部にあるキャッシュアサイドパターンの場合、多少古いデータを許容できることがよくあります。
+ ゲームリーダーボードでは、更新されたスコアに数秒の遅延があっても、ユーザーエクスペリエンスには大きな影響が及ばないことがよくあります。
+ セッションストアの場合、レプリカ間でのセッションデータの伝播にわずかな遅延が生じても、アプリケーションの機能にはほとんど影響しません。
+ レコメンデーションエンジンは通常、履歴データ分析を使用するため、リアルタイムの一貫性はそれほど重要ではありません。

結果整合性とは、レプリケーションプロセスが完了すると、通常はミリ秒以内に、すべてのレプリカノードが最終的に同じデータを返すことを意味します。このようなユースケースの場合、リードレプリカを実装することは、ElastiCache インスタンスから読み取る際のレイテンシーを低減する効果的な戦略です。

Amazon ElastiCache でリードレプリカを使用すると、次を通じて大幅なパフォーマンス向上が期待できます。

**読み取りスケーラビリティの拡張**
+ 読み取りオペレーションを複数のレプリカノードに分散する
+ プライマリノードからの読み取りトラフィックをオフロードする
+ 地理的により近いレプリカからのリクエストを処理して読み取りレイテンシーを削減する

**プライマリノードのパフォーマンスの最適化**
+ プライマリノードリソースを書き込みオペレーション専用にする
+ プライマリノードの接続オーバーヘッドを削減する
+ 書き込みパフォーマンスを向上させ、トラフィックのピーク時もより優れた応答時間を維持する

## ElastiCache サーバーレスでのレプリカからの読み取りの使用
<a name="ReadReplicas.serverless"></a>

ElastiCache サーバーレスは、異なる整合性要件に対して 2 つの異なるエンドポイントを提供します。2 つのエンドポイントは同じ DNS 名を使用しますが、ポートは異なります。レプリカからの読み取りポートを使用するには、[VPC のセキュリティグループとネットワークアクセスコントロールリストを設定](set-up.md#elasticache-install-grant-access-VPN)して、クライアントアプリケーションから両方のポートへのアクセスを許可する必要があります。

**プライマリエンドポイント (ポート 6379)**
+ 即時整合性を必要とするオペレーションに使用する
+ 最新データの読み取りを保証する
+ 重要なトランザクションと書き込みオペレーションに最適
+ 書き込みオペレーションに必要
+ 例: `test-12345.serverless.use1.cache.amazonaws.com:6379`

**レイテンシー最適化エンドポイント (ポート 6380)**
+ 結果整合性を許容できる読み取りオペレーション用に最適化
+ 可能な場合、ElastiCache サーバーレスは読み取りリクエストをクライアントのローカルのアベイラビリティーゾーン内にあるレプリカノードに自動的にルーティングします。この最適化により、異なるアベイラビリティーゾーンのノードからデータを取得する際に発生する追加のネットワーク遅延を回避し、レイテンシーを低減することができます。
+ ElastiCache サーバーレスは、ローカルノードが利用できない場合、他のゾーンの利用可能なノードを自動的に選択します。
+ 例: `test-12345.serverless.use1.cache.amazonaws.com:6380`
+ Glide や Lettuce などのクライアントは、レプリカからの読み取り設定が指定された場合、自動的に読み取りを検出して、レイテンシー最適化エンドポイントにルーティングします。クライアントがルーティング設定をサポートしていない場合 (例: valkey-java や古いバージョンの jedis)、レプリカから読み取るための適切なポートとクライアント設定を定義する必要があります。

## ElastiCache サーバーレスでのリードレプリカへの接続 - Valkey と Glide
<a name="ReadReplicas.connecting-primary"></a>

次のコードスニペットは、Valkey glide ライブラリで ElastiCache サーバーレスのレプリカからの読み取りを設定する方法を示しています。レプリカからの読み取りにポートを指定する必要はありませんが、ルーティング設定 `ReadFrom.PREFER_REPLICA` を設定する必要があります。

```
package glide.examples;

import glide.api.GlideClusterClient;
import glide.api.logging.Logger;
import glide.api.models.configuration.GlideClusterClientConfiguration;
import glide.api.models.configuration.NodeAddress;
import glide.api.models.exceptions.ClosingException;
import glide.api.models.exceptions.ConnectionException;
import glide.api.models.exceptions.TimeoutException;
import glide.api.models.configuration.ReadFrom;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;

public class ClusterExample {

    public static void main(String[] args) {
        // Set logger configuration
        Logger.setLoggerConfig(Logger.Level.INFO);

        GlideClusterClient client = null;

        try {
            System.out.println("Connecting to Valkey Glide...");

            // Configure the Glide Client
            GlideClusterClientConfiguration config = GlideClusterClientConfiguration.builder()
                .address(NodeAddress.builder()
                    .host("your-endpoint")
                    .port(6379)
                    .build())
                .useTLS(true)
                .readFrom(ReadFrom.PREFER_REPLICA)
                .build();

            // Create the GlideClusterClient
            client = GlideClusterClient.createClient(config).get();
            System.out.println("Connected successfully.");

            // Perform SET operation
            CompletableFuture<String> setResponse = client.set("key", "value");
            System.out.println("Set key 'key' to 'value': " + setResponse.get());

            // Perform GET operation
            CompletableFuture<String> getResponse = client.get("key");
            System.out.println("Get response for 'key': " + getResponse.get());

            // Perform PING operation
            CompletableFuture<String> pingResponse = client.ping();
            System.out.println("PING response: " + pingResponse.get());

        } catch (ClosingException | ConnectionException | TimeoutException | ExecutionException e) {
            System.err.println("An exception occurred: ");
            e.printStackTrace();
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            // Close the client connection
            if (client != null) {
                try {
                    client.close();
                    System.out.println("Client connection closed.");
                } catch (ClosingException | ExecutionException e) {
                    System.err.println("Error closing client: " + e.getMessage());
                }
            }
        }
    }
}
```