Implementing Distributed Locks
1. Setting Lock with SETNX
| Command | Returns |
SETNX lock:res token | 1 acquired, 0 held LEGACY |
2. Using SET with NX and EX Options
| Command | Description |
SET lock:res token NX PX 30000 | Atomic acquire + auto-expiry (preferred) |
3. Implementing Lock Expiration
| Property | Recommendation |
| TTL | Slightly > max work duration |
| Renewal | Background watchdog extends TTL |
4. Releasing Locks Safely (Lua Script)
Example: Token-checked release
EVAL "if redis.call('GET', KEYS[1]) == ARGV[1] then \
return redis.call('DEL', KEYS[1]) else return 0 end" \
1 lock:res <token>
Warning: Never DEL directly — you may delete a lock held by someone else after your TTL expired.
5. Handling Lock Timeouts
| Scenario | Mitigation |
| Work exceeded TTL | Renew with Lua CAS; if renewal fails, abort and rollback |
6. Implementing Redlock Algorithm
| Step | Detail |
| 1 | Get current time (ms) |
| 2 | Try SET NX PX on N independent masters (small timeout) |
| 3 | Lock valid if acquired on majority AND elapsed < TTL |
| 4 | Effective TTL = original − elapsed |
| 5 | On failure release on ALL nodes |
7. Preventing Deadlocks
| Technique | Detail |
| Always set TTL | Auto-release on crash |
| Unique token | UUID per acquisition |
| Lock ordering | Acquire multi-locks in fixed order |
8. Using WATCH for Optimistic Locking
| Pattern | Use |
| WATCH + MULTI/EXEC | No explicit lock; retry on contention |
| Best for | Low contention |
9. Handling Lock Renewal
Example: Renewal Lua
EVAL "if redis.call('GET', KEYS[1]) == ARGV[1] then \
return redis.call('PEXPIRE', KEYS[1], ARGV[2]) else return 0 end" \
1 lock:res <token> 30000
10. Understanding Lock Granularity
| Granularity | Tradeoff |
| Coarse (one global lock) | Simple, low concurrency |
| Fine (per-resource) | High concurrency, more keys |