Redis并发竞争Key问题
ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花
一、问题本质:为什么会出现Key并发竞争?
Redis是单线程串行执行命令的,本身不存在线程安全问题,但客户端并发请求会导致命令执行时序错乱,进而引发Key竞争:
- 核心场景:多个客户端同时对同一个Key执行读-改-写流程(如查询库存、扣减库存、回写库存),Redis单命令原子,但多命令组合非原子,会出现脏写、数据覆盖、超卖/超扣等问题
- 典型表现:库存超卖、计数器数值不准、分布式ID重复、缓存数据不一致
- 本质矛盾:客户端并发操作 vs Redis多命令非原子性
解决方案优先级:原子操作(无锁)> 乐观锁 > 分布式锁 > 业务拆分,优先用无锁方案降低性能损耗
二、核心解决方案(按优先级排序)
方案1:Redis原生原子操作(首选,零开销)
利用Redis单命令的原子性,把读-改-写合并为一个原子命令,彻底规避竞争,适用于简单数值操作、赋值场景。
1.1 原生原子命令
- 数值操作:INCR/INCRBY/DECR/DECRBY(计数器、库存扣减)、SETNX(互斥赋值)
- 哈希操作:HINCRBY/HSETNX(哈希结构字段原子更新)
- 适用场景:纯数值增减、简单键值赋值,无复杂业务逻辑判断
1.2 Lua脚本(复杂原子逻辑)
Redis保证Lua脚本整体原子执行,可嵌入多命令+业务判断,解决原生单命令无法覆盖的场景。
- 核心优势:减少网络开销、原子执行、无锁竞争
- 落地规则:脚本尽量轻量、避免耗时操作、不使用随机命令、统一key前缀
- 典型场景:库存扣减(判断库存是否充足+扣减)、分布式锁释放、限流判断
方案2:乐观锁(WATCH+版本号,读多写少首选)
基于版本号机制,通过Redis WATCH命令监听Key变化,若执行期间Key被修改则放弃当前操作,重试即可,无锁阻塞。
实现流程
- 查询Key对应数据+版本号
- WATCH监听目标Key,开启事务
- 执行业务修改,更新版本号
- EXEC提交事务:若Key被修改则返回nil,客户端重试;否则执行成功
优缺点与适用场景
- 优点:无锁阻塞、性能高、实现简单
- 缺点:写冲突频繁时重试次数多,性能下降
- 适用场景:读多写少、并发冲突概率低的场景(如商品详情更新、个人信息修改)
方案3:分布式锁(写密集场景兜底)
通过互斥锁保证同一时间只有一个客户端操作目标Key,解决高并发写冲突,是复杂业务场景的兜底方案。
3.1 基础实现:SETNX+过期时间
避免死锁:必须给锁设置过期时间,推荐用 SET lock_key unique_value NX EX 超时时间 原子命令,禁止先SETNX再EXPIRE(非原子易死锁)。
3.2 企业级实现:Redisson分布式锁
- 核心特性:可重入锁、锁续期(看门狗机制)、公平锁、红锁(解决单机Redis宕机丢锁)
- 避坑要点:锁粒度尽量小(只锁竞争Key,不锁全局)、避免锁超时、解锁用Lua脚本保证原子性
适用场景
高并发写、复杂业务逻辑、冲突概率高的场景(如秒杀库存、订单创建、分布式任务执行)
方案4:业务层拆分(根源优化,彻底降竞争)
从业务设计层面拆分热点Key,减少单Key的并发访问量,是根治热点Key竞争的终极方案。
- Key分片:把单个热点Key拆分为多个子Key(如stock_1、stock_2...stock_n),请求随机路由到子Key,汇总时求和
- 冷热分离:热点数据缓存到本地JVM缓存+Redis二级缓存,降低Redis访问频次
- 读写分离:读请求走从节点,写请求走主节点,分散压力
三、方案选型对比表
原子命令/Lua | 极高 | 低 | 简单读写、数值操作 | 不支持复杂业务逻辑 |
乐观锁(WATCH) | 高 | 中 | 读多写少、低冲突 | 高冲突时重试泛滥 |
分布式锁 | 中 | 中高 | 高并发写、强一致性 | 锁粒度、死锁、性能损耗 |
业务拆分 | 极高 | 高 | 极致热点Key根治 | 业务改造量大 |
四、实战避坑核心要点
- 拒绝长事务/长锁:Redis操作和业务逻辑尽量轻量化,避免锁占用时间过长
- 锁必须加超时:杜绝客户端宕机导致的死锁问题
- 重试机制优化:乐观锁/锁冲突时采用指数退避重试,避免雪崩
- 热点Key识别:通过Redis监控定位高频访问Key,提前做分片或缓存优化
- 慎用红锁:只有Redis集群极端可靠性场景才用,普通主从架构无需冗余复杂度
ps:如果这篇帖子对于还在找工作和找实习的你有所帮助,可以关注我,给本贴点赞、评论、收藏并订阅专栏;同时不要吝啬您的花花
本专栏聚焦 Redis 分布式锁从原理到生产落地全流程,拆解SET 原子加锁、Lua 解锁、锁续期、Redlock等核心技术,直击锁超时、误释放、主从一致性等高频痛点。结合 Redisson 实战与微服务场景案例,输出可直接复用的代码方案与避坑指南,助力后端工程师攻克分布式并发难题,构建高可靠锁服务。
查看12道真题和解析