私は先週、Linuxの人たちとシナリオをテストし、この実装のC#側で作業することに時間を費やすことができ、次のアプローチを使用しています。
- 設定から番兵アドレスを読み取り、それらに接続するためのConnectionMultiplexerを作成します
- +switch-masterチャネルにサブスクライブする
- 各センチネルサーバーに、マスターRedisとスレーブが何であるかを順番に尋ね、それらすべてを比較して、すべてが同意していることを確認します
- 監視員から読み取ったredisサーバーアドレスを使用して新しいConnectionMultiplexerを作成して接続し、イベントハンドラーをConnectionFailedとConnectionRestoredに追加します。
- + switch-masterメッセージを受信したら、redis ConnectionMultiplexerでConfigure()を呼び出します
- ベルトとブレースのアプローチとして、接続タイプがConnectionType.Interactiveの場合、connectionFailedまたはconnectionRestoredイベントを受信してから12秒後にredis ConnectionMultiplexerで常にConfigure()を呼び出します。
通常、redisマスターを失ってから約5秒後に、作業して再構成していることがわかります。この間、書き込みはできませんが、読み取ることはできます(スレーブを読み取ることができるため)。データは非常に迅速に更新され、数秒後に古くなるため、5秒で問題ありません(その後上書きされます)。
私が確信していなかったことの1つは、インスタンスがダウンしたときにredis ConnectionMultiplexerからredisサーバーを削除するか、接続の再試行を続行するかどうかでした。スレーブとしてミックスに戻ってきたらすぐに再試行することにしました。接続を再試行する場合としない場合でパフォーマンステストを行いましたが、ほとんど違いがないようでした。たぶん誰かがこれが正しいアプローチであるかどうかを明確にすることができます。
以前はマスターだったインスタンスを戻すと、混乱が生じることがあります。戻ってから数秒後に、書き込みの例外が発生します。「READONLY」は、スレーブに書き込めないことを示します。これはまれでしたが、接続状態の変更から12秒後にConfigure()を呼び出す「キャッチオール」アプローチでこの問題が発生することがわかりました。 Configure()の呼び出しは非常に安価であるように思われるため、必要かどうかに関係なく2回呼び出すことは問題ないように思われました。
スレーブができたので、キースキャンを行うデータクリーンアップコードの一部をスレーブにオフロードしました。これは私を幸せにします。
全体として、私はかなり満足しています。完璧ではありませんが、めったに起こらないことがある場合は、それで十分です。