【Redis实战】分布式锁的N种实现方案对比与避坑指南
【Redis实战】分布式锁的N种实现方案对比与避坑指南在高并发场景下分布式锁是保证数据一致性的关键技术。本文将从原理到实战详细讲解分布式锁的各种实现方案。一、为什么需要分布式锁假设这样一个场景双十一秒杀活动库存只剩1件但有两个用户同时下单。如果没有锁机制可能两个用户都抢到了这件商品导致超卖问题。单机环境下我们可以用 synchronized 或 ReentrantLock 来解决。但如果是分布式部署多个服务实例同时抢锁JVM锁就失效了——因为每个实例都有自己的锁对象彼此之间完全感知不到。分布式锁的核心目标互斥性同一时刻只能有一个客户端持有锁防死锁即使客户端崩溃锁也要能自动释放可重入同一个客户端可以多次获取锁高性能加锁/解锁操作要快二、方案一SET NX EX最简单粗暴这是很多人第一次用Redis实现分布式锁的方式public Boolean tryLock(String key, String value, long expireTime) {return redisTemplate.opsForValue().setIfAbsent(key, value, expireTime, TimeUnit.SECONDS);}优点简单一行代码搞定缺点可靠性差value 无法唯一标识锁的持有者三、方案二SET NX PX 唯一value推荐入门改进版每个锁带唯一标识解锁时校验// 加锁String uuid UUID.randomUUID().toString();Boolean success redisTemplate.opsForValue().setIfAbsent(key, uuid, 30, TimeUnit.SECONDS);// 解锁Lua脚本保证原子性String script “if redis.call(‘get’, KEYS[1]) ARGV[1] then return redis.call(‘del’, KEYS[1]) else return 0 end”;redisTemplate.execute(new DefaultRedisScript(script, Long.class),Collections.singletonList(key), uuid);四、方案三Redisson生产级方案Redisson是Redis的Java客户端封装了完善的分布式锁实现Autowiredprivate RedissonClient redissonClient;public void businessMethod() {RLock lock redissonClient.getLock(“myLock”);try {// 等待30秒锁定后自动续期if (lock.tryLock(30, -1, TimeUnit.SECONDS)) {// 业务逻辑}} finally {if (lock.isHeldByCurrentThread()) {lock.unlock();}}}核心特性自动续期看门狗机制防止锁提前释放可重入同一线程可多次获取锁公平锁/读写锁丰富的锁类型支持五、避坑指南坑1锁过期了但业务还没执行完问题设置了30秒过期但业务需要45秒解决方案Redisson的看门狗机制会每10秒自动续期30秒坑2主从切换导致锁丢失问题Redis主节点加锁成功但数据还没同步到从节点主节点挂了解决方案使用RedLock算法多节点加锁或使用Redisson Pro支持Redis Cluster坑3解锁时误删了他人的锁问题没有校验value直接del了解决方案解锁时用Lua脚本先判断value再删除六、总结方案可靠性复杂度适用场景SET NX⭐⭐测试/低并发SET NX value⭐⭐⭐⭐一般生产环境Redisson⭐⭐⭐⭐⭐⭐⭐高并发生产环境我的建议直接上Redisson省心省力。当然理解底层原理也很重要面试时能手写分布式锁会让你加分不少。相关阅读Redis缓存实战从入门到精通Spring Boot集成Redisson详细教程觉得有用的话点个赞再走呗 有问题欢迎评论区交流