分布式锁的实现方式

本文讨论了分布式环境中实现锁的三种方式:数据库锁、缓存锁(如Redis的setnx和delete),以及ZooKeeper的临时顺序节点。对比了它们的性能、可靠性和缺陷,特别强调了数据库锁的低效性和ZooKeeper的顺序机制在电商场景中的应用。
摘要由CSDN通过智能技术生成

分布式锁是指分布式环境下,系统部署在多个机器中,实现多进程分布式互斥的一种锁。实现分布式锁有三种主流方式,接下来一一盘点。

盘点之前要说说选择时的优缺点

数据库实现的锁表完全不推荐。
Redis分布式锁性能优于ZooKeeper,因为不需要反复创建节点。
实现的简单程度和可靠性ZooKeeper更好,因为其封装好的框架几乎能应对所有的分布式锁问题。

基于数据库实现的——锁表

实际上就是开一个表。当我们要锁住某个资源时,就在该表中增加一条记录,想要释放锁的时候就删除这条记录。但数据库表要磁盘io,所以效率很低。并且一旦这个数据库寄了,那系统崩了。数据库锁没有失效时间,未获得锁的进程只能一直等待已获得锁的进程主动释放锁。倘若已获得共享资源访问权限的进程突然挂掉、或者解锁操作失败,使得锁记录一直存在数据库中,无法被删除,而其他进程也无法获得锁,从而产生死锁现象。

基于缓存实现的——缓存锁

就是说把数据存放在计算机内存中,不需要写入磁盘,减少了IO读写,实现时候是维护一个队列来维持进程访问共享资源的顺序的。
Redis的setnx和delete方法就支持这一方式。

也存在缺陷,因为进程没法主动释放锁,假设ABC三个进程来,A完事了到B,B进程对应的服务器坏了,那C就得等B超时自动释放才能访问共享资源。通过超时时间来控制锁的失效时间,并不是十分靠谱,因为一个进程执行时间可能比较长,或受系统进程做内存回收等影响,导致时间超时,从而不正确地释放了锁。

ZooKeeper

ZooKeeper基于树形数据存储结构实现分布式锁,ZooKeeper的树形数据存储结构主要由4种节点构成:

  • 持久节点(PERSISTENT)。这是默认的节点类型,一直存在于ZooKeeper中。
  • 持久顺序节点(PERSISTENT_SEQUENTIAL)。在创建节点时,ZooKeeper根据节点创建的时间顺序对节点进行编号命名。
  • 临时节点(EPHEMERAL)。当客户端与Zookeeper连接时临时创建的节点。与持久节点不同,当客户端与ZooKeeper断开连接后,该进程创建的临时节点就会被删除。
  • 临时顺序节点(EPHEMERAL_SEQUENTIAL)。就是按时间顺序编号的临时节点。

ZooKeeper是根据临时顺序节点来实现的分布式锁。以电商售卖吹风机的场景为例。假设用户A、B、C同时在11月11日的零点整提交了购买吹风机的请求,ZooKeeper会为每个进程分配一个临时顺序节点。每个节点都有一个监听器监听当前自己是不是序号最小的**(理论上要监听共享资源上的所有节点,实际上只要监听自己上一个节点的状态就行)**,是就去访问共享资源,不是就判断:

  • 假设一个进程要读,前面有写的话,就得等待;假设前面没有写的,就可以并发读。
  • 假设一个进程要写,前面有进程在就得等待。
    在这里插入图片描述
  • 13
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值