Redisマスタがクラスタからデータ損失を切り替えるソリューション


一、データがなくなった場合
非同期コピーの同期が失われました。
クラスターから脳裂データが失われます。
1.非同期コピーが失われました
Redisマスタノードとスレーブノードとの間のデータのコピーについては、非同期的にコピーされ、クライアントがmasterノードに書き込み要求を送信すると、クライアントはOKを返し、その後、各SLaveノードに同期する。
この時点でマスターがslaaveノードに同期していない場合、あたごが発生します。マスタメモリのデータが失われます。
マスターで恒久化設定データを開くと失わないように保証できますか?答えは否定です。マスターーが発生した後、sentinelクラスターがマスターーの故障を検出し、新しいマスターーを選挙し直します。もし古いマスターーが故障回復後に再起動したら、新しいマスターーのデータを同期させる必要があります。この時、新しいマスターーのデータは空です。古いマスターのデータが更新されます。この時もデータが失われます。
2.クラスタが脳裂を発生する
まず、クラスターの脳分裂現象を理解する必要があります。これは一人で二つの脳を持っているように、いったい誰にコントロールされますか?分散型クラスタでは、分散型連携フレームzookeeperがこの問題をうまく解決し、半分以上のマシンを制御して解決した。
Redisでは、クラスタの脳分裂によってデータが失われる現象はどのようなものですか?
私たちはredisクラスタがあると仮定して、通常の状況でclientはmasterに要求を送信して、salveに同期して、sentinelクラスタはクラスタを監視して、クラスタが故障した時に自動的に故障転送します。

この時、ある原因のため、例えばネットワークの原因で、クラスタにパーティションが発生しました。マスターとslaaveノードの間で連絡が切れました。sentinel監視はしばらく連絡がないので、マスターが故障したと思います。そして再選挙して、slaveeを新しいマスターに切り替えます。しかし、Masterは故障していないかもしれません。ただ、ネットワークにパーティションが発生した場合、clientは古いmasterにデータを書きます。新しいmasterにはデータがありません。問題を発見しないと、古いmasterに大量のデータが蓄積されます。問題が発見された後、古いマスターはslaave同期の新しいマスターデータに下がりました。それでは前のデータが更新され、大量のデータがなくなりました。

上の二つのデータがなくなった場面を知ったら、私達はどうやってデータを失わないように保証しますか?分散システムでは、システムの利用可能性を測定し、4つの9、5つの9つのシステムが高い利用可能性に達したと言われています。redisクラスタに対して、データが完全に失われないことを保証することはできません。できるだけ少ないデータが失われるようにするしかないです。
どのようにしてできるだけ少ないデータの紛失を保証しますか?
redisのプロファイルには二つのパラメータがあります。設定できます。

min-slaves-to-write 1
min-slaves-max-lag 10
min-slass-to-writeデフォルトでは0、min-slass-max-lagは10です。
以上の構成を例にとって、この2つのパラメータは少なくとも1つのsalveのコピー遅延が10 sを超えてはいけないことを表しています。一旦、すべてのslaave複製と同期の遅延が10 sに達したら、マスターはいかなる要求も受け付けません。
min-slass-max-lagパラメータの値を小さくすることができます。このようにすれば、故障が発生した時に大量のデータが失われないようにします。遅延が発見されたら、この値を超えたらMasterにデータを書き込むことができません。
clientに対しては、データを一時的にローカルキャッシュとディスクに書き込み、一時的にmasterに書き込んで、データが失われないようにします。kafkaメッセージの列にデータを書き込むこともできます。時間を置いて、kafkaのデータを消費します。
上記の二つのパラメータの設定によって、データのロスをできるだけ減らすことができます。具体的な値は特定の環境でテスト設定を行う必要があります。
追加:Redis Clausterはデータをなくしますか?
Redis Clausterは強い整合性を保証しないで、いくつかの特殊なシーンで、クライアントは書き込み確認を受け取っても、データをなくしてしまう可能性があります。
シーン1:非同期コピー

clientはmaster Bに書き込みます。
マスターB回答OK
マスターBは、slaave B 1 B 2 B 3に同期します。
BはB 1 B 2 B 3の確認を待たずにclientに返信しました。slavieの同期が完了する前にマスターマシンが選択されました。その中の一つはslaaveがmasterに選ばれます。その時前にclientに書き込んだデータがなくなりました。
waitコマンドは、このようなシーンのデータセキュリティを強化することができます。
waitは現在のclientをブロックします。以前の書き込み操作で指定された数量のslavieが同期に成功しました。
waitはデータの安全性を高めることができますが、強い整合性を保証していません。
このような同期コピー方式を使っても、同期が完了していないslaaveがマスターーのために選ばれた場合があります。
場面2:ネットワークパーティション
6つのノードA、B、C、A 1、B 1、C 1、マスターー3つ、slavee 3つ、もう一つのclient、Z 1があります。

ネットワークパーティションが発生すると、A,C,A 1,B 1,C 1,B 1の2つの領域が形成される。

この時Z 1はまだBに書き込むことができます。短い時間でパーティションが回復すれば大丈夫です。クラスタ全体は正常に動作し続けますが、時間が長くなるとB 1はホームパーティションのマスターになります。Z 1はBに書き込むデータがなくなります。
maximum window(最大時間ウィンドウ)はデータ損失を低減できます。Z 1からBへの書き込みの総数を制御できます。
一定の時間が過ぎると、パーティションの多くの辺で選挙が行われますが、slaaveがマスターーとなります。この場合、パーティションの少数の辺のマスターーは書き込み要求の受け付けを拒否します。
この時間量はノードの期限切れ時間と呼ばれる非常に重要である。
マスターーは有効期限が過ぎたら、故障と見なされ、error状態になり、書き込み要求の受信を停止し、slaaveに取って代わられます。
結び目
Redis Clausterは強い整合性を保証しないで、データをなくした場面があります。
非同期コピー
マスターが成功しましたが、slaaveが同期される前にマスターマシンがなくなりました。slaaveはマスターになりました。データがなくなりました。
waitコマンドは同期にコピーできますが、データが失われず、性能に影響を与えることは全く保証できません。
ネットワークパーティション
パーティションの後にMasterが書き込み要求を受信し続けます。パーティションが回復したらこのmasterはslaaveになるかもしれません。前に書き込んだデータがなくなります。
ノードの失効時間を設定して、パーティションの間にmasterが受信した書き込みの数を減らして、データの損失を低減できます。
以上は個人の経験ですので、参考にしていただければと思います。間違いがあったり、完全に考えていないところがあれば、教えてください。