分布式锁
一. 概述
在分布式系统中,往往会出现各个节点对同一资源竞争的情况下。基于该背景下,衍生出分布式锁的这个 概念。那么问题来了,编写分布式锁代码时检验该代码到底对还是错,如何评估的?
二. 前提条件
1. 获取锁
我忘了从哪里看到的文章,对其进行了定义。那么以还残留的印象以及我的理解,进行解读。
独享性 只能有一个节点拥有,不可以同时拥有。这个是最基本的前提条件。
无死锁 设置超时时间。避免拥有该锁的节点宕机,导致其他节点一直获取不到锁。为了避免超时时间过短,可以节点上加上一个定时任务,来检查获取锁需要做的动作是否已经做完,如果还没做完,可以延长持有锁的事件。当然该定时任务可以解决另外的一个问题:持有锁的节点执行对应的动作时,发送释放锁请求失败时,可以交给定时任务来出来。定时任务在源代码中常常定义为 watchDog 看门狗。
可用性 个别服务机宕机,依然提供锁服务。
所以,在编写分布式锁代码时,就需要评估提供分布式锁的系统是否以上要求,如果不支持,那么开发出来的代码是有问题的。
2. 释放锁
释放锁就比较简单了,但仍需要注意的一个点:确保释放自己拥有的锁。因为在获取锁阶段,我们设置了超时时间,一旦超时时间而拥有该锁的节点 A 还没释放锁时,系统会自动将其锁释放掉,以至于其他节点 B 能获取锁。这个时候,节点 A 和节点 B 同时拥有锁,这就违背了分布式锁的独享性。
三. 实践
这里不编写代码,网上的代码例子很多,而且很多注意点都写的很清楚;
1. redis
在基于 redis 编写分布式锁时,需要注意的是要加上超时时间的设定。以及在释放锁时确保释放自己拥有的锁,这个就需要每个节点给这个锁附加一个不同的值。
当基于 redis 编写分布式锁,是会出现问题的。主要是因为 redis 无法保证数据的一致性问题。由于 redis 在副本拷贝是采用的异步拷贝的,这个就会破坏了独享性。对业务有一定的影响。那为什么依然还有人会用该 redis 做分布式锁呢?这个就需要结合业务场景来阐述,主要是评估一旦出现同时有多个节点拥有同一把锁,造成的生产问题有多大影响?例如,在抢购商品时,常规逻辑是当没有库存时是不允许下单成功的。使用 redis 来限制,会出现库存为 1 件时依然还有多人下单成功的,这时库存是为负数。然而商家往往有备货,或者从其他地方调货。可以避免没有库存(名义上库存)而发不出货出来的。这个就可以采用该方案。
所以说,一旦采用 redis 方案来做分布式锁,就需要有一套解决方案(主要是人工处理的)来解决 redis 衍生的问题。该问题发生的概率很低,只要实时监控 redis 集群的运行状态,一旦出现宕机,及时修复即可。
2. zookeeper
zookeeper 是最完美的方案,主要是因为其采用了分布式一致性算法(zab 协议)来确保了数据的一致性。
四. 总结
相关的代码以及详细的介绍,可以去查看
使用 Redis 如何设计分布式锁?使用 Zookeeper 来设计分布式锁可以吗?以上两种分布式锁的实现方式哪种效率比较高?该文章。
评论