分布式锁需要满足如下特性:
如上图是抽象的分布式锁实现模型,共享存储负责锁和对应客户端信息的存储。客户端1发起acquire()调用后,共享存储返回获取锁成功,当客户端2再发起对同一个锁的acquire()调用时,共享存储会返回获取锁失败。
以秒杀场景为例,常见的分布式锁服务的实现包括基于数据库、基于Redis、基于ZooKeeper三种。每种方案都有在可靠性、可用性、易用性等方面的优缺点。如何根据业务场景选型,需要技术人员分析并验证。
利用关系数据库支持数据的ACID强一致性和基于复制的高可用性,为系统中的竞争资源设计一张lock表。这张表用一列表示资源ID,表示正在尝试分配的资源,这一列用UNIQUE KEY约束,通过数据库保证这个资源ID不会被尝试分配多次,以此来提供锁能力,保证客户端互斥执行。
当客户端A尝试拍下宠物时,先将这只宠物ID加入到lock表,然后再进行剩余的支付操作,等支付成功后,将lock表中记录删除。如果在记录删除之前,有客户端B尝试拍下这只宠物,因为得不到锁,所以会返回给客户端B一个失败提醒。
优点:拥有较高的可靠性和稳定性。
缺点:性能会差些,并且会存在死锁问题。
Redis提供SET NX EX原子操作,它的语义是:当KEY不存在时,SET NX返回成功,并且设置这个KEY的过期时间;当KEY已存在时,SET NX返回失败。
我们可以构造一个以包含宠物ID的KEY,当客户端A执行SET {PET_ID} {VALUE} NX EX {EXPIRE_TIME}时,Redis返回成功。
在客户端A释放这个KEY之前,如果客户端B也执行SET NX指令,那么Redis会返回失败。
优势:有更高的性能和更低的延时,同时Redis原生支持的KEY过期机制,使得死锁问题很容易规避。
缺点:相比基于数据库的方案,Redis的高可用是异步复制的,这会在极端情况下出现KEY信息未及时同步宕机而导致锁丢失的情况。
ZooKeeper天生就是提供分布式协调服务的,非常适合用来实现分布式锁服务。有以下几个原因:
我们用一个包含了宠物ID信息的znode/path-to-lock/{pet-id}表示锁。多个客户端节点同时请求这个节点,只有一个节点能返回成功,其余返回失败。如果未抢到锁的客户端关心锁释放问题,可以同时注册一个Watcher事件,等待ZooKeeper的通知。
卖一下我厂架构师编著的《云原生应用架构实践》,以上内容出自该书,有删节。除了分布式锁的内容,书中也包含分布式事务的几种方案,但本身是解释互联网架构的纲要,即从单体架构到面向云计算的分布式服务化架构的演进。云计算是互联网业务的标配,如有整体了解对应的架构演进的需求,建议阅读。
分布式锁需要满足如下特性:
如上图是抽象的分布式锁实现模型,共享存储负责锁和对应客户端信息的存储。客户端1发起acquire()调用后,共享存储返回获取锁成功,当客户端2再发起对同一个锁的acquire()调用时,共享存储会返回获取锁失败。
以秒杀场景为例,常见的分布式锁服务的实现包括基于数据库、基于Redis、基于ZooKeeper三种。每种方案都有在可靠性、可用性、易用性等方面的优缺点。如何根据业务场景选型,需要技术人员分析并验证。
利用关系数据库支持数据的ACID强一致性和基于复制的高可用性,为系统中的竞争资源设计一张lock表。这张表用一列表示资源ID,表示正在尝试分配的资源,这一列用UNIQUE KEY约束,通过数据库保证这个资源ID不会被尝试分配多次,以此来提供锁能力,保证客户端互斥执行。
当客户端A尝试拍下宠物时,先将这只宠物ID加入到lock表,然后再进行剩余的支付操作,等支付成功后,将lock表中记录删除。如果在记录删除之前,有客户端B尝试拍下这只宠物,因为得不到锁,所以会返回给客户端B一个失败提醒。
优点:拥有较高的可靠性和稳定性。
缺点:性能会差些,并且会存在死锁问题。
Redis提供SET NX EX原子操作,它的语义是:当KEY不存在时,SET NX返回成功,并且设置这个KEY的过期时间;当KEY已存在时,SET NX返回失败。
我们可以构造一个以包含宠物ID的KEY,当客户端A执行SET {PET_ID} {VALUE} NX EX {EXPIRE_TIME}时,Redis返回成功。
在客户端A释放这个KEY之前,如果客户端B也执行SET NX指令,那么Redis会返回失败。
优势:有更高的性能和更低的延时,同时Redis原生支持的KEY过期机制,使得死锁问题很容易规避。
缺点:相比基于数据库的方案,Redis的高可用是异步复制的,这会在极端情况下出现KEY信息未及时同步宕机而导致锁丢失的情况。
ZooKeeper天生就是提供分布式协调服务的,非常适合用来实现分布式锁服务。有以下几个原因:
我们用一个包含了宠物ID信息的znode/path-to-lock/{pet-id}表示锁。多个客户端节点同时请求这个节点,只有一个节点能返回成功,其余返回失败。如果未抢到锁的客户端关心锁释放问题,可以同时注册一个Watcher事件,等待ZooKeeper的通知。
卖一下我厂架构师编著的《云原生应用架构实践》,以上内容出自该书,有删节。除了分布式锁的内容,书中也包含分布式事务的几种方案,但本身是解释互联网架构的纲要,即从单体架构到面向云计算的分布式服务化架构的演进。云计算是互联网业务的标配,如有整体了解对应的架构演进的需求,建议阅读。
* 版权声明 :社区问答内容由互联网用户编辑提交,本社区不拥有所有权,也不承担相关法律责任。如果您发现本社区中有涉嫌侵权、暴力、色情、反
动等言论,欢迎发送邮件至: 进行举报并提供初步证明,一经查实,本社区将立刻删除相关内容。