分布式锁总结
分布式锁实现方式
在分布式系统中,为了保证同一时间只能由一个客户端对共享资源操作,我们通常采用加锁来实现,常见有三种方式:
- 基于数据库实现的分布式锁
- 基于ZK实现的分布式锁
- 基于redis实现的分布式锁
对一个分布式锁的调研,我们可以从以下5种特性和4个雷区来考量,一个分布式锁没有绝对的好与坏,只有是否满足你的需求。
分布式锁需具备5种特性
- 互斥性:当一个线程/进程加锁成功后,其他线程/进程无法加锁,具有排他性。
- 锁失效机制:加锁成功后,应用服务器宕机导致锁未能释放,服务恢复后一直获取不到锁。应设置超时时间,防止出现类似死锁情况。
- 阻塞锁(可选):当前资源已被加锁,其他线程/进程来加锁是否阻塞等待,还是立即返回。
- 可重入性(可选):当前锁的持有者是否能再次进入。
- 公平性(可选):加锁顺序和请求加锁顺序是否一致,还是随机抢锁。
分布式锁4个雷区
- 死锁:加锁成功后,不知什么原因导致服务器出现宕机,未能成功释放,出现死锁。正确做法:设置超时时间
- 锁误删:只有持有当前锁的线程,才能删除锁,即:解铃还需系铃人。正确做法:唯一id标识当前线程
- 锁超时并发执行:加锁成功后,由于代码执行非常耗时、下游服务执行慢、调用链太长或GC耗时等原因导致锁超时,其他线程获得锁出现并发执行。
- 集群容错:成功在master加锁,未能及时同步到slave节点,此时出现脑裂存在多个master节点,其他节点也可以加锁成功。
3种分布式锁对比
我们从性能和安全两个方面来对比下这三种分布式锁,如下:
对比项 |
基于redis分布式锁 |
基于zk分布式锁 |
基于DB分布式锁 |
性能 |
好 |
稍差(动态增删节点) |
差 |
安全 |
差(Master宕机导致超时并发问题) |
稍差(GC停顿导致超时并发问题) |
好 |
3种分布式锁总结
- 基于redis实现的分布式锁
- 基于zk实现的分布式锁
- 基于数据库实现的分布式锁