redisサブスクリプションパブリケーションメカニズムによる分散ロックの実現
2767 ワード
推奨:jeesuite開発フレームワーク、無料オープンソース、ワンストップソリューション.
通常、分散シーンロックメカニズムを解決するにはredisが最初に考えられます.redis単一スレッドが天然にこの問題を解決したからだ.redisを使用して分散ロックを実装するには、getsetおよびsetnxを使用します. getset:与えられたkeyの値をvalueに設定し、keyの古い値(old value) を返す. SETNX:keyの値をvalueとし、keyが存在しない場合のみ.与えられたkeyが既に存在する場合、SETNXは何もしない.
しかし、この方式は、ロックが待機している場合、ロック解放通知を自発的に取得することができず、ポーリングしてredisを絶えず調べなければならない.これにより、クエリー・リクエストが大量に発生し、待機時間が増加します(たとえば、10 msでポーリングしますが、次のミリ秒でロックが取得できるかもしれませんが、10 msを待つ必要があります).次に、redis SUBPUBメカニズムに基づいて実現した分散ロックの考え方を共有します.は、redis Listキューおよびsubpubメカニズムを使用する. 各待機ロックは、グローバル一意のeventIdを生成し、redisキューは、取得ロックを待機するeventIdのセットを配置する. ロックを取得するプロセス1:キューに入れた後の長さがちょうど:1であれば、ロックが取得されます. ロックを取得するプロセス2:キューに入れた後の長さ>1で、前のロックの解放を待つ. ロック解除:まずeventIdキューRPOPから次のロック取得の通知対象とする. ロック待機:スレッドブロックはredisパブリッシュメッセージを待機し、nextEventIdが現在と一致する場合、ロックを取得する. その他の考慮事項:ロックタイムアウト、デッドロックなどの問題.
添付:1.eventId構造:固定ビット数ノードID+13ビットタイムスタンプ+一意シーケンスロックを解除し、メッセージの内容を公開します:lockName+セパレータ+nextEventId 完全コード:完全コードを取得
通常、分散シーンロックメカニズムを解決するにはredisが最初に考えられます.redis単一スレッドが天然にこの問題を解決したからだ.redisを使用して分散ロックを実装するには、getsetおよびsetnxを使用します.
redis> GETSET db mongodb # , nil
(nil)
redis> GET db
"mongodb"
redis> GETSET db redis # mongodb
"mongodb"
redis> GET db
"redis"
redis> EXISTS job # job
(integer) 0
redis> SETNX job "programmer" # job
(integer) 1
redis> SETNX job "code-farmer" # job ,
(integer) 0
redis> GET job #
"programmer"
しかし、この方式は、ロックが待機している場合、ロック解放通知を自発的に取得することができず、ポーリングしてredisを絶えず調べなければならない.これにより、クエリー・リクエストが大量に発生し、待機時間が増加します(たとえば、10 msでポーリングしますが、次のミリ秒でロックが取得できるかもしれませんが、10 msを待つ必要があります).次に、redis SUBPUBメカニズムに基づいて実現した分散ロックの考え方を共有します.
添付:1.eventId構造:固定ビット数ノードID+13ビットタイムスタンプ+一意シーケンス
public String buildEvenId(){
return new StringBuilder().append(EVENT_ID_PREFIX).append(System.currentTimeMillis()).append(eventIdSeq.incrementAndGet()).toString();
}