Basic distributed lock:
# SET key value NX EX timeout (atomic: set only if not exists)
SET lock:resource unique_id NX EX 30-- Release: Lua script để atomic check-and-delete
if redis.call('GET', KEYS[1]) == ARGV[1] then
return redis.call('DEL', KEYS[1])
endVấn đề với single Redis instance: nếu Redis crash sau khi client A acquire lock nhưng trước khi expire, lock mất vĩnh viễn; nếu Redis failover sang replica, replica có thể chưa nhận lock → client B cũng acquire được lock → 2 clients cùng hold lock. Redlock (Martin Kleppmann cảnh báo vẫn không hoàn hảo): acquire lock trên N (>=5) independent Redis instance — phải là các host độc lập thực sự, không dùng chung persistence; lock chỉ valid khi acquire thành công trên majority (N/2+1) trong thời gian < lock validity.
- Kleppmann argue rằng nếu process bị pause dài hơn TTL (GC, network), client vẫn tin rằng đang hold lock trong khi lock đã expire và được acquire bởi client khác.
- Đây là thuật toán phức tạp, nhiều tranh cãi.
- Thực tế production: dùng Redlock cho non-critical locks (rate limiting, idempotency key); dùng ZooKeeper hoặc etcd cho critical distributed coordination.
- Library:
ioredis+redlocknpm package; JavaRedisson.
Basic distributed lock:
# SET key value NX EX timeout (atomic: set only if not exists)
SET lock:resource unique_id NX EX 30-- Release: Lua script for atomic check-and-delete
if redis.call('GET', KEYS[1]) == ARGV[1] then
return redis.call('DEL', KEYS[1])
endProblem with a single Redis instance: if Redis crashes after client A acquires the lock but before it expires, the lock is permanently gone; if Redis fails over to a replica that hasn't received the lock yet, client B can also acquire it → two clients hold the lock simultaneously. Redlock (Martin Kleppmann warns it is still imperfect): acquire the lock on N (>=5) truly independent Redis instances (different physical hosts, no shared persistence); the lock is only valid if acquired on a majority (N/2+1) within less than the lock validity time.
- Kleppmann argues that if a process is paused longer than the TTL (GC pause, network delay), the client still believes it holds the lock while the lock has already expired and been acquired by another client.
- This is a complex algorithm with ongoing debate.
- For production: use Redlock for non-critical locks (rate limiting, idempotency keys); use ZooKeeper or etcd for critical distributed coordination.
- Libraries:
ioredis+redlocknpm package; JavaRedisson.