← 返回首页
🔐

分布式锁详解:Redis与Zookeeper实现

📂 java ⏱ 2 min 314 words

分布式锁详解: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. 最佳实践

  1. 选择合适的方案:Redis简单,Zookeeper更可靠
  2. 设置超时时间:避免死锁
  3. 实现可重入锁:支持同一线程多次获取
  4. 监控锁状态:实时监控锁的使用情况
  5. 处理异常情况:确保锁的正确释放

总结

分布式锁是分布式系统中的重要组件。掌握Redis和Zookeeper的分布式锁实现,可以解决分布式系统中的并发问题。