TwKit

推文

@Zen_with_AI · 2026-10-14 05:32

小路带你60天学系统设计Day 17/60|分布式锁:多台机器怎么抢同一把锁 Day 16 讲了跨服务的数据一致性。今天换个角度:多台机器同时操作同一份资源(比如秒杀扣库存),怎么保证同一时刻只有一个在改? 先说为什么难。单机一把 synchronized/mutex 就够了,因为锁活在同一个进程的内存里。但分布式下每个进程各有各的内存,谁也不认谁的锁——得找一个大家都认的"裁判"。 三类裁判,按工程常用程度排: 数据库:建一张锁表,插入一条记录 = 加锁(唯一约束保证互斥),删记录 = 释放。实现最简单,但性能差,而且锁没有过期机制——持有者挂了,锁就永远卡在那儿。 Redis:SET key value NX PX——"不存在才设置 + 过期时间",一条原子命令搞定加锁;释放用 Lua 脚本先校验 value 是不是自己的再删,防止误删别人的锁。这是工程里最常见的方案(Redisson 就是这么封装的)。但有个著名坑:主从架构下,master 刚加上锁就挂了,锁还没同步到 slave,别人又能加锁——互斥被打破。RedLock(多个实例多数派)想修这个问题,但 Martin Kleppmann 写过长文质疑:有时钟漂移的地方 RedLock 也不安全,争议至今没停。 ZooKeeper / etcd:创建临时顺序节点,序号最小的拿到锁;会话断开节点自动删除,天然防死锁;watch 机制让没抢到的人排队等通知,不惊群。靠 ZAB/Raft 保证强一致,正确性最好,代价是多运维一套组件、性能不如 Redis。 一把合格的分布式锁看三点:互斥(同一时刻只有一个持有者)、无死锁(锁一定能释放:过期时间或会话机制兜底)、容错(持有者挂了,锁能被别人接管)。 选型建议:性能优先、能容忍极小概率异常,用 Redis;正确性优先(资金、库存),用 ZooKeeper/etcd;流量小的内部系统,数据库锁表也够用。 💡 思考题:Redis 锁的 value 为什么要用随机值,而不能所有客户端都写死同一个值?(提示:想想释放锁那一步。) Day 18 预告:待定 #系统设计60天

曝光 500 · 评论 2 · 点赞 4 · 书签 1 · 曝光/时 218.7367339027653

TwKit
正在载入