すべてのプロダクト
Search
ドキュメントセンター

ApsaraDB for Redis:Redisクライアントの再試行メカニズム

最終更新日:Sep 12, 2024

アプリケーションは、一時的なネットワークジッタ、サービスの一時的な利用不能、およびビジーサービスによって引き起こされるタイムアウトなど、ネットワークおよび実行環境に関連する一時的な障害に遭遇する可能性がある。 自動再試行メカニズムを設定して、このような障害を防ぎ、操作を成功させることができます。

一時的な障害の原因

原因

説明

障害によってトリガーされる高可用性メカニズム

ApsaraDB for Redisは、ノードのヘルスステータスを監視できます。 インスタンス内のマスターノードに障害が発生すると、マスター /レプリカの切り替えが自動的にトリガーされます。 たとえば、インスタンスの高可用性を確保するために、マスターノードとレプリカノードの役割が切り替えられます。 その結果、クライアントは次の一時的な障害に遭遇する可能性があります。

  • 一時的な接続 (秒単位)

  • 30秒以内の読み取り専用状態 (マスター /レプリカの切り替えによるデータ損失とデュアル書き込みの潜在的なリスクを防ぐため)

説明

詳細については、「マスターレプリカ切り替えの実行」をご参照ください。

低速クエリによるリクエストのブロック

O(N) の時間複雑度を有する動作が実行されるとき、要求ブロックおよび低速クエリが発生する。 この場合、クライアントによって開始された他の要求は一時的に失敗する。

複雑なネットワーク環境

クライアントとRedisサーバー間の複雑なネットワーク環境では、ネットワークのジッターやデータの再送信などの問題が発生する場合があります。 この場合、クライアントによって開始された要求は一時的に失敗することがある。

推奨される再試行ルール

再試行ルール

説明

べき等の操作のみを再試行します。

タイムアウトは、次のフェーズのいずれかで発生します。

  • コマンドはクライアントから送信されますが、ApsaraDB for Redisには到達していません。

  • コマンドはApsaraDB for Redisに到達しましたが、実行はタイムアウトします。

  • このコマンドはApsaraDB for Redisで実行されていますが、結果がクライアントに返されるとタイムアウトが発生します。

ApsaraDB for Redisで再試行操作が繰り返し実行される場合があります。 したがって、すべての操作が再試行メカニズムに適しているわけではありません。 SETコマンドの実行など、べき等の操作のみを再試行することを推奨します。 SET a bコマンドを複数回実行した場合、aの値はbのみになります。 それ以外の場合、実行は失敗します。 べき等ではないLPUSH mylist aコマンドを実行すると、mylistには複数の要素が含まれている可能性があります。

適切な再試行時間と間隔を設定します。

実際のシナリオでは、ビジネス要件に基づいて再試行時間と間隔を設定します。 報告が行われない場合、以下のような問題が発生する可能性があります。

  • 再試行の回数が不足している場合や、再試行の間隔が予想よりも長い場合、アプリケーションは操作を完了できないことがあります。

  • 過剰な回数の再試行が試みられた場合、または再試行間の間隔が予想よりも短い場合、アプリケーションは過剰なシステムリソースを消費する可能性があり、サーバーは大量の繰り返し要求に圧倒される可能性があります。

一般的な再試行間隔ポリシーには、即時再試行、固定間隔再試行、指数バックオフ再試行、およびランダムバックオフ再試行が含まれます。

ネストの再試行を避けます。

再試行ネスティングは、繰り返しまたは無制限の再試行を引き起こす可能性があります。

再試行例外を記録し、失敗レポートを生成します。

再試行プロセス中に、再試行が失敗した場合にのみ、WARNレベルで再試行ログを生成するようにシステムを構成することを推奨します。

ジェディス

Jedis 4.0.0以降、できれば最新のJedisバージョンを使用することを推奨します。 次の例では、Jedis 5.0.0が使用されます。

  1. 次の依存関係をpom.xmlファイルに追加して、Jedisを含めます。

    <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>5.0.0</version>
        </dependency> 
  2. Jedisを使用してTair操作を再試行します。

    • インスタンスが標準インスタンスまたはプロキシモードのクラスターインスタンスの場合、JedisPoolモードを使用する必要があります。

      次のサンプルコードは、合計10秒間の再試行時間内にSETコマンドを最大5回まで自動的に再試行します。 すべての再試行が失敗すると、例外がスローされます。

      PooledConnectionProvider provider = new PooledConnectionProvider(HostAndPort.from("127.0.0.1:6379"));
      int maxAttempts = 5; // The maximum number of retries.
      Duration maxTotalRetriesDuration = Duration.ofSeconds(10); // The maximum total retry duration.
      UnifiedJedis jedis = new UnifiedJedis(provider, maxAttempts, maxTotalRetriesDuration);
      try {
          System.out.println("set key: " + jedis.set("key", "value"));
      } catch (Exception e) {
          // If the exception is caught in this block, it implies that the operation failed even after the maximum number of attempts (maxAttempts) or after the maximum total retry duration (maxTotalRetriesDuration) is reached. 
          e.printStackTrace();
      }
    • インスタンスが直接接続モードのクラスターインスタンスの場合、JedisClusterモードを使用する必要があります。

      maxAttemptsパラメーターを設定して、失敗した場合の再試行回数を定義できます。既定値は5です。 最大試行回数後も操作が失敗した場合は、例外がスローされます。

      HostAndPort hostAndPort = HostAndPort.from("127.0.0.1:30001");
      int connectionTimeout = 5000;
      int soTimeout = 2000;
      int maxAttempts = 5;
      ConnectionPoolConfig config = new ConnectionPoolConfig();
      JedisCluster jedisCluster = new JedisCluster(hostAndPort, connectionTimeout, soTimeout, maxAttempts, config);
      try {
          System.out.println("set key: " + jedisCluster.set("key", "value"));
      } catch (Exception e) {
          // If the exception is caught in this block, it implies that the operation failed even after the maximum number of attempts (maxAttempts). 
          e.printStackTrace();
      }

リディソン

Redissonクライアントは、再試行ロジックを制御する2つのパラメーターを提供します。

  • retryAttempts: 再試行の数。 デフォルト値: 3。

  • retryInterval: 再試行間隔。 デフォルト値: 1500 単位:ミリ秒。

Jedisクライアントの再試行設定の例:

Config config = new Config();
config.us eSingleServer()
    . setTimeout(1000)
    . setRetryAttempts (3)
    . setRetryInterval(1500) // ms
    . setAddress("redis:// 127.0.0.1:6379");
RedissonClient connect = Redisson.create(config); 

StackExchange.Redis

StackExchang.Redisクライアントは、接続の再試行のみをサポートします。 StackExchange.Redisクライアントでの再試行設定の例:

var conn = ConnectionMultiplexer.Connect("redis0:6380,redis1:6380,connectRetry=3");
説明

APIレベルの再試行メカニズムの詳細については、「Polly」をご参照ください。

レタス

Lettuceクライアントは、コマンドがタイムアウトした後の再試行のパラメーターを提供しませんが、次のパラメーターを使用して再試行メカニズムを実装できます。

  • at-most-once execution: コマンドは最大で1回実行できます。 クライアントが切断されてから再接続されると、コマンドが失われる可能性があります。

  • at-least-once execution (default): コマンドの実行が1回以上成功することが保証されます。 これは、実行の成功を保証するために複数の試みがなされ得ることを示す。 この方法を使用して、クライアントが複数回の再試行を行っているときにTairインスタンスでマスター /レプリカの切り替えが発生した場合、クライアントで多数の再試行コマンドが蓄積される可能性があります。 マスター /レプリカの切り替えが完了すると、TairインスタンスのCPU使用率が急上昇する可能性があります。

説明

詳細については、「クライアントオプション」および「コマンド実行の信頼性」をご参照ください。

Lettuceクライアントの再試行設定の例:

clientOptions.isAutoReconnect() ? Reliability.AT_LEAST_ONCE : Reliability.AT_MOST_ONCE;