翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。
Lettuce クライアント設定 (Valkey と Redis OSS)
このセクションでは、推奨される Java と Lettuce の設定オプションと、それらが ElastiCache クラスターにどのように適用されるかについて説明します。
このセクションの推奨事項は、Lettuce バージョン 6.2.2 でテスト済みです。
Java DNSキャッシュ TTL
Java 仮想マシン (JVM) はDNS名前ルックアップをキャッシュします。がホスト名を IP アドレスにJVM解決すると、 time-to-live () と呼ばれる指定された期間、IP アドレスがキャッシュされますTTL。
TTL 値の選択は、レイテンシーと変化への応答性のトレードオフです。が短いとTTLs、DNSリゾルバーはクラスターの更新DNSに気づきます。これにより、クラスターで実行される置換やその他のワークフローにアプリケーションがより迅速に応答できるようになります。ただし、 TTL が低すぎると、クエリボリュームが増加し、アプリケーションのレイテンシーが長くなる可能性があります。正しいTTL値はありませんが、TTL値を設定するときに変更が有効になるまでに余裕がある時間を考慮する必要があります。
ElastiCache ノードは変更される可能性のあるDNS名前エントリを使用するため、 を 5 ~ 10 秒TTLの低さJVMに設定することをお勧めします。これにより、ノードの IP アドレスが変更されると、アプリケーションはDNSエントリを再クエリすることで、リソースの新しい IP アドレスを受信して使用できます。
一部の Java 設定では、 JVMが再起動されるまでDNSエントリが更新されないようにJVMデフォルトTTLが設定されます。
の設定方法の詳細についてはTTL、JVM「 の設定方法TTLJVM」を参照してください。
Lettuce のバージョン
Lettuce のバージョン 6.2.2 以降の使用をお勧めします。
エンドポイント
クラスターモードが有効なクラスターを使用している場合は、redisUri
をクラスター設定エンドポイントに設定します。このDNSルックアップは、クラスター内で使用可能なすべてのノードのリストURIを返し、クラスターの初期化中にランダムにそのうちの 1 つに解決されます。トポロジの更新の仕組みの詳細については、このトピックのdynamicRefreshResources後半を参照してください。
SocketOption
を有効にしますKeepAlive
接続タイムアウトは
ClusterClientOption: クラスターモードを有効にするクライアントオプション
接続が失われAutoReconnect
を設定しますCommandTimeout
トポロジから障害が発生したノードを除外nodeFilter
例えば、フェイルオーバーが終了し、クラスターが復旧プロセスを開始した後、 clusterTopology が更新されている間、クラスターバスノードマップには、ダウンノードがノードとしてリストされてからトポロジからFAIL完全に削除されます。この期間中、Lettuce クライアントは正常なノードと見なし、継続的に接続します。そのため、再試行を使い果たすとエラーが発生します。
例:
final ClusterClientOptions clusterClientOptions = ClusterClientOptions.builder() ... // other options .nodeFilter(it -> ! (it.is(RedisClusterNode.NodeFlag.FAIL) || it.is(RedisClusterNode.NodeFlag.EVENTUAL_FAIL) || it.is(RedisClusterNode.NodeFlag.HANDSHAKE) || it.is(RedisClusterNode.NodeFlag.NOADDR))) .validateClusterNodeMembership(false) .build(); redisClusterClient.setOptions(clusterClientOptions);
注記
ノードフィルタリングは、true DynamicRefreshSources に設定して使用するのが最適です。そうしないと、1 つの問題のあるシードノードからトポロジビューを取得すると、一部のシャードのプライマリノードに障害が発生していると見なされ、このプライマリノードは除外され、スロットがカバーされなくなります。複数のシードノード ( DynamicRefreshSources が true の場合) があると、少なくとも一部のシードノードで、新しく昇格したプライマリでのフェイルオーバー後にトポロジビューが更新される必要があるため、この問題が発生する可能性が低くなります。
ClusterTopologyRefreshOptions: クラスターモード対応クライアントのクラスタートポロジの更新を制御するオプション
注記
クラスターモードが無効なクラスターは、クラスター検出コマンドをサポートしていないため、すべてのクライアントの動的トポロジー検出機能と互換性があるわけではありません。
で無効になっているクラスターモード ElastiCache は、Lettuce の と互換性がありませんMasterSlaveTopologyRefresh
。代わりに、クラスタモードが無効になっている場合は、StaticMasterReplicaTopologyProvider
を設定し、クラスターの読み取りと書き込みのエンドポイントを提供します。
クラスターモードが無効なクラスターとの接続の詳細については、「Valkey または Redis OSS (クラスターモードが無効) クラスターのエンドポイントの検索 (コンソール)」を参照してください。
Lettuce の動的トポロジー検出機能を使いたい場合は、既存のクラスターと同じシャード構成でクラスターモードが有効なクラスターを作成できます。ただし、クラスターモードが有効なクラスターでは、高速フェールオーバーをサポートするために、少なくとも 3 つのシャードと 1 つのレプリカを構成することをお勧めします。
を有効にしますenablePeriodicRefresh
このオプションを有効にすると、このジョブをバックグラウンドタスクに追加することで、クラスタートポロジの更新に伴うレイテンシを減らすことができます。トポロジの更新はバックグラウンドジョブで実行されますが、多数のノードがあるクラスターでは多少遅くなる可能性があります。これは、すべてのノードが最新のクラスタービューを取得するためにそれらのビューに対してクエリが実行されているためです。大規模なクラスターを実行する場合は、この時間を長くすることをお勧めします。
を有効にしますenableAllAdaptiveRefreshTriggers
を有効にしますcloseStaleConnections
を有効にしますdynamicRefreshResources
動的更新を使用すると、検出されたすべてのノードにクラスタートポロジを照会し、最も正確なクラスタービューを選択しようと試みます。false に設定すると、最初のシードノードのみがトポロジ検出のソースとして使用され、クライアント数は最初のシードノードについてのみ取得されます。無効になっている場合、クラスター設定エンドポイントが障害の発生したノードに解決されたとき、クラスタービューを更新しようとすると失敗し、例外が発生します。このシナリオは、障害が発生したノードのエントリがクラスター設定エンドポイントから削除されるまでに時間がかかるときに発生する可能性があります。そのため、設定エンドポイントは、障害が発生したノードに短期間ランダムに解決できます。
ただし、有効にすると、クラスタービューから受信したすべてのクラスターノードを使用して、現在のビューについてクエリを実行します。障害が発生したノードをそのビューから除外するので、トポロジ更新は成功します。ただし、 dynamicRefreshSources が true の場合、Lettuce はすべてのノードにクエリを実行してクラスタービューを取得し、結果を比較します。そのため、多数のノードを持つクラスターではコストがかかる可能性があります。多数のノードがあるクラスターでは、この機能をオフにすることをお勧めします。
final ClusterTopologyRefreshOptions topologyOptions = ClusterTopologyRefreshOptions.builder() .enableAllAdaptiveRefreshTriggers() .enablePeriodicRefresh() .dynamicRefreshSources(true) .build();
ClientResources
DnsResolver
指数バックオフとフルジッターreconnectDelay
ClientResources clientResources = DefaultClientResources.builder() .dnsResolver(new DirContextDnsResolver()) .reconnectDelay( Delay.fullJitter( Duration.ofMillis(100), // minimum 100 millisecond delay Duration.ofSeconds(10), // maximum 10 second delay 100, TimeUnit.MILLISECONDS)) // 100 millisecond base .build();
Timeouts
コマンドのタイムアウトよりも低い接続タイムアウト値を使用してください。Lettuce はレイジー接続確立を使用します。そのため、接続タイムアウトがコマンドタイムアウトよりも大きい場合、Lettuce が異常なノードへの接続を試みてコマンドのタイムアウトが常に超過すると、トポロジ更新後に障害が一定期間持続する可能性があります。
異なるコマンドに対しては動的コマンドタイムアウトを使用してください。コマンドの想定期間に基づいてコマンドタイムアウトを設定することをお勧めします。例えば、FLUSHDB、、、、、または Lua スクリプトなど、複数のキーで反復するコマンドにはFLUSHALLKEYSSMEMBERS、より長いタイムアウトを使用します。、、 などの単一キーコマンドにはSETGET、短いタイムアウトを使用しますHSET。
注記
次の例で設定されているタイムアウトは、キーと値が 20 バイトまでの SET/GET コマンドを実行するテスト用です。コマンドが複雑な場合や、キーと値が大きい場合は、処理時間が長くなる可能性があります。タイムアウトは、アプリケーションのユースケースに基づいて設定する必要があります。
private static final Duration META_COMMAND_TIMEOUT = Duration.ofMillis(1000); private static final Duration DEFAULT_COMMAND_TIMEOUT = Duration.ofMillis(250); // Socket connect timeout should be lower than command timeout for Lettuce private static final Duration CONNECT_TIMEOUT = Duration.ofMillis(100); SocketOptions socketOptions = SocketOptions.builder() .connectTimeout(CONNECT_TIMEOUT) .build(); class DynamicClusterTimeout extends TimeoutSource { private static final Set<ProtocolKeyword> META_COMMAND_TYPES = ImmutableSet.<ProtocolKeyword>builder() .add(CommandType.FLUSHDB) .add(CommandType.FLUSHALL) .add(CommandType.CLUSTER) .add(CommandType.INFO) .add(CommandType.KEYS) .build(); private final Duration defaultCommandTimeout; private final Duration metaCommandTimeout; DynamicClusterTimeout(Duration defaultTimeout, Duration metaTimeout) { defaultCommandTimeout = defaultTimeout; metaCommandTimeout = metaTimeout; } @Override public long getTimeout(RedisCommand<?, ?, ?> command) { if (META_COMMAND_TYPES.contains(command.getType())) { return metaCommandTimeout.toMillis(); } return defaultCommandTimeout.toMillis(); } } // Use a dynamic timeout for commands, to avoid timeouts during // cluster management and slow operations. TimeoutOptions timeoutOptions = TimeoutOptions.builder() .timeoutSource( new DynamicClusterTimeout(DEFAULT_COMMAND_TIMEOUT, META_COMMAND_TIMEOUT)) .build();