クバネティス(Kubernetes) 環境で Redis Scale-Out


クバネティス(Kubernetes) 環境で Redis Scale-Out

1. Redis-Cluster 拡張の助言

クバネティス(Kubernetes) の kubectl scale --replicas だけでポッド(Pod) 数を増やしても、Redis-Cluster は実質的に拡張されません。
以下で Redis-Cluster を実際に拡張する標準手順を簡単に見ます。

  • ① クバネティス(Kubernetes) 命令で Redis ポッド(Pod) を増設(例: 6個 ➔ 10ポッド(Pod) へ拡張)
  • ② Redis の redis-cli --cluster add-node で増設したノード(Node) を既存 Cluster に参加させます
  • ③ Redis の cluster rebalance でスロットとデータ(キー)を新しく追加した Redis ノード(Node) へ移動します
  • ここまで完了して初めて Redis-Cluster の拡張が完了します。

💻 負荷が重い状態(CPU 100%)でリアルタイム拡張が難しい理由

  • ③番 Redis の 'cluster rebalance' 進行時、スロットとデータを移す過程でかなりの負荷が発生します。 既存 Redis-0, 1, 2 から大容量データを新規ノード(Node) へ移すので、ネットワークと CPU 消費は当然発生します。 すでに CPU 使用率が100%の状態でデータ再配置(Rebalance) まで加わると、既存 Redis の応答時間(Latency) が急増しサービス障害につながることがあります。
  • Rebalance 作業中の性能低下: データ移動中はアプリケーションのキー読み取り/書き込み時に既存ノード(Node) と新規ノード(Node) の間で ASK / MOVED Redirection (既存 Redis にそのキーがあるか尋ね、なければ新しい Redis にそのキーが着いたか尋ねる) 過程が頻繁に発生し、応答時間が落ち CPU 使用率がさらに上がります。
  • クラスタの構造的複雑性: 実際の拡張は Master ノード(Node) の奇数維持ルール(3個 ➔ 5個など)と1:1 レプリカ(Replica) 構成を一緒に考える必要があるため、既存6ポッド(Pod) から10ポッド(Pod) へ増やすなど多数のノード(Node) を一度に構成しなければならず、Rebalance が非常に複雑になります。
  • nodes.conf 状態不一致と障害リスク: Rebalance 進行中に何らかの理由でポッド(Pod) が1〜2個ダウンすると、Redis-Cluster 全体の麻痺に広がることがあります。 特にスロット移動中にノード(Node) がダウンすると、各ポッド(Pod) の nodes.conf にあるスロット所有状態が一致せず、自動復旧ができなくなるリスクが高いです。
  • [運用ガイド] したがって Redis の負荷増加が予想されるなら、あらかじめ安定した時点(CPU 使用率60%以下)で先に拡張するか、急な負荷が出たときは 負荷が落ち着いた安定時点を待ってから拡張してください。

🧑‍💻 Redis-Operator による自動拡張

  • Redis-Cluster の自動拡張には 'Redis-Operator'(別製品)を使って構築できます。
  • Redis-Operator が上で説明した 'cluster add-node, rebalance' などの命令を実行してくれます。
  • この場合でも、拡張時点を決める hpa.yaml で cpu: averageUtilization を高く設定することは推奨しません。

🌐 Redis-Operator 提供(URL)

  • Redis-Operator (OT-CONTAINER-KIT)
    説明: オープンソースコミュニティで最も活発に使われる Redis Operator の一つです。 `RedisCluster` Custom Resource(CRD) を定義すると、ノード(Node) 追加・削除、Failover、Auto-scaling を 安全に処理してくれます。
    関連ドキュメント/Github: 🔗 redis-operator   🔗 getting-started
  • Spotahome Redis Operator
    説明: Redis-Sentinel および Redis-Cluster アーキテクチャをクバネティス(Kubernetes) コントローラとして安全に管理できるよう スペインのテック企業 Spotahome が開発して公開したオペレータです。
    関連ドキュメント/Github: 🔗 Spotahome Redis Operator
  • Redis Enterprise K8s Operator(公式 Redis)
    説明: Redis.io (Redis Ltd.) 公式提供のオペレータです。K8s HPA および Custom Metrics と連携し ノード(Node) 増設から Shard Rebalancing までの全過程を自動化します。
    公式ガイド: 🔗 Redis Enterprise K8s Operator

2. Redis-Sentinel 拡張の助言

Redis-Sentinel 環境で CPU 使用率が100%に達するボトルネックは、ほとんど Master ノード(Node) で発生します。 単一 Master 構造のため、すべてのデータ変更(投入/修正/削除)処理が Master 1台に集中するからです。

  • レプリカノード(Node)(Replica)増設の限界: すでに2つのレプリカノード(Node) が読み取り(Read) トラフィックを分散しているので、レプリカ側で CPU ボトルネックが起きることは極めて稀です。 したがってポッド(Pod) を追加増設するのは、レプリカノード(Node) を1台増やすだけであり、 Master に集中した書き込み(Write) 負荷と CPU ボトルネックはまったく解決できません。
  • 読み取り(Read) 分散の限界: 新しいレプリカノード(Node) を追加すると、Master から全データを同期(Full Resync) する過程が発生します。 この同期過程で Master ノード(Node) に RDB 生成とネットワーク I/O 負荷が加わり、かえって Master の CPU 状態が悪化することがあります。

💡 結論と最適な代替

Master 負荷による Sentinel 環境の性能限界に直面したとき、ポッド(Pod)(レプリカノード(Node))増設は正しい解決ではありません。   根本的な解決(Scale-Out / アーキテクチャ転換)は 継続的な書き込みトラフィック増加が予想されるなら、単一 Master の Sentinel を離れ、複数 Master で書き込み トラフィックを分散できる Redis-Cluster 構造へアーキテクチャを転換すべきです。


Redis-Cluster 拡張方法

1. ポッド(Pod) 追加

1) 既存状態の照会 🧮

redis-cluster-0~5: 6つのポッド(Pod) があります。

💻 Terminal

2) ポッド(Pod) 追加: 6個 -> 10個 ⚡

💻 Terminal

3) ポッド(Pod) 追加後の確認 🧮

redis-cluster-6~9: 4つのポッド(Pod) 追加作成完了

💻 Terminal

2. Redis-Cluster ノード(Node) 追加

Master として追加されますが、スロットが割り当てられていないのでまだデータは入りません。

1) redis-cluster-6 ノード(Node) 追加: add-node

kubectl exec -it redis-cluster-0 -- redis-cli -a redisgate --cluster add-node
redis-cluster-6.redis-cluster-service.default.svc.cluster.local:18504
redis-cluster-0.redis-cluster-service.default.svc.cluster.local:18504
0番 Redis に接続して6番 Redis をクラスタに追加します。

出力内容 ▼
💻 Terminal

2) redis-cluster-7 ノード(Node) 追加: add-node

kubectl exec -it redis-cluster-0 -- redis-cli -a redisgate --cluster add-node
redis-cluster-7.redis-cluster-service.default.svc.cluster.local:18504
redis-cluster-0.redis-cluster-service.default.svc.cluster.local:18504
0番 Redis に接続して7番 Redis をクラスタに追加します。 ⇒ '出力内容' 省略

3. スロット割り当て: rebalance

1) 'rebalance' 命令実行 ⚡

追加したノード(Node) にスロットを割り当て: 'rebalance' 命令実行
kubectl exec -it redis-cluster-0 -- redis-cli -a redisgate
--cluster rebalance redis-cluster-0.redis-cluster-service.default.svc.cluster.local:18504
--cluster-use-empty-masters
* 移動する(Moving) スロット数だけ '#' が表示されます。省略せずすべて表示しました。
* 移動するキー数だけ時間がかかります。

💻 Terminal

2) スロット割り当て確認

💻 Terminal

3) Redis-Cluster 状態確認: cluster info

💻 Terminal

4) Redis-Cluster 状態確認: cluster nodes

💻 Terminal

4. 8, 9番ノード(Node) 追加

8, 9番ノード(Node) をレプリカ(Replica) として追加します。

1) 8番ノード(Node) 追加: add-node --cluster-slave

kubectl exec -it redis-cluster-0 -- redis-cli -a redisgate --cluster add-node
redis-cluster-8.redis-cluster-service.default.svc.cluster.local:18504
redis-cluster-6.redis-cluster-service.default.svc.cluster.local:18504 --cluster-slave
8番ノード(Node) を6番ノード(Node) のレプリカ(Slave) として追加します。
オプション '--cluster-slave' を使用: 🚨 '--cluster-replica' オプションは使用不可 (Redis-8.8.2 redis-cli.c ソース確認)

出力内容 ▼
💻 Terminal

2) 9番ノード(Node) 追加: add-node --cluster-slave

kubectl exec -it redis-cluster-0 -- redis-cli -a redisgate --cluster add-node
redis-cluster-9.redis-cluster-service.default.svc.cluster.local:18504
redis-cluster-7.redis-cluster-service.default.svc.cluster.local:18504 --cluster-slave
9番ノード(Node) を7番ノード(Node) のレプリカ(Slave) として追加します。 ⇒ '出力内容' 省略

3) 追加したレプリカノード(Node) 確認

8, 9番がレプリカ(slave) として追加されたか確認: IP 199, 201 ノード(Node) の slaves が '0' から '1' に変わりました。

💻 Terminal

4) 追加したレプリカノード(Node) 確認

出力結果を見やすく整理しました。

💻 Terminal

5) 最終結果のポッド(Pod) 確認 🧮

💻 Terminal

6) メモリ確認 🧮

💻 Terminal

7) 🖧 Redis-Cluster 最終ポッド(Pod) ダイアグラム

┌────────────────┐ ┌────────────────┐ ┌───────────────┐ ┌────────────────┐ ┌────────────────┐ │ Redis-0(174) │ │ Redis-1(165) │ │ Redis-2(167) │ │ Redis-6(199) │ │ Redis-7(201) │ │ 🟢Master-1 │ │ 🟢Master-2 │ │ 🟢Master-3 │ │ 🟢Master-4 │ │ 🟢Master-5 │ └──────┬─────────┘ └──────┬─────────┘ └──────┬────────┘ └───────┬────────┘ └───────┬────────┘ │ │ │ │ │ │ ┌──────────────────│────────────────────┘ │ │ │ │ └────────────────────┐ │ │ └──────────────────┐ │ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ ┌────────────────┐ ┌────────────────┐ ┌───────────────┐ ┌────────────────┐ ┌────────────────┐ │ Redis-3(169) │ │ Redis-4(175) │ │ Redis-5(173) │ │ Redis-8(203) │ │ Redis-9(205) │ │ 🟡Replica-1 │ │ 🟡Replica-2 │ │ 🟡Replica-3 │ │ 🟡Replica-4 │ │ 🟡Replica-5 │ └────────────────┘ └────────────────┘ └───────────────┘ └────────────────┘ └────────────────┘

🧑‍💻 まとめ

クバネティス(Kubernetes) 環境で Redis-Cluster ポッド(Pod) の拡張を完了しました。



<< K8s Standalone ③ K8s Redis Summary >>

Email 返事がかかってなれば、メールでお知らせします。