如何用redis实现分布式锁

WBOY
リリース: 2016-06-07 16:10:04
オリジナル
1181 人が閲覧しました

引子 redis作为一个强大的key/value数据库,其实还可以用来实现轻量级的分布式锁。 1.实现方案1 最早官方在SETNX命令页给了一个实现: acquire lock: SETNX lock.foo current Unix time + lock timeout + 1 release lock: DEL lock.foo acquire lock when ti

引子

redis作为一个强大的key/value数据库,其实还可以用来实现轻量级的分布式锁。

1.实现方案1

最早官方在SETNX命令页给了一个实现:

acquire lock: SETNX lock.foo <current Unix time + lock timeout + 1>
ログイン後にコピー
release lock: DEL lock.foo
ログイン後にコピー
acquire lock when time expired: GETSET lock.foo <current Unix timestamp + lock timeout + 1>
ログイン後にコピー

不过这个方案有漏洞,就是release lock用的DEL命令不支持cas删除(delete if current value equals old value),这样忽略race condition将会出现问题:

A client will try to release the lock after the expire time deleting the key created by another client that acquired the lock later.

2.实现方案2

官方在SETNX命令页介绍了新的方案:SET command + Lua script:

Starting with Redis 2.6.12 it is possible to create a much simpler locking primitive using the SET command to acquire the lock, and a simple Lua script to release the lock. The pattern is documented in the SET command page.

The old SETNX based pattern is documented below for historical reasons.

该方案有2个优化:

(1)SET 命令可以设置key过期时间:SET key value [EX seconds] [PX milliseconds] [NX|XX]

The lock will be auto-released after the expire time is reached.

(2)使用Lua脚本实现cas删除(详见SET命令页)

It is possible to make this system more robust modifying the unlock schema as follows:

  • Instead of setting a fixed string, set a non-guessable large random string, called token.
  • Instead of releasing the lock with DEL, send a script that only removes the key if the value matches.
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!