プロダクションで2年間Redis Clusterを運用してみて


TL;DR

  • Redis Clusterで運用は本当に楽になった
    • でも、Redis 4.0は不安
  • Redis Clusterで一番怖いのはDisk IO
    • 特にフェイルオーバーなどのFull Resync時

Redisとは?

  • 高速なインメモリ型のKVS
  • シングルスレッド
  • 豊富なデータ構造(次ページにて詳細)
  • 豊富な操作(次々ページにて詳細)

豊富なデータ構造

  • key-value型
  • hash型(key-field-value)
  • set型(集合演算ができる)
  • sorted set型(スコア付きset)
  • 任意の型(redis modules機能)

豊富な操作

  • インクリメントや和集合などなど
  • lua scriptも実行できちゃう
    • シングルスレッドだからatomicな処理になる

Redisの問題点

  • writeがスケールしない
  • 気軽に停止できない
    • サーバー再起動やバージョンアップなど

Redis Cluster登場

  • キーごとに水平シャーディング
    • writeがスケールする!
  • 無停止フェイルオーバーができる
    • サーバーの停止ができる!
    • Redisのバージョンアップができる!

Redis Clusterの問題点

  • multiple key操作がしにくくなった
Redisではできた
del key1 key2 key3

Redis Clusterではしにくい

同じスロット(※)に割り当てられたキーにしか出来ない。
↓は一応できる。

del {key}1 {key}2 {key}3

スロット(slot)
  • redis clusterのシャーディングする際の単位
  • cluster全体で16384個のslotを持つ
  • ある特定のキーはhash計算され、いずれかのスロットに割り当てられる
  • multiple key操作は、同一スロット内にしか行えない
  • キー名の一部を{}で囲むと、{}内に囲まれた文字でhash計算される
    • つまり、同一のスロットに明示的に割り当てられる
    • key1とkey2は別スロットになるが
    • {key}1と{key}2は同じスロットになる

Redis Clusterの問題点2

  • リソースを富豪的に使う

リソースを相当富豪的に使う

  • メモリ使いすぎ
  • 既定値では、masterがactive,slaveはstandby
  • slaveに持たせている分のデータは利用されない
    • slaveにreadを向かせたい場合は、設定変更が必要
    • クライアントライブラリの対応も必要

リソースを相当富豪的に使う2

  • 機材使いすぎ
  • Redis Clusterの最小推奨構成はmaster3/slave3
    • 物理サーバー故障も考えると、サーバー筐体3台必須
    • なぜmaster3/slave3が最小推奨構成かは後述

ここまでがRedis Clusterの概要


ここからが運用していく中で感じたこと


結局、推奨構成は?

  • masterは3ノード以上の奇数
  • masterとslaveの比率は1:2以上

why?masterが3ノード以上の奇数?

masterの数を増やすと

  • writeが分散される
  • 複数のmasterが同時にダウンした時の可用性が向上する

障害時にslaveの昇格投票ルール

  • 全masterのうちの過半数の賛成票が必要
例えば
  • 3masterでClusterを組むと
    • 2master同時にダウンすると、生きているmasterは1つ
    • つまり、過半数(2つ以上)の賛成票は絶対得られない
  • 4masterでClusterを組むと
    • 2master同時にダウンすると、生きているmasterは2つ
    • つまり、過半数(3つ以上)の賛成票は絶対得られない
  • 5masterでClusterを組むと
    • 2master同時にダウンすると、生きているmasterは3つ
    • つまり、過半数(3つ以上)あの賛成票を得られる

※最小推奨構成がmaster3/slave3なのは、この投票ルールのせい


masterを3ノード以上の奇数にするのは

同時にmasterがダウンした時にも
サービス継続できるようにするため。


why?masterとslaveの比率は1:2以上?

  • masterが連続でダウン(not同時)した時の可用性が向上する

slaveの融通(レプリカマイグレーション)

masterとslaveの比率が1:1だったら?
masterがダウンし、slaveが昇格した後、
昇格した元slaveには、slaveはいない。

つまり、昇格した元slaveが単一障害点になる。

masterとslaveの比率が1:2以上なら
slaveを持っていない単一障害点のmasterには、他のslaveを複数持つmasterから、slaveを自動で融通してもらえる。


master:slave比率を1:2以上にするのは

連続でmasterがダウンした時にも、
サービス継続できるようにするため。


Redis Clusterの可用性まとめ

例えば、
Redis 15インスタンス(5master,10slave)構成では

  • masterが2ノード同時に落ちても、サービス継続できる
  • 悲観的に適当な6ノードが連続で落ちても、サービス継続できる

つまり、夜に熟睡できる!


Redis Clusterのイケてないところ

  • Disk IOが激しい

可用性のためのmaster昇格やslave融通の際、
毎回Full Resyncが走る。

Full Resyncが走れば、Redisのバックアップファイルである
RDBやAOFのDisk Writeがバカにならない。
(つらい、上手いこと部分同期してくれ)

実際にあった事例

Disk IOが詰まり、masterノードが死と判定され、
slaveが昇格。

slave昇格時のDisk IOがやっぱり詰まり、またすぐに死判定され、
また別のslaveが昇格。連鎖的に昇格祭り。

解決方法
- Disk IOの遅さを改善したり(RAID ControllerやSSD)
- そもそも大きなデータを減らしたり
- AOFやRDBのバックアップを停止させたり


今後のRedis Clusterの不安事

  • 現在Redis最新は3.2.6
  • 開発中のは4.0.0-RC2
  • 3系と4系を混ぜてCluster組めないっぽい

3系で作ったClusterから4系への移行、どうしよう。
今から新規に組むなら、4系を待つ選択肢も。


その他

  • フェイルオーバー(昇格)の検知は、nodes.confファイルのタイムスタンプで検知できる
  • Cluster組む前に色々、redis.confは設定すべき
    • ノードが死んだと判断されるまでの秒数
    • 1ノードが死んだ時にCluster全体を死ぬ判定にするか、そのノードを担当していたキーだけを死んだ判定にするか
    • 細かい設定はRedis cluster tutorial参照
  • Redisのノード間の通信(GOSSIP)の非効率さ、なんとかならないのか・・・
    • ノードIDが無駄に長いせいなんだけど・・・

まとめ

  • Redis Clusterで夜、安心して眠れる
  • 3系から4系への移行どうしよう
  • 良きRedis Clusterライフを