简单例子代码:纠结哥/java-learn - Gitee.com
分布式锁(Distributed Lock)是一种用于分布式系统中的同步机制,确保多个进程或线程在不同的节点上对共享资源的访问是互斥的。常见的分布式锁实现方式包括基于数据库、Redis、Zookeeper等
实现方式 | 性能 | 可靠性 | 适用场景 | 优缺点 |
---|---|---|---|---|
数据库 | 低 | 一般 | 低并发,适合小型系统 | 容易实现,但性能差 |
Redis | 高 | 一般 | 高频率并发,适合 Web 服务 | 需处理误删锁问题 |
Zookeeper | 低 | 高 | 任务调度,高可靠性要求的分布式环境 | 适用于分布式协调 |
在分布式环境下,多个实例可能同时操作同一资源,导致数据不一致。例如:
- 秒杀系统:多个用户同时下单,超卖问题
- 定时任务调度:多个实例同时执行同一任务,导致重复执行
- 库存扣减:多个实例并发操作库存,导致超卖
分布式锁可以解决这些问题,确保同一时刻只有一个实例能操作资源。
1.基于数据库
思路:
- 通过数据库的**唯一索引(PRIMARY KEY 或 UNIQUE)**来确保锁的唯一性
- 通过
INSERT
或SELECT ... FOR UPDATE
实现加锁
-- 创建锁表
CREATE TABLE distributed_lock (
lock_name VARCHAR(64) PRIMARY KEY,
locked_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- 获取锁(加锁)
INSERT INTO distributed_lock (lock_name) VALUES ('order_lock');
-- 释放锁(解锁)
DELETE FROM distributed_lock WHERE lock_name = 'order_lock';
优点
- 易于实现,不需要额外的组件
- 适用于小规模分布式系统
缺点
- 性能较低:数据库的 I/O 远高于内存
- 死锁风险:如果程序崩溃,锁可能无法释放
- 数据库压力大:高并发下数据库可能成为瓶颈
2.基于 Redis
思路:
- 利用
SET NX
(仅当键不存在时才设置)+ 过期时间,确保互斥性 - 通过
DEL
删除锁,实现解锁 - 可结合
Redisson
等库进行更高级的锁管理
import redis
import time
redis_client = redis.StrictRedis(host='localhost', port=6379, decode_responses=True)
lock_key = "my_lock"
lock_value = "unique_identifier" # 可使用 UUID,确保唯一性
expire_time = 10 # 10秒自动释放
# 获取锁
if redis_client.set(lock_key, lock_value, nx=True, ex=expire_time):
print("获取锁成功!")
try:
# 业务逻辑
time.sleep(5)
finally:
# 释放锁
if redis_client.get(lock_key) == lock_value:
redis_client.delete(lock_key)
print("释放锁成功!")
else:
print("获取锁失败!")
优点
- 性能高:Redis 运行在内存中,速度快
- 可设置超时时间,防止死锁
- 支持高并发
缺点
- 可能出现误删锁(如果锁被其他进程误覆盖)
- 需要 Redis 作为额外组件
优化方案:
- 使用 Redisson(支持可重入锁、公平锁等)
- 使用 Lua 脚本确保删除锁的原子性
- Redis Cluster 保证高可用性
3.基于 Zookeeper
思路:
- Zookeeper 通过**临时有序节点(Ephemeral + Sequential)**来实现分布式锁
- 进程创建一个临时顺序节点,最小的节点获得锁
- 进程执行完任务后删除节点,释放锁
InterProcessMutex lock = new InterProcessMutex(client, "/lock_path");
try {
if (lock.acquire(5, TimeUnit.SECONDS)) {
try {
// 业务逻辑
} finally {
lock.release();
}
}
} catch (Exception e) {
e.printStackTrace();
}
优点
- 可靠性高:Zookeeper 通过 Watch 机制监控锁状态
- 避免死锁:进程崩溃时,Zookeeper 自动释放锁
- 支持公平锁
缺点
- 性能较低:Zookeeper 适用于低并发场景
- 运维成本高:需要维护 Zookeeper 集群