Redis 高可用性 Sentinel メカニズムの実装の詳細

Redis 高可用性 Sentinel メカニズムの実装の詳細

この記事は私の技術ノート [1] Redis 記事から引用したものです。頻繁にアクセスしていただければ幸いです。

文章

前回の記事「Redis の高可用性パノラマ」では、Redis の高可用性について学びました。高可用性には 2 つの意味があります。1 つはサービスの中断が少ないこと、もう 1 つはデータ損失が少ないことです。マスター/スレーブ ライブラリ モードとセンチネルによりサービスの中断が少なくなり、AOF ログと RDB スナップショットによりデータ損失が少なくなります。

そして、センチネルの 3 つの責任、つまり監視、マスター選択 (マスター ライブラリの選択)、通知を学びました。今日は詳しく学びます。

まず、Sentinel を起動する前に、Sentinel を設定する必要があります。Redis ソース コードには Sentinel.conf [2] という名前のファイルが含まれており、その一部は次のように構成されています。

sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000

設定の最初の行は、mymaster という名前のマスター サーバーを監視するように Sentinel に指示します。このマスター サーバーの IP アドレスは 127.0.0.1 で、ポート番号は 6379 です。このマスター サーバーが無効であると判断するには、少なくとも 2 つの Sentinel が同意する必要があります。

ご覧のとおり、メイン ライブラリの IP とポートのみを設定します。他のセンチネルの接続情報が設定されていません。これらのセンチネル インスタンスはお互いのアドレスを知らないため、どうやってクラスターを形成するのでしょうか?

Sentinel インスタンスは、Redis が提供するパブリッシュ/サブスクライブ メカニズム、つまりパブリッシュ/サブスクライブ メカニズムのおかげで相互に検出できます。マスター/スレーブ クラスターには、マスター ライブラリに名前が付けられたチャネルがあり__sentinel__:hello、それを通じてさまざまなセンチネルが相互に検出し、通信します。

1. センチネルクラスターの構成

2 秒ごとに、各 Sentinel ノードは__sentinel__:helloマスター ノードに対する Sentinel ノードの判断と現在の Sentinel ノードの情報を Redis データ ノードのチャネルに送信します。

センチネル間の通信

例えば。上の図では、Sentinel 1 が独自の IP (172.16.19.3) とポート (26579) を__sentinel__:helloチャネルに公開し、Sentinel 2 と 3 がチャネルにサブスクライブしています。このとき、Sentinel 2 と 3 は、このチャネルから Sentinel 1 の IP アドレスとポート番号を直接取得できます。

その後、Sentinel 2、3 は Sentinel 1 とのネットワーク接続を確立できます。このようにして、Sentinel 2 と 3 もネットワーク接続を確立できるため、Sentinel クラスターが形成されます。メインライブラリがオフラインかどうかの判断や交渉など、ネットワーク接続を介して相互に通信できます。

Sentinel は相互に接続を確立してクラスターを形成するだけでなく、スレーブ ライブラリとの接続も確立する必要があります。これは、Sentinel の監視タスクでは、マスター ライブラリとスレーブ ライブラリの両方でハートビート判定を行う必要があり、マスター/スレーブ ライブラリの切り替えが完了した後、スレーブ ライブラリに新しいマスター ライブラリと同期するように通知する必要があるためです。 。

では、Sentinel はどのようにしてスレーブ ライブラリの IP アドレスとポートを知るのでしょうか?

2. スレーブノード情報の取得

これは、センチネルが INFO コマンドをメイン ライブラリに送信することによって行われます。下図に示すように、Sentinel 2 はメイン ライブラリに INFO コマンドを送信し、コマンドを受信したメイン ライブラリはスレーブ ライブラリのリストを Sentinel に返します。その後、Sentinel はスレーブ ライブラリ リストの接続情報に従って各スレーブ ライブラリとの接続を確立できます。Sentinel 1 と 3 も同じ方法でスレーブ ライブラリとの接続を確立できます。

スレーブノード情報の取得

以下は、マスター ノードで実行される info コマンドのスニペットです。

# Replication
role:master
connected_slaves:2
slave0:ip=127.0.0.1,port=6380,state=online,offset=4917,lag=1
slave1:ip=127.0.0.1,port=6381,state=online,offset=4917,lag=1

その後、Sentinel はこの接続上のスレーブ ライブラリを継続的に監視します。センチネル ノードは 10 秒ごとにマスター ノードとスレーブ ノードに info コマンドを送信して、クラスターの最新のトポロジを取得します。このようにして、新しいスレーブ ノードが参加すると、それをすぐに感知できます。ノードが到達不能になった後、または新しいマスター ライブラリが選択された後、info コマンドを使用してノード トポロジ情報をリアルタイムで更新することもできます。

情報コマンドを実行する

クラスターに関する情報を手に入れた Sentinel は、ついに活動を開始できるようになります。最初の責任は、マスター/スレーブ ライブラリがオフラインかどうかを判断することです。

3. マスタースレーブデータベースがオフラインであることをどのように判断するか?

3.1 定期的にpingコマンドを実行する

Sentinel プロセスの実行中は、マスター ノード、スレーブ ノード、および他の Sentinel ノードに 1 秒ごとに ping コマンドを送信し、それらがまだオンラインで実行されているかどうかを確認します。マスター ライブラリとスレーブ ライブラリが指定された時間内にセンチネルの ping コマンドに応答しない場合、センチネルはそれを「オフライン ステータス」としてマークします。

pingコマンドを実行する

検出がメイン ライブラリの場合、センチネルは単純にマスター/スレーブ スイッチを有効にすることはできません。なぜなら、そのような状況が存在する可能性が非常に高いからです。つまり、監視員が判断を誤ったが、実際にはメインの図書館には欠陥がありません。

一般に、誤った判断は、クラスタ ネットワークの負荷が高い場合、ネットワークが混雑している場合、またはメイン ライブラリ自体が高い負荷にさらされている場合に発生します。センチネルが判断を誤ってマスターとスレーブの切り替えを開始すると、その後のマスター選択と通知操作により、追加のコンピューティングと通信のオーバーヘッドが発生します。

では、どうすれば誤判断を減らすことができるのでしょうか?

3.2 主観的オフラインと客観的オフライン

センチネル メカニズムは通常、複数のインスタンスで構成されるクラスター モードでデプロイされます。センチネル クラスターとも呼ばれます。複数のセンチネル インスタンスを導入して一緒に判断することで、単一のセンチネルがネットワーク状態が悪いためにメイン ライブラリがオフラインであると誤って判断することを防ぐことができます。同時に、複数のセンチネルのネットワークが同時に不安定になる確率が少なく、一緒に判断することで誤判断率も減らすことができます。

主観的なオフラインと客観的なオフライン

記事の冒頭で説明した Sentinel.conf 設定を覚えていますか?

sentinel monitor mymaster 127.0.0.1 6379 2
sentinel down-after-milliseconds mymaster 60000

down-after-millisecondsこのオプションは、Sentinel がサーバーがオフラインであるとみなすクリティカルしきい値です。

Sentinel が送信した ping コマンドに対してサーバーがミリ秒以内に応答を返さない場合、またはエラーを返した場合、Sentinel はサーバーを主観的にダウンしている (略して SDOWN) とマークします。

メイン ライブラリがオフラインになったことに同意するのに十分な Sentinel が存在しない場合、メイン ライブラリが Sentinel の PING コマンドに対して有効な応答を返すと、メイン ライブラリの主観的なオフライン ステータスは削除されます。また、2 人以上のセンチネルがメイン ライブラリを主観的にオフラインとしてマークすると、メイン ライブラリは客観的にダウン (略して ODOWN) としてマークされます。センチネルは、多くのスレーブ ライブラリから新しいマスター ライブラリとなるスレーブ ライブラリを選択する次の意思決定プロセスを開始しようとしています。

4. 新しいメインライブラリを選択するにはどうすればよいですか?

4.1 初期スクリーニング

マスターが選択されているときにスレーブ ライブラリが正常に実行されている場合、それを新しいマスター ライブラリとして選択し、使用を開始すると想像してください。しかし、すぐにネットワークに障害が発生し、この時点でマスターを再選出する必要がありました。これは明らかに私たちが期待していたものではありません。したがって、マスターを選択する際には、スレーブ ライブラリの現在のオンライン状態を確認するだけでなく、以前のネットワーク接続状態も判断する必要があります。スレーブ ライブラリが常にマスター ライブラリから切断されており、その切断数が特定のしきい値を超えている場合は、スレーブ ライブラリのネットワーク状態があまり良好ではないと考えられるため、スレーブ ライブラリをフィルタリングできます。

一次審査

どのように判断するか?構成項目 down-after-milli秒 * 10 を使用します。このうち、ミリ秒後のダウンは、マスター/スレーブ ライブラリが切断されていると考えられる最大接続タイムアウト時間です。ダウンアフターミリ秒ミリ秒以内にマスター ノードとスレーブ ノードがネットワーク経由で接続されていない場合は、マスター ノードとスレーブ ノードが切断されているとみなすことができます。切断回数が 10 回を超える場合は、スレーブ ライブラリのネットワーク状態が良好ではないことを意味し、新しいマスター ライブラリとして使用するのに適していません。

このようにして、メインライブラリに適さないスレーブライブラリをフィルタリングし、スクリーニング作業が完了します。

次のステップは、残りのスレーブ ライブラリにスコアを付けることです。スレーブ ライブラリの優先順位、スレーブ ライブラリのコピーの進行状況、およびスレーブ ライブラリの ID 番号の 3 つのルールに従って、3 ラウンドのスコアリングを順番に実行できます。

4.2 3 ラウンドの採点

最初のラウンド: 最も高い優先順位を持つスレーブがより高いスコアを獲得します。

ユーザーは、スレーブ優先順位設定項目を使用して、さまざまなスレーブ ライブラリに異なる優先順位を設定できます。たとえば、メモリ サイズの異なる 2 つのスレーブ ライブラリがある場合、メモリの大きいインスタンスに高い優先順位を手動で設定できます。

第 2 ラウンド: 古いマスター ライブラリの同期度に最も近いスレーブ ライブラリのスコアが高くなります。

このルールの基礎は、古いマスター ライブラリに最も近いスレーブ ライブラリがマスター ライブラリとして選択された場合、新しいマスター ライブラリには最新のデータが含まれるということです。

スレーブ ライブラリと古いマスター ライブラリ間の同期の進行状況を判断するにはどうすればよいですか?

マスター/スレーブ ライブラリが同期されると、コマンド伝播のプロセスが発生します。このプロセス中、マスター ライブラリは master_repl_offset を使用して、repl_backlog_buffer 内の最新の書き込み操作の位置を記録し、スレーブ ライブラリは、slave_repl_offset の値を使用して現在のレプリケーションの進行状況を記録します。

マスター/スレーブ ライブラリが同期されると、コマンド伝播のプロセスが発生します。このプロセス中、マスター ライブラリは master_repl_offset を使用して、repl_backlog_buffer 内の最新の書き込み操作の位置を記録し、スレーブ ライブラリは、slave_repl_offset の値を使用して現在のレプリケーションの進行状況を記録します。

次の図に示すように、スレーブ ライブラリ 2 を新しいマスター ライブラリとして選択する必要があります。

3 ラウンド目: ID 番号が小さいスレーブが高いスコアを獲得します。

各インスタンスには ID が付けられます。これは、ここではスレーブ ライブラリの番号に似ています。現在、Redis がマスター ライブラリを選択する場合、デフォルトのルールがあります。優先度とレプリケーションの進行状況が同じ場合、ID 番号が最も小さいスレーブ ライブラリが最も高いスコアを持ち、新しいマスター ライブラリとして選択されます。

この時点で、新しいメイン ライブラリが選択され、次のステップではスレーブ ライブラリをメイン ライブラリにアップグレードします。しかし、ここで再び疑問が生じます。非常に多くの監視員がいる場合、誰がマスター/スレーブ切り替え操作を実行する必要があるのでしょうか?

4.3 マスター/スレーブ切り替えを実行するセンチネルはどれですか?

Sentinel インスタンスは、マスター ライブラリが「主観的にオフライン」であると判断する限り、他の Sentinel に SENTINEL is-master-down-by-addr コマンドを送信し、相手がマスター ライブラリがオフラインになったと考えているかどうかを尋ねます。次に、他のセンチネル インスタンスはメイン ライブラリとの関係に応じて Y または N で応答します。Y は賛成票に相当し、N は反対票に相当します。

この時点で、センチネルは他のセントリーにコマンドを送信して、マスター/スレーブ切り替えを単独で実行し、他のすべてのセントリーに投票させたいことを示すことができます。この投票プロセスは「リーダー選挙」と呼ばれます。選出されたリーダーは、最終的にマスターとスレーブの切り替えを実行する監視者です。

たとえば、現在 3 つのセンチネルがあり、クォーラム構成は 2 です。選出プロセスがどのようなものかを見てみましょう。

T1 で、S1 はメイン データベースが「客観的にオフライン」であると判断し、リーダーになりたい場合は、まず自分自身に投票し、次に S2 と S3 にそれぞれリーダーになりたいことを示すコマンドを送信します。

T2 では、S3 はメイン データベースが「客観的にオフライン」であると判断し、リーダーになりたいと考えているため、最初に自分自身に投票し、次に S1 と S2 にそれぞれコマンドを送信して、リーダーになりたいことを示します。

時間 T3 で、S1 は S3 からリーダー投票リクエストを受信します。S1 は自分自身に Y に投票したため、他のセントリーに投票できなくなり、S1 は反対を表明するために N と応答します。同時に、S2 は T2 で S3 によって送信されたリーダー投票リクエストを受信します。S2 は以前に投票したことがないため、投票リクエストを送信した最初のセンチネルには Y と応答し、後で投票リクエストを送信したセンチネルには N と応答します。したがって、T3 で、S2 は S3 に応答し、S3 が次になることに同意します。リーダー。

T4 で、S2 は T1 で S1 によって送信された投票コマンドを受信します。S2はT3でS3の投票要求に同意しているため、このときS2はS1にNを返信し、S1がリーダーになることに不支持を表明する。これは、S3 と S2 の間のネットワーク トラフィックは正常ですが、S1 と S2 の間のネットワーク トラフィックが輻輳している可能性があるため、投票リクエストの送信が遅くなるために発生します。

時間 T5 で、S1 はそれ自体から 1 票 Y を取得し、S2 から 1 票 N を取得します。S3 は、自身の Y 票に加えて、S2 から Y 票も受け取りました。この時点で、S3 はリーダーの投票の過半数を獲得しただけでなく、あらかじめ設定されたクォーラム値 (クォーラムは 2) に達したため、最終的にリーダーになりました。

次に、S3 はマスター選択操作の実行を開始し、新しいマスター ライブラリが選択された後、他のスレーブ ライブラリおよびクライアントに新しいマスター ライブラリの情報を通知します。

5. 新しいマスター ライブラリをスレーブ ライブラリとクライアントに通知します。

上記の調査を通じて、センチネルがマスター ライブラリに INFO コマンドを送信して、スレーブ ライブラリの IP アドレスとポートを取得できることがわかりました。

ただし、Sentinel はマスター ライブラリとスレーブ ライブラリにしか接続できません。これは、マスター/スレーブ ライブラリが切り替わった後、クライアントも新しいマスター ライブラリにリクエスト操作を送信する前に、新しいマスター ライブラリの接続情報を知る必要があるためです。したがって、Sentinel は新しいメイン ライブラリの情報もクライアントに伝える必要があります。

では、新しいメインライブラリの情報をどのようにしてクライアントに伝えるのでしょうか?

5.1 パブリッシュ/サブスクライブ メカニズムに基づくクライアント イベント通知

本質的に、Sentinel は特定のモードで実行される Redis インスタンスですが、リクエスト操作には対応せず、監視、マスター選択、通知のタスクを完了するだけです。したがって、各 Sentinel インスタンスは pub/sub メカニズムも提供し、クライアントは Sentinel からメッセージをサブスクライブできます。

以下の図は、いくつかの重要なチャネルと、関連するいくつかの主要なイベントを示しています。記事の最後にあるリンク [3] でさらに多くのチャンネルをチェックできます。

クライアントは、メイン ライブラリからセンチネルの構成ファイルを読み取った後、センチネルのアドレスとポートを取得し、センチネルとのネットワーク接続を確立できます。

センチネルが新しいマスター ライブラリを選択すると、クライアントには次の switch-master イベントが表示されます。このイベントは、メイン ライブラリが切り替えられ、新しいメイン ライブラリの IP アドレスとポート情報がすでに利用可能であることを示します。この時点で、クライアントは新しいメイン ライブラリのアドレスとポートを使用して通信できます。

switch-master <master name> <oldip> <oldport> <newip> <newport>

まとめ

ここまでで、見張りの仕事の責任と詳細について学びました。この記事の知識消化リンクを以下のように整理しました。

在sentinel.conf中配置哨兵
-> 没有配置其他哨兵ip,怎么组成集群的?
-> 哨兵是怎么知道从库的IP和端口的?
-> 职责1:如何判断主从库下线了?
-> 职责2:如何选定新主库?
-> 由哪个哨兵执行主从切换?
-> 职责3:如何把新主库告诉客户端?

今後もドライグッズの技術的な内容については次のコンテンツでお伝えしていきますので、お楽しみに。公開アカウント「Student Yang Technotes」では技術交流を歓迎しています。

文中に記載されているリンク

  • [1] https://www.dbses.cn/technotes
  • [2] https://github.com/redis/redis/blob/unstable/sentinel.conf
  • [3] https://redis.io/docs/management/sentinel/#pubsub-messages

添付された Redis ドキュメント

  • http://www.redis.cn/topics/sentinel.html
  • https://redis.io/docs/management/sentinel

おすすめ

転載: blog.csdn.net/yang237061644/article/details/128383818