Redis クラスター障害の分析

小云云
リリース: 2023-03-17 22:18:02
オリジナル
2424 人が閲覧しました

Redis Cluster は、分散型で単一障害点を可能にする Redis の高度なバージョンです。 Redis クラスターには最も重要なノードや中心的なノードがありません。このバージョンの主な目的の 1 つは、線形スケーラブルな機能を設計することです (ノードは自由に追加および削除できます)。

この記事では主にRedisクラスターの障害に関する詳細な分析を紹介しますので、皆様のお役に立てれば幸いです。

障害の症状:

Redisのクエリが失敗したことを示すビジネスレベルの表示プロンプト

クラスター構成:

3つのマスターと3つのスレーブ、各ノードには8GBのデータがあります

マシンの分散:

同じラック内で、

xx.x.xxx.199
xx.x.xxx.200
xx.x.xxx.201

redis-serverプロセスステータス:

コマンドを通過しましたps -eo pid,lstart grep $pid,

プロセスが 3 か月間継続的に実行されていることがわかりました

障害が発生する前のクラスターのノード ステータス:

xx.x.xxx.200 :8371( bedab2c537fe94f8c0363ac4ae97d56832316e65) マスター
xx.x.xxx.199:8373(792020fe66c00ae56e27cd7a048ba6bb2b67adb6) スレーブ
xx.x.xxx.201:8375(5ab4f85) 306da6d 633e4834b4d3327f45af02171b) マスター
xx.x.xxx.201:8372(826607654f5ec81c3756a4a21f357e644efe605a) スレーブ
xx.x.xxx.199:8370(462cadcb41e635d460425430d318f2fe464665c5)マスター
xx.x.xxx.200:8374(1238085b578390f3c8efa30824fd9a4baba10ddf)スレーブ

------------------- --- ----------以下はログ解析です ------------------------ ----- --

ステップ 1:
マスター ノード 8371 がスレーブ ノード 8373 との接続を失いました:
46590:M 09 Sep 18:57:51.379 # スレーブ xx.x.xxx.199 との接続:8373 が失われました。

ステップ 2:
マスター ノード 8370/8375 は、8371 が接続されていないと判断します:
42645:M 09 Sep 18:57:50.117 * ノード bedab2c537fe94f8c0363ac4ae97d56832 をマーキング316e65 は失敗しました (定足数に達しました)。

ステップ 3:
ノード 8372/8373/8374 から、8371 が失われたというマスター ノード 8375 を受信しました:
46986:S 09 Sep 18:57:50.120 * 5ab4f85306da6d633e4834b4d3327f から FAIL メッセージを受信しました45af02171b bedab2c537fe94f8c0363ac 4ae97d56832316e65

ステップ 4 :
マスター ノード 8370/8375 認証 8373 マスター ノード転送へのアップグレード:
42645:M 09 Sep 18:57:51.055 # エポック 16 の 792020fe66c00ae56e27cd7a048ba6bb2b67adb6 にフェイルオーバー認証が付与されました

ステップ 5:
元のノード 837 1 変更自分の設定を変更し、8373 のスレーブ ノードになります:
46590:M 09 Sep 18:57:51.488 # 設定変更が検出されました。792020fe66c00ae56e27cd7a048ba6bb2b67adb6 のレプリカとして再設定しています

ステップ 6:
マスター ノード8370/8375/8373クリア 8371 障害ステータス:
42645:M 09 Sep 18:57:51.522 * ノード bedab2c537fe94f8c0363ac4ae97d56832316e65 の失敗状態をクリア: スロットのないマスターが再び到達可能になりました。

ステップ 7:
新しいスレーブから開始ノード 8371 と新しいマスター ノード8373、最初の完全なデータ同期:
8373 ログ : :
4255:M 09 Sep 18:57:51.906 * スレーブ xx.x.xxx.200:8371
4255:M 09 Sep 18:57:51.906 * によって完全再同期が要求されましたターゲットとの同期のための BGSAVE の開始: ディスク
4255: M 09 Sep 18:57:51.941 * pid 5230
8371 ログによってバックグラウンド保存が開始されました:
46590:S 09 Sep 18:57:51.948 * マスターからの完全な再同期: d7751c4ebf1e63d3baebea1ed409e0e 7243a4423:440721 826993

ステップ 8:
マスターノード 8370/8375 は、8373 (新しい所有者) が失われたと判断します:
42645:M 09 Sep 18:58:00.320 * ノード 792020fe66c00ae56e27cd7a048ba6bb 2b67adb6 は失敗しました (クォーラムに達しました)。

ステップ 9:
マスター ノード 8370/8375 決定 8373 (新しいマスター) が復元されました:
60295:M 09 Sep 18:58:18.181 * ノード 792020fe66c00ae56e27cd7a048ba6bb2b67adb6 の FAIL 状態をクリアします: 再び到達可能ですが、誰もいませんしばらくしてからスロットを処理する

ステップ 10:
完全同期を完了するには BGSAVE 操作が必要です:
5230:C 09 Sep 18:59:01.474 * DB はディスクに保存されました
5230:C 09 Sep 18:59:01.491 * RDB : コピーオンライトで使用されるメモリ 7112 MB
4255:M 09 Sep 18:59:01.877 * バックグラウンド保存は成功で終了しました

ステップ 11:
ノード 8371 から開始してマスター ノード 8373 から受信したデータ:
46590:S 09 Sep 18:59:02.263 * MASTER <-> SLAVE sync: マスターから 2657606930 バイトを受信

ステップ 12: マスター ノード 8373 は、スレーブ ノード 8371 が出力バッファを制限していることを検出しました:
4255 :M 09 Sep 19:00:19.014 # クライアント id=14259015 addr=xx.x.xxx.200:21772 fd=844 name= age=148 idle=148 flags=S db=0 sub=0 psub=0 multi= -1 qbuf=0 qbuf-free=0 obl=16349 oll=4103 omem=95944066 events=rw cmd=psync は出力バッファ制限を克服するためにできるだけ早く閉じるようにスケジュールされています。
4255:M 09 Sep 19:00:19.015 # 接続スレーブ xx.x.xxx.200 と: 8371 が失われました。

ステップ 13:
スレーブ ノード 8371 がマスター ノード 8373 からのデータの同期に失敗し、接続が切断され、最初の完全な同期が失敗しました:
46590:S 09 Sep 19:00:19.018 # 同期しようとしたときに I/O エラーが発生しましたMASTER との接続: 接続が失われました
46590:S 09 Sep 19:00:20.102 * MASTER xx.x.xxx.199:8373 に接続中
46590:S 09 Sep 19:00:20.102 * MASTER <-> SLAVE 同期が開始されました。

ステップ 14:
ノード 8371 から同期を再開します。接続が失敗しました。マスター ノード 8373 への接続数がいっぱいです:
46590:S 09 Sep 19:00:21.103 * MASTER xx.x.xxx に接続中.199:8373
46590:S 09 Sep 19:00:21.103 * MASTER <-> SLAVE 同期が開始されました
46590:S 09 Sep 19:00:21.104 * SYNC の非ブロック接続によりイベントが発生しました。
46590:S 09 Sep 19: 00:21.104 # マスターからの PING へのエラー応答: '-ERR クライアントの最大数に達しました'

ステップ 15:
スレーブ ノード 8371 がマスター ノード 8373 に再接続し、2 回目の完全同期を開始します:
8371 ログ:
46590:S 09 Sep 19:00:49.175 * MASTER xx.x.xxx.199:8373
46590:S 09 Sep 19:00:49.175 * MASTER <-> SLAVE 同期が開始されました。
46590:S 09 Sep 19:00:49.175 * SYNC のノンブロッキング接続によりイベントが発生しました。
46590:S 09 Sep 19:00:49.176 * マスターが PING に応答したため、レプリケーションを続行できます...
46590:S 09 Sep 19:00:49.179 * 部分的な再同期は不可能です (キャッシュされたマスターなし)
46590:S 09 Sep 19:00:49.501 * マスターからの完全な再同期: d7751c4ebf1e63d3baebea1ed409e0e7243a4423:440780763454
8373 ログ:
4255:M 09 9月 19:00:49.176 * スレーブ xx.x .xxx.200:8371 が同期を要求します
4255:M 09 Sep 19:00:49.176 * スレーブ xx.x.xxx.200:8371
4255:M 09 Sep 19:00 によって完全な再同期が要求されました: 49.176 * ターゲットで同期のための BGSAVE を開始: ディスク
4255:M 09 Sep 19:00:49.498 * pid 18413
18413:C 09 Sep 19:01:52.466 * DB がディスクに保存されました
18413:C 09 Sep 19:01:52.620 * RDB: コピーオンライトで 2124 MB のメモリが使用されました
4255:M 09 Sep 19:01:53.186 * バックグラウンド保存は正常に終了しました

ステップ 16:
ノード 8371 からのデータを同期しました成功し、エクスペリエンスの読み込みを開始しました メモリ:
46590:S 09 Sep 19:01:53.190 * MASTER <-> SLAVE sync: マスターから 2637183250 バイトを受信中
46590:S 09 Sep 19:04:51.485 * MASTER <- > スレーブ同期: 古いデータをフラッシュしています
46590:S 09 Sep 19:05:58.695 * MASTER <-> スレーブ同期: メモリに DB をロードしています

ステップ 17:
クラスターが通常に戻ります:
42645 :M 09 Sep 19:05: 58.786 * ノード bedab2c537fe94f8c0363ac4ae97d56832316e65 の FAIL 状態をクリアします: スレーブは再び到達可能です。

ステップ 18:
ノード 8371 からのデータを正常に同期します (7 分かかります):
46590:S 09 9 月 19: 08:19. 303 * MASTER < -> スレーブ同期: 正常に終了しました


複数のマシンが同じラック内にあるため、ネットワークが中断される可能性は低いですスロー クエリ ログを確認した後、KEYS コマンドが実行されたことがわかりました。これには 8.3 秒かかりました。次に、クラスター ノードのタイムアウト設定を確認したところ、5 秒 (cluster-node. -timeout 5000)


ノードが接続を失った理由:


クライアントは 8.3 秒かかったコマンドを実行し、

2016/9/9 18:57:43 と KEYS の実行を開始しました。コマンド

2016/9/9 18:57:50 8371 が切断されたと判断されました (redis ログ)
2016/9/9 18:57:51 KEYS コマンド実行後



まとめると以下の問題があります:

1. クラスターノードタイムアウトの設定が比較的短いため、KEYS のクエリによりクラスター判定ノード 8371 が接続を失いました

2。8371 が接続を失ったため、8373 がマスターにアップグレードされました。マスターとスレーブの同期を開始しました


3. client-output-buffer-limit の設定の制限により、最初の 2 番目の完全な同期は失敗しました


4. PHP クライアントの接続プールの問題により、サーバーに必死に接続した結果、SYN 攻撃に似た効果が発生しました


5. 最初の完全同期が失敗した後、スレーブ ノードがマスター ノードに再接続しました。30 秒かかりました (最大接続数を 1 時間超過しました)。



client-output-buffer-limit パラメータについて:

# The syntax of every client-output-buffer-limit directive is the following: 
# 
# client-output-buffer-limit <class> <hard limit> <soft limit> <soft seconds> 
# 
# A client is immediately disconnected once the hard limit is reached, or if 
# the soft limit is reached and remains reached for the specified number of 
# seconds (continuously). 
# So for instance if the hard limit is 32 megabytes and the soft limit is 
# 16 megabytes / 10 seconds, the client will get disconnected immediately 
# if the size of the output buffers reach 32 megabytes, but will also get 
# disconnected if the client reaches 16 megabytes and continuously overcomes 
# the limit for 10 seconds. 
# 
# By default normal clients are not limited because they don&#39;t receive data 
# without asking (in a push way), but just after a request, so only 
# asynchronous clients may create a scenario where data is requested faster 
# than it can read. 
# 
# Instead there is a default limit for pubsub and slave clients, since 
# subscribers and slaves receive data in a push fashion. 
# 
# Both the hard or the soft limit can be disabled by setting them to zero. 
client-output-buffer-limit normal 0 0 0 
client-output-buffer-limit slave 256mb 64mb 60 
client-output-buffer-limit pubsub 32mb 8mb 60
ログイン後にコピー


実行するアクション:


1 。インスタンスを 4G 未満に、そうしないと、マスターとスレーブの切り替えに時間がかかります

2. プロセスの途中で同期が失敗しないように、client-output-buffer-limit パラメーターを調整します


3. クラスター ノード タイムアウトを調整します。 15秒未満にすることはできません


4. マスター/スレーブの切り替えにつながるため、クラスターノードのタイムアウトよりも長い時間がかかるクエリを禁止します


5. SYN攻撃に似たクライアントのおかしな接続方法を修正します


関連おすすめ:

Redisクラスター構築の全記録

Redisクラスター仕様知識の詳細な説明

redisクラスターの練習

以上がRedis クラスター障害の分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート