分散ロック
概要
#分散システム 上で共有したいリソースに対して #悲観的ロック を使って排他制御を実現すること
英語で Distributed Lock と言う
リソースのロック状態を管理するものを分散ロックマネージャ (Distributed Lock Manager)という
#ZooKeeper などがこれに当たる
Redlock
Redis 分散ロックマネージャとして使った分散ロックのこと
使用例と簡単な概要は 分散ロックを業務で使用したので書き留める | 株式会社CAM を見るとよい
Redis による分散ロック — Redis Documentation (Japanese Translation) に詳細な説明がある
特徴
常に一つのクライアントのみがロックを取得できる
dead-lock free
耐障害性
Redis ノードが過半数生きている限り
Redis クラスターを使う前提ぽい
ドキュメントには Redis 1台で SETNX を使って分散ロックを実現する方法も書いてあった (それは Redlock ではない)
分散ロックを使おうとなること自体が誤り
分散ロックという名の過ち - Software Transactional Memo に書いてあること
分散ロックは #リーダー選出 と同じらしい
そして、分散ロックを使うと結局は分散システム上でトランザクションを再発明することになる、とのこと
分散システムなので、ロックを取ったものが突然消えることはよくある
これによって無理やりロックを解放する必要が出てくる
例えば、一定時間経過後にロックを自動で解放する、とか
こうすると問題が2つ起きる
一つは、ロックを取ったマシンがダウンした、などで消えるケースではなく
消えたと思ってもネットワーク切断していただけで実は生きて処理を継続していた、バグとか何かの要因でいつもより処理時間が掛かって自動解放されるまで処理が終わらなかった、とかだと思われる
なので、 #Sprit-Brain と書いてある
もう一つは、ロックを解放しても処理がどこまで実行されたのかわからない、という問題
中途半端にストレージに永続化してしまったかもしれないし、実は全部の処理が終わっていたのかもしれない
これらに対処するのは大変である
そして、対処するなら結局は処理をアトミックに扱う、まさにトランザクションを分散システムの上に作ることに行き着くのだ、という記事
たぶん
追記の部分にある #冪等リトライのパターン に落とし込むのが経験上も最強な気がする