【テクニカル・上級編】 Redis Sentinelによる高可用性 – Redis

Redis Sentinel:分散システムにおける「生存の境界線」を設計する

Redis Sentinelは、単なる「監視ツール」ではない。これは非同期複製(Asynchronous Replication)という、一見すると脆いパズルピースを、どうやって強固な高可用性システムへと昇華させるかという、分散合意アルゴリズムの静かなる戦場である。

多くのエンジニアが「自動フェイルオーバーをしてくれる便利なもの」と誤解しているが、アーキテクトの視点からは、Sentinelは「一貫性のない分散環境において、どうやって主権を移譲し、スプリットブレインを防ぐか」という苦闘の歴史そのものだ。

—

1. 監視の深淵:Pub/Subの向こう側

Sentinelは、マスターノードに対して定期的な `PING` を打ち込み、生存を確認する。しかし、これは単なるエコーではない。

Sentinelはマスターに対して `INFO` コマンドを定期発行し、トポロジの変化を動的に検知する。ここで重要なのは、Sentinel同士の通信だ。各Sentinelはマスターの `__sentinel__:hello` チャネルを通じて相互に情報を交換し、自身の存在をアピールする。

もしあなたが「Sentinelの通信量が多い」と嘆くなら、それは設計の誤りだ。Sentinelの通信は、システムの「心拍」である。これを最適化したいなら、ネットワークスタックのチューニングよりも、まずはトポロジのシンプルさを追求すべきだ。

2. クォーラム(定足数):民主主義による独裁の正当化

Sentinelにおいて最も誤解されやすい概念が「クォーラム(Quorum)」だ。

  • quorum: 故障と判定するために必要なSentinelの賛成数
  • majority: リーダー選出(投票)のために必要なSentinelの総数(N/2 + 1)

この二つを混同してはならない。Quorumは「マスターが本当に死んだか?」を判定する閾値であり、Majorityは「誰がフェイルオーバーを実行する特権を得るか?」を決定する閾値だ。

ここでアーキテクトが留意すべきは、「ネットワークパーティション」への耐性だ。奇数台のSentinelを配置するのは定石だが、それは単なるおまじないではない。パティションが発生した際、Majorityに到達できない側は、たとえ自分が「マスターが死んだ」と判断しても、フェイルオーバーを実行できないように設計されている。これがスプリットブレインを物理的に防ぐ防波堤となる。

3. フェイルオーバーの極限プロセス:`SENTINEL_STATE_FAILOVER_STATE_WAIT_PROMOTION`

フェイルオーバーがトリガーされた際、裏側では以下の地獄のようなシーケンスが走る。

1. SDOWN (Subjectively Down): 単一のSentinelがPING応答なしを検知。
2. ODOWN (Objectively Down): クォーラム以上のSentinelがSDOWNを認める。
3. Leader Election: Raftライクなアルゴリズムで、フェイルオーバーを主導するSentinelが選ばれる。
4. Promotion: 最も適切なスレーブ(`slave-priority`とレプリケーションオフセットで選別)をマスターに昇格させる。

ここでの極限知見:
`slave-priority` を0に設定されたノードは、決してマスターに昇格しない。これは「読み取り専用専用」のノードを明示的に作るためのフラグだが、DR(災害復旧)サイトを構築する際、誤ってここを0に設定し、フェイルオーバー時に昇格候補から外れるという悲劇が後を絶たない。

スレーブの優先順位設定例(redis.conf)
値が小さいほど昇格優先度が高い。0は昇格対象外。
replica-priority 100

4. クライアント側の適応:追従する知性

Sentinelがマスターを切り替えても、クライアントが旧マスターを見続けていれば意味がない。

ここで重要なのは、クライアントの「サービスディスカバリ」能力だ。Redisクライアントライブラリ(Jedis, Lettuce, go-redis等)は、Sentinelに対して「現在のマスターは誰か?」を問い合わせるメカニズムを備えている。

もし、貴方のアプリケーションが「フェイルオーバー中に数秒間のダウンタイムが発生する」と悩んでいるなら、それはコードの問題だ。

  • 接続プールのキャッシュ戦略: クライアントがIPを静的に保持していないか?
  • 再接続ロジック: 接続失敗時にSentinelへ再問い合わせを行う `Sentinel Discovery` を実装しているか?

これらが実装されていないクライアントは、分散システムにおける「死んだパーツ」に等しい。

5. チーフアーキテクトからの提言

Redis Sentinelを導入する際に、以下の項目をチェックリストに加えよ。

1. ネットワーク隔離: SentinelとRedisデータノードのネットワークを分離し、監視パケットがアプリケーションのトラフィックによってドロップされないようにせよ。
2. 観測性の確保: `sentinel monitor` の設定だけでなく、`sentinel failover-timeout` の値を、マスターのデータセットサイズと同期性能に応じて慎重に計算せよ。データが数GBあるのにタイムアウトを短く設定すれば、フェイルオーバーは無限ループに陥る。
3. 自動化の限界: Sentinelは銀の弾丸ではない。運用において最も重要なのは、フェイルオーバーが発生した瞬間に、その「原因」をログから特定できるパイプラインを構築することである。

Redisの美しさは、その極めてシンプルな設計の中に、分散システムの課題を凝縮させている点にある。Sentinelを使いこなすということは、Redisの「揮発性」と「可用性」の境界線上で、泥臭い現実を制御し続けることと同義だ。

さて、次はどのレイヤを掘り下げようか?アーキテクチャの真価は、トラブルが起きた瞬間にこそ試される。その準備はできているか。

コメント

タイトルとURLをコピーしました