distributed-locks
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseDistributed Locks
分布式锁
Coordinate exclusive access to resources across multiple service instances.
实现跨多个服务实例的资源独占访问协调。
Overview
概述
- Preventing duplicate processing of jobs/events
- Coordinating singleton processes (cron, leaders)
- Protecting critical sections across instances
- Implementing leader election
- Rate limiting at distributed level
- 防止作业/事件重复处理
- 协调单例进程(定时任务、领导者)
- 跨实例保护临界区
- 实现领导者选举
- 分布式级别限流
Lock Types Comparison
锁类型对比
| Lock Type | Durability | Latency | Use Case |
|---|---|---|---|
| Redis (single) | Low | ~1ms | Fast, non-critical |
| Redlock (multi) | High | ~5ms | Critical, HA required |
| PostgreSQL advisory | High | ~2ms | Already using PG, ACID |
| 锁类型 | 持久性 | 延迟 | 适用场景 |
|---|---|---|---|
| Redis(单节点) | 低 | ~1ms | 快速、非关键场景 |
| Redlock(多节点) | 高 | ~5ms | 关键场景、需高可用 |
| PostgreSQL advisory锁 | 高 | ~2ms | 已使用PG、需ACID特性 |
Quick Reference
快速参考
Redis Lock (Single Node)
Redis锁(单节点)
python
from uuid_utils import uuid7
import redis.asyncio as redis
class RedisLock:
"""Redis lock with Lua scripts for atomicity."""
ACQUIRE = "if redis.call('set',KEYS[1],ARGV[1],'NX','PX',ARGV[2]) then return 1 end return 0"
RELEASE = "if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) end return 0"
def __init__(self, client: redis.Redis, name: str, ttl_ms: int = 30000):
self._client = client
self._name = f"lock:{name}"
self._owner = str(uuid7())
self._ttl = ttl_ms
async def acquire(self) -> bool:
return await self._client.eval(self.ACQUIRE, 1, self._name, self._owner, self._ttl) == 1
async def release(self) -> bool:
return await self._client.eval(self.RELEASE, 1, self._name, self._owner) == 1
async def __aenter__(self):
if not await self.acquire():
raise LockError(f"Failed to acquire {self._name}")
return self
async def __aexit__(self, *_):
await self.release()See redis-locks.md for complete implementation with retry/extend.
python
from uuid_utils import uuid7
import redis.asyncio as redis
class RedisLock:
"""Redis lock with Lua scripts for atomicity."""
ACQUIRE = "if redis.call('set',KEYS[1],ARGV[1],'NX','PX',ARGV[2]) then return 1 end return 0"
RELEASE = "if redis.call('get',KEYS[1])==ARGV[1] then return redis.call('del',KEYS[1]) end return 0"
def __init__(self, client: redis.Redis, name: str, ttl_ms: int = 30000):
self._client = client
self._name = f"lock:{name}"
self._owner = str(uuid7())
self._ttl = ttl_ms
async def acquire(self) -> bool:
return await self._client.eval(self.ACQUIRE, 1, self._name, self._owner, self._ttl) == 1
async def release(self) -> bool:
return await self._client.eval(self.RELEASE, 1, self._name, self._owner) == 1
async def __aenter__(self):
if not await self.acquire():
raise LockError(f"Failed to acquire {self._name}")
return self
async def __aexit__(self, *_):
await self.release()查看redis-locks.md获取包含重试/续期的完整实现。
PostgreSQL Advisory Lock
PostgreSQL Advisory锁
python
from sqlalchemy import text
async def with_advisory_lock(session, lock_id: int):
"""PostgreSQL advisory lock (session-level)."""
await session.execute(text("SELECT pg_advisory_lock(:id)"), {"id": lock_id})
try:
yield
finally:
await session.execute(text("SELECT pg_advisory_unlock(:id)"), {"id": lock_id})See postgres-advisory-locks.md for transaction-level and monitoring.
python
from sqlalchemy import text
async def with_advisory_lock(session, lock_id: int):
"""PostgreSQL advisory lock (session-level)."""
await session.execute(text("SELECT pg_advisory_lock(:id)"), {"id": lock_id})
try:
yield
finally:
await session.execute(text("SELECT pg_advisory_unlock(:id)"), {"id": lock_id})查看postgres-advisory-locks.md获取事务级锁和监控相关内容。
Key Decisions
关键决策
| Decision | Recommendation |
|---|---|
| Backend | Redis for speed, PG if already using it |
| TTL | 2-3x expected operation time |
| Retry | Exponential backoff with jitter |
| Fencing | Include owner ID for safety |
| 决策项 | 建议方案 |
|---|---|
| 后端存储 | 追求速度选Redis,已使用PG则选PG |
| TTL设置 | 为预期操作时间的2-3倍 |
| 重试策略 | 带抖动的指数退避 |
| 防护机制 | 包含所有者ID以保证安全 |
Anti-Patterns (FORBIDDEN)
反模式(禁止)
python
undefinedpython
undefinedNEVER forget TTL (causes deadlocks)
NEVER forget TTL (causes deadlocks)
await redis.set(f"lock:{name}", "1") # WRONG - no expiry!
await redis.set(f"lock:{name}", "1") # WRONG - no expiry!
NEVER release without owner check
NEVER release without owner check
await redis.delete(f"lock:{name}") # WRONG - might release others' lock
await redis.delete(f"lock:{name}") # WRONG - might release others' lock
NEVER use single Redis for critical operations
NEVER use single Redis for critical operations
lock = RedisLock(single_redis, "payment") # Use Redlock for HA
lock = RedisLock(single_redis, "payment") # Use Redlock for HA
NEVER hold locks across await points without heartbeat
NEVER hold locks across await points without heartbeat
async with lock:
await slow_external_api() # Lock may expire!
undefinedasync with lock:
await slow_external_api() # Lock may expire!
undefinedRelated Skills
相关技能
- - Complement locks with idempotency
idempotency-patterns - - Redis patterns
caching-strategies - - Job deduplication
background-jobs
- - 用幂等性补充锁的能力
idempotency-patterns - - Redis相关模式
caching-strategies - - 作业去重
background-jobs
References
参考资料
- Redis Locks - Lua scripts, retry, extend
- Redlock Algorithm - Multi-node HA
- PostgreSQL Advisory - Session/transaction
- Redis Locks - Lua脚本、重试、续期
- Redlock Algorithm - 多节点高可用
- PostgreSQL Advisory - 会话/事务级锁
Capability Details
能力详情
redis-locks
redis-locks
Keywords: Redis, Lua, SET NX, atomic, TTL
Solves: Fast distributed locks, atomic acquire/release, auto-expiry
关键词: Redis、Lua、SET NX、原子性、TTL
解决问题: 快速分布式锁、原子性获取/释放、自动过期
redlock
redlock
Keywords: Redlock, multi-node, quorum, HA, fault-tolerant
Solves: High-availability locking, survive node failures
关键词: Redlock、多节点、法定人数、高可用、容错
解决问题: 高可用锁、节点故障时仍可正常工作
advisory-locks
advisory-locks
Keywords: PostgreSQL, advisory, pg_advisory_lock, session, transaction
Solves: Lock with existing PG, ACID integration, no extra infra
关键词: PostgreSQL、advisory、pg_advisory_lock、会话、事务
解决问题: 基于现有PG实现锁、ACID集成、无需额外基础设施
leader-election
leader-election
Keywords: leader, election, singleton, coordinator
Solves: Single active instance, coordinator pattern
关键词: leader、选举、单例、协调器
解决问题: 单活跃实例、协调器模式