Redisを使って分散ロックを実現

2638 ワード

原文のリンク:http://www.dubby.cn/detail.html?id=9067
錠をかける
オンラインのほとんどの提案はSETNXを使用しています.これ自体は問題がないです.低バージョンのRedisでは、このコマンドだけが互いに反発できるSet Keyです.しかし、Redisのバージョンが高くなるにつれて、より多くのコマンドが私たちのニーズを満足させるために提供されます.
SET
SET key value [EX seconds] [PX milliseconds] [NX|XX]
これはあなたが知っているのとは違って、SET key valueは私達は全部知っています.その後ろの選択肢は何ですか?実はSETこのコマンドはRedis 1.0.0の時に提供されましたが、その時はSET key valueだけが提供されました.後のオプションはRedis 2.6.12の時に加えられます.
  • EX seconds:有効期限を設定します.単位は秒
  • です.
  • PX miliseconds:有効期限を設定し、単位はミリ秒
  • です.
  • NX:Key*が***が存在しない時だけ設定が成功します.
  • XX:Key*がすでに**が存在している時だけ設定が成功します.
    なぜ従来の使用よりもSETNXのほうがいいですか?SETNXは有効期限を設定できないからです.
    //1.  
    SETNX key value
    
    //2.    ,      
    EXPIRE key seconds
    
    //3.    ...
    
    //4.   
    もしプログラムが2ステップの前に1ステップの後に引っかかったら、デッドロックになります.根本的な原因と、ロックを設定して、期限を過ぎた時間を設定することは原子操作ではありません.もちろん、物事を使って保証してもいいです.ただ、こんなに簡単ではないです.
    ロックを解除する
    DEL
    DEL key [key ...]
    DELを直接使用して削除すればいいです.
    もっとたくましい錠
    上で検討したロックは、実はKeyだけに注目しています.Valueは関心がありません.このような問題は、このロックがどのクライアントに属しているかを確認できないということです.つまり、誤って削除する可能性があります.
    例を挙げると、クライアントはロック1を作成し、ロジックを処理した後、このクライアントはロック1を解放するつもりですが、この操作はロックの有効期限後、つまりこのロック1が自動的に無効になりました.この時、もう一つのクライアントが新しいロック2を作成しました.クライアントが削除したのはlcok 2です.これは誤ってロックを解除しました.
  • は、UUIDなどのValueをTokenという意味の値に設定する.
  • は、簡単にDELを使用してロックを解除することができず、スクリプト
  • を借りる必要がある.
    if redis.call("get",KEYS[1]) == ARGV[1]
    then
        return redis.call("del",KEYS[1])
    else
        return 0
    end
    呼び出し方法は、概ねEVAL ...script... resource-name token-valueである.
    レディソン
    より成熟した分散式ロックと同期器