Professional Documents
Culture Documents
—— Owen.Yuan
What
• 锁
• 同⼀一进程不不同线程之间互斥,保护共享数据的读写安全。
• synchronized
• java.util.concurrent.locks.Lock
• 分布式锁
• 分布式系统下,多个进程中的不不同线程之间互斥。
Think
• 正确性
• 同⼀一时刻只能有⼀一个客户端(线程)获取到锁。
• 安全性
• 避免死锁
• ⽹网络不不可靠,客户端不不可靠等
• 可重⼊入
• 已获取锁的线程可以再⼀一次获取到锁
How
• DB
• ⾏行行级锁
• Redis
• 单进程单线程
• Zookeeper
• 分布式协调系统
The DB way
• 悲观锁
• 乐观锁
• 版本号字段
• 库存扣减场景
• Update stock_table set stock_num = stock - #{sale_count} where stock >= #{sale_count}
• 业务数据状态流转
• DB 乐观锁适合业务数据状态变更更场景
• 库存扣减
• 状态流转
• ⽆无法实现同⼀一时刻同⼀一⽅方法只能有⼀一个线程进⼊入。
A redis way
• Not recommend
• Acquire lock
• Release lock
• DEL lock_key_name ?
A bad case
• 客户端 A 获取到锁。
• 客户端 B 获取到锁。
• 客户端 C 获取到锁。
• 客户端 B 和 C 同时获取到锁。
How to avoid the problem
• 如何区分不不同的客户端
• 每个客户端有⼀一个全局的唯⼀一标识
A better way
• Recommend
• Acquire lock
• Release lock
• EVAL
Lua script
Another case
• 客户端 A 获取到锁。
• 客户端 B 获取到锁。
Think again
• 设置合理理的锁超时时间
• 可重⼊入?
• 请⾃自⾏行行思考
• 绝⼤大多数场景下,Redis 可以满⾜足。
The more better way —
zookeeper
• Zookeeper 是什什么 ?
• Zookeeper 能做什什么 ?
• 数据发布订阅
• 负载均衡
• 集群 Leader 选举
• 分布式锁
Concepts in zookeeper
• Node
• PERSISTENT
• PERSISTENT_SEQUENTIAL
• EPHEMERAL
• EPHEMERAL_SEQUENTIAL
• Session
• Watcher
How to do
• 同⼀一 Node 下创建
EPHEMERAL_SEQUENTIAL Lock-0000001
Node
Watcher, check exist
Lock-0000002
• 监听顺序排在前⾯面的邻近节点的 Watcher, check exist
exist 事件
Lock-0000003
锁成功 Lock-0000004
/app/sys-name/service-name/lock/lock-name
Distributed lock used in our
case
• 竞拍项⽬目
• 同⼀一竞拍商品同⼀一场次,出价先后顺序控制。
Tips
• 注意控制锁的粒度
• 如⾮非必要,切勿滥⽤用
Thank you
Hope it is useful to u