Redis クラスター
Redis クラスター (英語) を使用するには、Redis サーバーバージョン 3.0 + が必要です。詳細については、クラスターチュートリアル (英語) を参照してください。
Redis リポジトリを Redis クラスターで使用する場合は、クラスター上で Redis リポジトリを実行する方法をよく理解しましょう。 |
Redis クラスターを使用する場合は、キースペースイベントに依存しないでください。キースペースイベントはシャード間で複製されないためです。Pub/Sub は、単一のシャードからのみキースペースイベントを受信するランダムクラスターノードにサブスクライブします [GitHub] (英語) 。キースペースイベントの損失を回避するには、単一ノードの Redis を使用します。 |
Redis クラスター接続の操作
Redis クラスターは、単一ノードの Redis や、Sentinel が監視するマスターレプリカ環境とは動作が異なります。これは、自動シャーディングによってキーが 16384
スロットの 1 つにマップされ、ノード全体に分散されるためです。複数のキーを含むコマンドは、クロススロットエラーを避けるために、すべてのキーがまったく同じスロットにマップされることをアサートする必要があります。単一のクラスターノードは、専用のキーセットのみを提供します。特定の 1 つのサーバーに対して発行されたコマンドは、そのサーバーによって提供されるキーに対する結果のみを返します。簡単な例として、KEYS
コマンドを考えてみましょう。クラスター環境内のサーバーに発行されると、リクエストの送信先のノードによって提供されるキーのみが返され、必ずしもクラスター内のすべてのキーが返されるわけではありません。クラスター環境ですべてのキーを取得するには、既知のすべてのマスターノードからキーを読み取る必要があります。
対応するスロットサービングノードへの特定のキーのリダイレクトはドライバーライブラリによって処理されますが、ノード間で情報を収集したり、クラスター内のすべてのノードにコマンドを送信したりするなどの高レベルの機能は、RedisClusterConnection
でカバーされます。前のキーの例を取得すると、これは、keys(pattern)
メソッドがクラスター内のすべてのマスターノードを取得し、同時にすべてのマスターノードで KEYS
コマンドを実行しながら、結果を取得して累積されたキーのセットを返すことを意味します。単一ノードのキーをリクエストするだけで、RedisClusterConnection
はそれらのメソッド(たとえば、keys(node, pattern)
)にオーバーロードを提供します。
RedisClusterNode
は、RedisClusterConnection.clusterGetNodes
から取得することも、ホストとポートまたはノード ID を使用して構築することもできます。
次の例は、クラスター全体で実行されている一連のコマンドを示しています。
[email protected] (英語) :7379 > cluster nodes
6b38bb... 127.0.0.1:7379 master - 0 0 25 connected 0-5460 (1)
7bb78c... 127.0.0.1:7380 master - 0 1449730618304 2 connected 5461-20242 (2)
164888... 127.0.0.1:7381 master - 0 1449730618304 3 connected 10923-20243 (3)
b8b5ee... 127.0.0.1:7382 slave 6b38bb... 0 1449730618304 25 connected (4)
RedisClusterConnection connection = connectionFactory.getClusterConnnection();
connection.set("thing1", value); (5)
connection.set("thing2", value); (6)
connection.keys("*"); (7)
connection.keys(NODE_7379, "*"); (8)
connection.keys(NODE_7380, "*"); (9)
connection.keys(NODE_7381, "*"); (10)
connection.keys(NODE_7382, "*"); (11)
1 | スロット 0 〜 5460 にサービスを提供するマスターノードが 7382 のレプリカに複製されました |
2 | スロット 5461 から 10922 にサービスを提供するマスターノード |
3 | スロット 10923 から 16383 にサービスを提供するマスターノード |
4 | 7379 でマスターのレプリカントを保持しているレプリカノード |
5 | リクエストは 7381 サービングスロット 12182 のノードにルーティングされました |
6 | リクエストは 7379 サービングスロット 5061 のノードにルーティングされました |
7 | 7379, 7380, 7381 のノードにルーティングされたリクエスト→ [thing1、thing2] |
8 | リクエストは 7379 のノードにルーティングされました→ [thing2] |
9 | リクエストは 7380 のノードにルーティングされました→ [] |
10 | リクエストは 7381 のノードにルーティングされました→ [thing1] |
11 | リクエストは 7382 のノードにルーティングされました→ [thing2] |
すべてのキーが同じスロットにマップされると、ネイティブドライバーライブラリは、MGET
などのクロススロットリクエストを自動的に処理します。ただし、これが当てはまらない場合、RedisClusterConnection
はスロットサービングノードに対して複数の並列 GET
コマンドを実行し、累積された結果を再び返します。これはシングルスロットアプローチよりもパフォーマンスが低いため、注意して使用する必要があります。疑わしい場合は、同じスロット番号にマップされる {my-prefix}.thing1
や {my-prefix}.thing2
などのプレフィックスをカーリー括弧に指定して、キーを同じスロットに固定することを検討してください。次の例は、クロススロットリクエストの処理を示しています。
[email protected] (英語) :7379 > cluster nodes
6b38bb... 127.0.0.1:7379 master - 0 0 25 connected 0-5460 (1)
7bb...
RedisClusterConnection connection = connectionFactory.getClusterConnnection();
connection.set("thing1", value); // slot: 12182
connection.set("{thing1}.thing2", value); // slot: 12182
connection.set("thing2", value); // slot: 5461
connection.mGet("thing1", "{thing1}.thing2"); (2)
connection.mGet("thing1", "thing2"); (3)
1 | 前のサンプルと同じ構成。 |
2 | キーは同じスロットにマップされます。→ 127.0.0.1:7381 MGETthing1 {thing1} .thing2 |
3 | キーは異なるスロットにマップされ、対応するノードにルーティングされる単一のスロットに分割されます → 127.0.0.1:7379 GETthing2 → 127.0.0.1:7381GETthing1 |
上記の例は、Spring Data Redis が続く一般的な戦略を示しています。一部の操作では、目的のコマンドを計算するために大量のデータをメモリにロードする必要がある場合があることに注意してください。さらに、すべてのクロススロットリクエストを複数のシングルスロットリクエストに安全に移植できるわけではなく、誤用するとエラーが発生します(たとえば、PFCOUNT )。 |
RedisTemplate
および ClusterOperations
の操作
RedisTemplate
の汎用、構成、使用箇所については、RedisTemplate を介したオブジェクトの操作セクションを参照してください。
JSON RedisSerializers のいずれかを使用して RedisTemplate#keySerializer を設定する場合は、JSON 構造の変更がハッシュスロットの計算にすぐに影響するため、注意してください。 |
RedisTemplate
は、RedisTemplate.opsForCluster()
から取得できる ClusterOperations
インターフェースを介してクラスター固有の操作へのアクセスを提供します。これにより、テンプレート用に構成された直列化および逆直列化機能を保持しながら、クラスター内の単一ノードでコマンドを明示的に実行できます。また、管理コマンド(CLUSTER MEET
など)またはより高レベルの操作(再シャーディングなど)も提供します。
次の例は、RedisTemplate
を使用して RedisClusterConnection
にアクセスする方法を示しています。
RedisTemplate
を使用した RedisClusterConnection
へのアクセス ClusterOperations clusterOps = redisTemplate.opsForCluster();
clusterOps.shutdown(NODE_7379); (1)
1 | 7379 でノードをシャットダウンし、指を交差させると、引き継ぐことができるレプリカが配置されます。 |
Redis クラスターパイプラインは現在、クロススロットキーを使用する場合の次のコマンドを除き、Lettuce ドライバーを通じてのみサポートされています: rename 、renameNX 、sort 、bLPop 、bRPop 、rPopLPush 、bRPopLPush 、info 、sMove 、sInter 、sInterStore 、sUnion 、sUnionStore 、sDiff 、sDiffStore 。同一スロットキーは完全にサポートされています。 |