You are on page 1of 18

撩撩分布式锁

—— Owen.Yuan
What
• 锁

• 同⼀一进程不不同线程之间互斥,保护共享数据的读写安全。

• synchronized

• java.util.concurrent.locks.Lock

• 分布式锁

• 分布式系统下,多个进程中的不不同线程之间互斥。
Think
• 正确性

• 同⼀一时刻只能有⼀一个客户端(线程)获取到锁。

• 安全性

• 避免死锁

• ⽹网络不不可靠,客户端不不可靠等

• 可重⼊入

• 已获取锁的线程可以再⼀一次获取到锁
How
• DB

• ⾏行行级锁

• Redis

• 单进程单线程

• Zookeeper

• 分布式协调系统
The DB way
• 悲观锁

• Select column_name from table_name where id = #{id} for update

• 乐观锁

• More like CAS (compare and swap)

• 版本号字段

• Update table_name set version = version+1 where version = #{version}

• 库存扣减场景

• Update stock_table set stock_num = stock - #{sale_count} where stock = #{stock}

• Update stock_table set stock_num = stock - #{sale_count} where stock >= #{sale_count}

• 业务数据状态流转

• Update table_name set status = #{status} where status = #{previous_status}


The DB way

• DB 乐观锁适合业务数据状态变更更场景

• 库存扣减

• 状态流转

• ⽆无法实现同⼀一时刻同⼀一⽅方法只能有⼀一个线程进⼊入。
A redis way
• Not recommend

• Acquire lock

• SETNX lock_key_name lock_value ?

• EXPIRE lock_key_name timeout ?

• Release lock

• DEL lock_key_name ?
A bad case
• 客户端 A 获取到锁。

• 客户端 A 释放锁,请求未能及时送达 Redis。

• 锁定时间 timeout, 被 Redis 释放。

• 客户端 B 获取到锁。

• 客户端 A 释放锁请求送达,锁被释放。(客户端 B 获取的锁被释放)

• 客户端 C 获取到锁。

• 客户端 B 和 C 同时获取到锁。
How to avoid the problem

• 如何区分不不同的客户端

• 每个客户端有⼀一个全局的唯⼀一标识
A better way
• Recommend

• Acquire lock

• SET lock_key_name lock_value NX PX timeout

• Release lock

• EVAL

Lua script
Another case

• 客户端 A 获取到锁。

• 客户端 A 操作时间过⻓长,锁定时间 timeout, 被 Redis 释


放。

• 客户端 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

• 顺序排在⾸首位的节点则表示获取 Watcher, check exist

锁成功 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

You might also like