Redis 分散ロックをマスターする:実証済みのパターン、一般的な落とし穴、および実用的なアプリケーション

はじめに
分散ロックは、運用環境で実際に依存するまでは単純に思えます。
1 つのプロセスにはリソースへの排他的アクセスが必要です。複数のサーバーが稼働しています。 Redisは真ん中に座っています。アイデアは単純明快です。Redis にロックを設定して次に進みます。
しばらくの間は、このアプローチがうまくいくようです。その後、プロセスがクラッシュしたり、ネットワーク遅延が発生したり、遅延が急増したりします。突然、2 つのプロセスが同じロックを要求したり、そのロックを所有するプロセスが存在しなかったり、ロックが解放されなかったりします。
Redis のロックの問題のほとんどは、Redis 自体が原因ではありません。このような問題が発生するのは、分散ロックが誤解されることが多いためです。 Redis は調整のためのツールを提供するものであり、完全な排他性を保証するものではありません。
分散ロックとは実際には何ですか
分散ロックはメモリ内のミューテックスと同じではありません。絶対的な保証はなく、失敗を排除することもできません。
分散ロックは、信頼性の低い環境で動作する調整メカニズムです。ネットワークに障害が発生し、プロセスがクラッシュし、クロックがずれます。完璧な動作を前提としたロック戦略はいずれ破綻します。
Redis ロックはベストエフォート型のロックです。正しく設計されていれば、非常に効果的です。何気なく実装すると、微妙な競合状態やデータ破損が発生します。
Redis ロックを安全に使用するための最初のステップは、期待値を調整することです。
Redis ロックが理にかなっている場合
Redis 分散ロックは、次の場合に適しています。
-
クリティカルセクションの同時実行を防ぐ必要があります
-
作業は複数のサーバー間で調整する必要があります
-
操作は短期間です
-
再試行は可能です
一般的な使用例には、ジョブの重複排除、スケジュールされたタスクの調整、キャッシュの再構築、二重処理の防止などがあります。
Redis ロックは、長時間実行されるビジネス トランザクション、ユーザー向けの重要なワークフロー、または安全に再試行できない操作には適していません。再試行が受け入れられない場合、Redis ロックは間違ったツールです。
Redis の唯一の安全なロック プリミティブ
最も安全な Redis ロック プリミティブは、単一のアトミック コマンドです。
SET キー値 NX EX ttl
このコマンドは、ロックがまだ存在しない場合にのみロックを作成し、一意の所有者の値を割り当て、ロックが自動的に期限切れになるように TTL を設定します。
他のアプローチでは競合状態が発生します。 TTL なしで SETNX を使用するか、別の手順で有効期限を設定すると、失敗して中断されます。 TTL は必須であり、プロセスが予期せずクラッシュしたときにシステムを保護します。
ロック TTL が必須である理由
TTL がないと、Redis ロックは永久に存続する可能性があります。ロックを保持しているときにプロセスがクラッシュすると、システムはサイレントに停止します。
TTL はロックを自己修復します。障害が発生すると、ロックは最終的に期限切れになり、進行が再開できるようになります。これにより、一時的に重複が生じる可能性がありますが、そのトレードオフは意図的なものです。
有効期限が切れないロックは、ロックがないことよりも危険です。
ロックの所有権と安全な解放
Redis ロックは、それを取得したプロセスによってのみ解放される必要があります。このため、ロック値は定数文字列ではなく、一意の識別子である必要があります。
ロックを解除するには、所有権を確認する必要があります。安全なアプローチは、保存された値をチェックし、予想される所有者と一致する場合にのみロックを削除する Lua スクリプトを使用することです。
これにより、ロックの有効期限が切れ、別のプロセスによって取得され、元の所有者によって誤って削除されるという競合状態が防止されます。
安全なロック期間の選択
ロック TTL は、保護された操作の予想される最大実行時間を超える必要があります。平均実行時間を使用するだけでは十分ではありません。
作業の実行中にロックの有効期限が切れた場合、別のプロセスがロックを取得し、同じ作業を同時に実行する可能性があります。これにより、重複や破損が発生する可能性があります。
同時に、TTL が長すぎると、何か問題が発生した場合の回復が遅れます。ロック期間は、システムの変化に応じて変化するバランスです。
ロックされた作業を小さく制限しておくことが、最も安全なアプローチです。
ロック拡張機能とハートビート
一部の操作には予想より時間がかかります。 TTL を定期的に更新してロックを拡張することは可能ですが、複雑さが増し、新しい障害モードが追加されます。
ロック所有者のみが TTL を延長できるようにする必要があり、所有権が失われた場合は延長を直ちに停止する必要があります。
多くの場合、ロック拡張ロジックを実装するよりも、作業を小さなチャンクに再設計する方が安全です。
レッドロック論争
Redlock は、複数の Redis インスタンスを使用してロックの安全性を向上させるアルゴリズムです。また、これは物議を醸しており、運用が複雑です。
ほとんどのシステムでは、Redlock は利点よりも複雑さをもたらします。これは、現実の環境では保証することが難しいタイミングの仮定に依存しています。
Redlock レベルの保証が必要な場合、Redis は適切なツールではない可能性があります。トランザクション ロックまたは特殊な調整システムを備えたデータベースの方が適している可能性があります。
ほとんどの Redis の使用例では、適切な TTL ベースのロックを備えた単一の Redis インスタンスで十分です。
ロックはトランザクションではありません
Redis ロックは操作をトランザクション化しません。自動ロールバックは提供されず、運用中に障害が発生した場合の一貫性も保証されません。
ロックは同時実行性を低下させます。失敗をなくすものではありません。クリティカル セクションは、繰り返し実行しても害が生じないように、冪等になるように設計する必要があります。
この設計原則により、ロック関連のバグのリスクが大幅に軽減されます。
Redis がダウンすると何が起こるか
Redis がダウンするか再起動すると、すべてのロックが消えます。これは予期された動作です。
Redis がオンラインに戻ると、複数のプロセスが同時にロックを取得し、作業を開始する可能性があります。システムはこの可能性を許容する必要があります。
Redis の再起動中にロックが失われると破損が発生する場合、ロックの設計は安全ではないため、再検討する必要があります。
本番環境でのロックの監視
Redis ロックは決して非表示にすべきではありません。チームは、存在するロックの数、ロックの存続期間、およびロックの取得が失敗する頻度を監視する必要があります。
異常に長く存続するロックは、プロセスが停止していることを示します。頻繁に取得が失敗する場合は、競合または不正なロック設計が示唆されます。
安全な操作には視認性が不可欠です。
一般的な Redis ロックのアンチパターン
よくある間違いには、TTL なしで SETNX を使用すること、ロックの所有権に定数値を使用すること、ロックをやみくもに削除すること、長時間実行されるタスクのロックを保持すること、ロックが正確性を保証すると仮定することなどが含まれます。
これらのアンチパターンは、実際の運用停止で頻繁に発生します。
実用的なロックのチェックリスト
安全な Redis ロックの実装には次のものが含まれます。
-
TTL でキーをロックする
-
一意のロック所有権の値
-
リリース時の所有権の確認
-
存続期間が短いクリティカル セクション
-
冪等な操作
-
テストされた障害パス
これらのいずれかが欠けている場合は、ロックの設計を再検討する必要があります。
Redis ロックの健全なメンタル モデル
Redis ロックはエアバッグではなくシートベルトです。被害は軽減されますが、事故を完全に防ぐことはできません。
慎重に使用すると、分散システムでの調整が簡素化されます。何気なく使用すると、微妙で永続的なバグが発生します。
概要
分散ロックは失敗が避けられないため困難です。 Redis は、完璧ではなく、高速かつシンプルで実用的なロック メカニズムを提供します。
障害に備えて設計し、ロックを短くし、TTL を一貫して使用し、操作を安全に再試行できるようにします。正しく使用すると、Redis 分散ロックは実稼働システムにおいて信頼性が高く効果的なツールとなります。
-
.NET Core での Redis 統合をマスターする:実践ガイド
はじめに Redis は、最新のアプリケーションのキャッシュ、セッション ストレージ、メッセージ ブローカリング、パブリッシュ/サブスクライブ通信に広く使用されている高速なメモリ内キー/値ストアです。軽量でパフォーマンスが高く、開発者にとって使いやすいため、スケーラブルなシステムを構築するための有力な選択肢となります。 .NET Core で開発していて、Redis をアプリケーションに統合したい場合、この記事では StackExchange.Redis ライブラリを使用して基本的な Redis 操作を実行する方法を説明します。 Windows システムで作業している場合は、Redis
-
RedisセキュリティコースがRedis大学で公開されました
過去数か月間、Redis教育チームはRedisのセキュリティをカバーする新しいコースに懸命に取り組んできました。本日、RU330:RedisSecurityの一般提供を発表できることをうれしく思います。本番環境でRedisを実行している場合は、必ずサインアップする必要があります。 さらに説得力が必要な場合は、読み進めてください。 なぜRedisセキュリティなのか その塩に値するデータベースは安全でなければならないというのは普遍的な真実です。しかし、どのように Redisを保護しますか?正直なところ、Redisの初期の開発では、一般的にセキュリティよりもユーティリティと安定性が優先されてい