私たちのセットアップ
- 各 AWS シドニー AZ に 1 つずつ、3 つの redis センチネル
- AWS Auto-scaling グループ ポリシーを使用して水平方向に自動的にスケーリングするマスターと複数のスレーブを備えた 2 ~ 500 個の redis ノード
- トラフィックをマスターにプッシュする 1x 書き込み ELB
- トラフィックをスレーブにプッシュする ELB の読み取り x 1
- Sentinel にトラフィックをプッシュする 1x Sentinel ELB
- ファシリテーター x 1 (詳細は以下を参照)
このセットアップは、メタデータとキャッシュと呼ばれるもののために 2 つのクラスターに複製されます。より多くのクラスターを展開したいと考えています。
ファシリテーター
Sentinels pub/sub にサブスクライブし、+switch-masterメッセージをリッスンする、私たちが構築した Python デーモンです。ファシリテーターが実行するアクションは次のとおりです。
- +switch-master によってトリガーされたマスター フェイルオーバーを検出し、マスターします。
- 次を使用して、新しいマスターのセンチネルを照会します
SENTINEL get-master-addr-by-name mymaster
- RedisClusterNodeRole = slave で古いマスターにタグを付けます
- RedisClusterNodeRole = master で新しいマスターにタグを付けます
- 書き込み ELB に新しいマスターを追加します
- 読み取り ELB から新しいマスターを削除します
- 書き込み ELB から古いマスターを削除します
- 古いマスターを読み取り ELB に追加しようとします (サーバーがダウンしている場合、これは失敗しますが、問題ありません)。
問題
スレーブはトラフィックに応じて 1 日に複数回出入りする可能性があるため、両方のクラスターのセンチネルに属する一部のスレーブが同じスレーブをめぐって争うことになります。これは、IP プールがクラスター間で共有されているために発生します。私たちが知る限り、スレーブ ID はそれらの IP です。
複製する方法は次のとおりです。
- クラスタ キャッシュには IP 172.24.249.152のマスターがあります
- クラスター キャッシュには、IP 172.24.246.142のスレーブをマスターに昇格させるマスター フェールオーバーがあります。IP 172.24.249.152 のノードがオフになりました
- クラスター メタデータがスケールアップし、DHCP が IP 172.24.249.152 (クラスター キャッシュ上の以前のマスター) を割り当てます。
- クラスター キャッシュは、以前のマスターが起動していることを認識し、172.24.246.142 (キャッシュ クラスターの新しいマスター)のスレーブとして再構成しようとします。
- クラスター メタデータは 172.24.246.142 で +sdown をトリガーし、しばらくして -sdown に続いて +slave-reconf-sent をトリガーし、メタデータ クラスターのスレーブとして再構成を試みます。
- クラスタ キャッシュは、クラスタ メタデータがポイント 5 で行っているのと同じことをしようとします。
センチネルは、そのリソースを永遠に奪い合うこの無限ループに陥ります。異なるマスター名を持つ両方の redis クラスターを管理するセンチネル グループしかない場合でも、これは発生します。これにより、センチネルは異なるクラスター間のリソースを認識しておらず、クラスターごとに論理的なことを個別に実行していると考えられます。
試した解決策
- +sdown イベントの後に a をトリガー
SENTINEL reset mymaster
して、センチネルにそのノードを忘れさせようとします。これに関する問題は、そのクラスターがマスター フェイルオーバーを実行している場合に競合状態が発生する可能性があることです。私たちはこの仮定をうまく複製し、1 つのマスターを指し、他の 2 つが別のマスターを指しているという、非同期のセンチネルを残しました。 - クラスターごとに 1 つの IP のプールにネットワークを分離します。これは、IP が再利用されないため機能しますが、新しいクラスターが必要な場合に、機敏性が大幅に低下し、複雑になります。これが最終的な解決策ですが、可能であれば回避したいと考えています。
理想的なソリューション
Redis Sentinel は
SENTINEL removeslave 172.24.246.142 mymaster
、スレーブで +sdown イベントが発生するたびに実行できる を提供します。これにより、そのクラスタは、a が持つ副作用を作成することなく、そのスレーブが存在していたことを忘れますSENTINEL reset mymaster
。IP だけでスレーブの一意性を識別するのをやめます。おそらく、redisサーバーの開始タイムスタンプまたはその他のトークンを追加して、シャットダウンされたスレーブと、同じIPで再起動された新しいスレーブが同じノードとして表示されるのを防ぎます。
質問
redis センチネル コードの変更を伴わず、クラスター間で IP プールを分離する必要のない他のソリューションを考えられますか?