MySQL 系统学习 第六阶段:Redis + 缓存 + 高并发设计 第七章:Redis 分布式锁

📅 2026/7/15 11:53:45
MySQL 系统学习 第六阶段:Redis + 缓存 + 高并发设计 第七章:Redis 分布式锁
一、什么是分布式锁锁控制多个请求同时访问共享资源。例如库存商品库存 1两个用户同时购买用户A 用户B如果没有锁A 查询库存1 B 查询库存1 A 扣库存 B 扣库存结果库存可能变成-1这就是超卖。二、为什么普通锁不能解决单机synchronized只能锁住一个 JVM例如服务器A 服务器B 服务器C三个服务每个都有自己的锁。它们互相不知道。分布式系统用户请求 ↓ ┌───────┬───────┐ │ │ │ 服务A 服务B 服务C 锁 锁 锁三个锁无法互斥。所以需要所有服务器共享的一把锁。三、Redis 为什么可以实现分布式锁因为 Redis所有服务都能访问操作速度快支持原子操作结构服务A | 服务B | 服务C | Redis lock:product:100大家竞争 Redis 中同一个 Key。四、Redis 实现分布式锁核心命令SET NX EX例如SET lock:product:100 user1 NX EX 10含义NX不存在才创建。如果 Key 已存在失败。EX设置过期时间。例如10秒后自动释放锁流程第一个请求SET lock:product:100 user1 NX EX 10 成功获得锁。第二个请求SET lock:product:100 user2 NX EX 10 失败等待。五、为什么必须设置过期时间防止死锁。例如服务拿到锁lock然后服务器宕机。如果没有过期时间锁永远存在其他请求永远无法执行。所以EX 10自动释放。六、为什么不能直接 DEL 删除锁错误DEL lock:product问题可能删除别人的锁。例如服务A获得锁 执行时间超过10秒锁自动过期。服务B重新获得锁此时服务A执行DEL lock:product会删除服务B的锁。七、正确删除锁方式加唯一标识创建锁lock:product:100 value: uuid-123删除时先判断是不是自己的锁然后删除。流程获取锁 ↓ 执行任务 ↓ 判断 value ↓ 删除锁八、Lua 脚本保证原子性判断if value uuid 删除必须一次完成。否则判断和删除之间可能被其他请求插入。Redis 使用 Lua保证判断 删除 一次执行九、分布式锁应用场景1. 秒杀例如库存110000 人抢。锁lock:stock:100保证只有一个请求修改库存。2. 防止重复任务例如定时任务每天凌晨生成报表多个服务同时执行。使用锁保证只执行一次。3. 订单创建防止重复生成订单。4. 数据同步多个服务同时修改数据。十、RedLock了解Redis 官方提出的一种分布式锁算法。思想部署多个 Redis 节点。例如Redis1 Redis2 Redis3 Redis4 Redis5获取超过半数锁才认为成功。目的提高 Redis 故障情况下的可靠性。十一、企业常用方案简单场景SET NX EX Lua删除复杂高可靠场景Redisson RedLock十二、本章总结知识点作用分布式锁解决多服务并发问题SET NX保证只有一个请求获取锁EX防止死锁UUID区分锁的拥有者Lua保证删除锁原子性RedLock提高分布式锁可靠性本章一句话总结Redis 分布式锁通过 SET NX EX 保证同一时间只有一个服务执行关键操作解决高并发下的数据一致性问题。思考题精简回答什么是分布式锁为什么单机锁不能解决分布式问题分布式锁是多个服务节点之间共享的一把锁用于保证同一时间只有一个服务操作共享资源。单机锁只能锁住一个 JVM多个服务器之间无法互相感知。为什么秒杀库存扣减需要分布式锁因为大量用户同时购买同一个商品时会出现并发修改库存问题。分布式锁可以保证库存扣减操作串行执行避免超卖。Redis 分布式锁为什么使用SET NX EXNX保证只有一个请求能创建锁。EX设置过期时间防止死锁。两者结合实现简单可靠的加锁。为什么 Redis 锁必须设置过期时间防止服务异常宕机后锁一直存在导致其他请求永远无法获取锁。为什么删除 Redis 锁不能直接 DEL因为可能删除其他服务创建的锁。正确方式是先判断锁的 value 是否属于自己再删除。Lua 脚本在 Redis 分布式锁中解决什么问题保证“判断锁属于自己”和“删除锁”两个操作原子执行避免并发问题。RedLock 主要解决什么问题解决单个 Redis 节点故障导致分布式锁失效的问题提高锁的可靠性。