分布式锁详解:Redis与Zookeeper实现
分布式锁详解:Redis与Zookeeper实现
概述
分布式锁是分布式系统中的重要组件。本教程介绍Redis和Zookeeper的分布式锁实现。
1. Redis分布式锁
import org.springframework.data.redis.core.StringRedisTemplate;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
public class RedisDistributedLock {
private final StringRedisTemplate redisTemplate;
private final String lockKey;
private final long lockTimeout;
private final String requestId;
public RedisDistributedLock(StringRedisTemplate redisTemplate, String lockKey, long lockTimeout) {
this.redisTemplate = redisTemplate;
this.lockKey = lockKey;
this.lockTimeout = lockTimeout;
this.requestId = UUID.randomUUID().toString();
}
public boolean tryLock() {
return Boolean.TRUE.equals(
redisTemplate.opsForValue().setIfAbsent(lockKey, requestId, lockTimeout, TimeUnit.MILLISECONDS)
);
}
public boolean tryLock(long waitTime) throws InterruptedException {
long end = System.currentTimeMillis() + waitTime;
while (System.currentTimeMillis() < end) {
if (tryLock()) {
return true;
}
Thread.sleep(100);
}
return false;
}
public boolean unlock() {
String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
return redisTemplate.execute(
new DefaultRedisScript<>(script, Long.class),
Collections.singletonList(lockKey),
requestId
) == 1L;
}
}
2. Zookeeper分布式锁
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.recipes.locks.InterProcessMutex;
import java.util.concurrent.TimeUnit;
public class ZookeeperDistributedLock {
private final CuratorFramework client;
private final String lockPath;
private InterProcessMutex lock;
public ZookeeperDistributedLock(CuratorFramework client, String lockPath) {
this.client = client;
this.lockPath = lockPath;
}
public boolean tryLock(long timeout, TimeUnit unit) throws Exception {
lock = new InterProcessMutex(client, lockPath);
return lock.acquire(timeout, unit);
}
public void unlock() throws Exception {
if (lock != null && lock.isAcquiredInThisProcess()) {
lock.release();
}
}
}
3. 实际应用示例
分布式任务调度
@Service
public class DistributedTaskScheduler {
private final RedisDistributedLock lock;
@Scheduled(fixedRate = 60000)
public void executeTask() {
if (lock.tryLock()) {
try {
// 执行定时任务
processTask();
} finally {
lock.unlock();
}
}
}
}
库存扣减
@Service
public class InventoryService {
private final RedisDistributedLock lock;
public boolean deductStock(String productId, int quantity) {
String lockKey = "stock:" + productId;
RedisDistributedLock productLock = new RedisDistributedLock(redisTemplate, lockKey, 5000);
if (productLock.tryLock()) {
try {
// 查询库存
int currentStock = getStock(productId);
if (currentStock >= quantity) {
// 扣减库存
updateStock(productId, currentStock - quantity);
return true;
}
return false;
} finally {
productLock.unlock();
}
}
return false;
}
}
4. 最佳实践
- 选择合适的方案:Redis简单,Zookeeper更可靠
- 设置超时时间:避免死锁
- 实现可重入锁:支持同一线程多次获取
- 监控锁状态:实时监控锁的使用情况
- 处理异常情况:确保锁的正确释放
总结
分布式锁是分布式系统中的重要组件。掌握Redis和Zookeeper的分布式锁实现,可以解决分布式系统中的并发问题。