modify: 排他锁

This commit is contained in:
2026-08-27 09:42:21 +08:00
parent 9f7f71be7c
commit 0bdee195c1
7 changed files with 159 additions and 2 deletions
+33
View File
@@ -52,8 +52,41 @@ cache.close() # 释放连接
with Cache.from_config(cfg) as cache: ... # 上下文管理器,退出自动 close
cache.client # 底层客户端逃生口(diskcache.Cache / redis.Redis)
# 原子写(分布式锁原语):仅当 key 不存在时写入,成功返回 True,已存在返回 False,不覆盖
ok = cache.backend.set_nx("leader", {"node": "gw-1"}, expire=30)
```
### 分布式排他锁 `DistributedLock`
基于 `backend.set_nx`(SET NX + TTL 租约)实现的**跨进程/跨主机排他锁**,用于集群协调(如保证全局只有一个 MQTT Bridge 消费):
```python
import asyncio
from chongming_cache import Cache, DistributedLock
async def main():
cache = Cache.from_config(config["cache"])
lock = DistributedLock(cache, "mqtt_bridge", ttl=30, renew_interval=10)
if not lock.acquire(): # 全局唯一持锁方返回 True,其余返回 False
print("其他实例已持有,跳过")
return
lock.start() # 后台自动续约(防宕机/长暂停导致锁过期被抢)
try:
... # 执行受保护的单例任务
finally:
await lock.stop() # 停止续约
lock.release() # 受保护释放
cache.close()
asyncio.run(main())
```
- `acquire()`:SET NX,原子地仅在不存在时写入;key 带 TTL 租约,持有方宕机后到期自动让出,不会死锁。
- `start()` / `stop()`:后台续约任务;续约前校验 token,仅在自己仍持有时 `touch`,锁丢失即停止续约。
- `release()`:受保护释放——仅当 token 仍匹配(仍是自己持有)才删除,绝不误删其他进程/主机抢到的锁。
- **后端适用性**:`redis` 真正跨主机共享;`diskcache` 进程安全(SQLite),可用于单机多进程或共享卷场景,不可跨无共享文件系统的主机。
---
## 后端配置(config.toml `[cache]` 段)