k8s_redis_scaleout
クバネティス(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) があります。
2) ポッド(Pod) 追加: 6個 -> 10個 ⚡
3) ポッド(Pod) 追加後の確認 🧮
redis-cluster-6~9: 4つのポッド(Pod) 追加作成完了
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 をクラスタに追加します。
出力内容
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) スロット数だけ '#' が表示されます。省略せずすべて表示しました。
* 移動するキー数だけ時間がかかります。
2) スロット割り当て確認
3) Redis-Cluster 状態確認: cluster info
4) Redis-Cluster 状態確認: cluster nodes
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 ソース確認)
出力内容
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' に変わりました。
4) 追加したレプリカノード(Node) 確認
出力結果を見やすく整理しました。
5) 最終結果のポッド(Pod) 確認 🧮
6) メモリ確認 🧮
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 >> |
|---|
