07 | 分布式锁:关键重地,非请勿入

2019-10-07 聂鹏程
《分布式技术原理与算法解析》
课程介绍


讲述:聂鹏程

时长:大小18.95M


你好,我是聂鹏程。今天,我来继续带你打卡分布式核心技术。
我在第 3 篇文章中,与你一起学习了分布式互斥,领悟了其“有你没我,有我没你”的精髓,为你解释了同一临界资源同一时刻只能被一个程序访问的问题,并介绍了解决分布式互斥的算法。
不知道你有没有发现一个细节,在之前介绍的算法中,我主要讲了如何协调多个进程获取权限和根据权限有序访问共享资源,“获得访问权限的进程可以访问共享资源,其他进程必须等待拥有该权限的进程释放权限”。但是,我并没有介绍在访问共享资源时,这个权限是如何设置或产生的,以及设置或产生这个权限的工作原理是什么。
那么,在本讲,我就将带你一起打卡分布式锁,去学习分布式锁是如何解决这个问题的。

为什么要使用分布锁?

首先,我先带你认识一下什么是锁。
在单机系统中,经常会有多个线程访问同一种资源的情况,我们把这样的资源叫做共享资源,或者叫做临界资源。为了维护线程操作的有效性和正确...

展开全文
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。

精选留言

  • miracle
    2019-10-31
    1 .redis 不用通过超时来释放锁,DEL操作可以直接释放不用等到超时 2. redis 官方已经明确说明不推荐 setnx 来实现分布式锁了(https://redis.io/commands/setnx) 官方给出了 the Redlock algorithm 各语言的实现版本是来实现分布式锁的机制,比如JAVA的实现版本(https://github.com/redisson/redisson) 所以从可靠性来讲并不比zk的方案差
    共 7 条评论
    42
  • Eternal
    2019-10-26
    学完3-7节我自己总结了一下个人的理解: 分布式协调与同步的场景中需要解决一些通用问题 1.分布式系统中,多个节点都需要访问一个临界资源,但是同一时刻只能有一个节点可以访问,为了解决这个问题就是要通过分布式互斥来实现,老师说的有你没我,有我没你;分布式锁就是实现分布式互斥的一种实现方式 2.分布式系统中,多个节点需要同时写一份相同的数据,怎么保证数据写的是一致的呢?需要一个节点来协调,这个协调节点叫做leader,它是怎么产生的呢?是通过选举产生的,这就是分布式选举; 3.分布式系统中,多个节点达成某一项共识可以通过选举(投票)的方式实现,选举不简单是少数服从多数,还有一些拓展:投票的时候考虑优先级,考虑权重,考虑代理等 4.分布式系统中除了互斥,达成共识还有协同作战:分布式事务,多个节点同时做一件事,要么全成功,要么全失败;本来单机事务是通过数据库(Mysql)的多版本MVCC实现的,现在在分布式环境中,每个节点都有数据库,不能实现分布式事务了,现在需要通过程序来模拟实现单机事务的特性ACID。考虑实际情况,XA协议下的2阶段和3阶段提交都不能很好的满足需求,衍生出了新的理论(BASE)来实现
    展开

    作者回复: 总结得很到位,加油!

    共 3 条评论
    28
  • 忆水寒
    2019-10-07
    分布式锁是实现互斥的一种手段。
    共 1 条评论
    14
  • 安排
    2019-12-14
    给库存数加锁这个例子写的不好。文中说到, 我们能想到的最简单方案就是,给吹风机的库存数加一个锁。当有一个用户提交订单后,后台服务器给库存数加一个锁,根据该用户的订单修改库存。而其他用户必须等到锁释放以后,才能重新获取库存数,继续购买。 既然说了其他用户必须等到锁释放后才能重新获取库存,那为什么后面又说A和B同时获得库存数呢?这不矛盾了吗?还有这个库存数是存在哪里的?如果存在公共服务器上,类似于redis那个例子,那多个用户抢同一把锁也没问题啊,反正只有一个能抢到,等一个用户释放锁,下一个用户再获得锁。
    展开
    共 1 条评论
    12
  • Dale
    2019-10-09
    分布式互斥是在分布式系统中存在多个节点共享某个资源或临界区,任何时刻只允许一个进程访问资源或执行临界区,而分布式锁正好是解决分布式互斥的一种方法。

    作者回复: 总结得很到位,加油!

    
    12
  • 冬风向左吹
    2020-04-12
    1、分布式互斥:在一个分布式系统中,控制集群中的节点互斥的访问共享资源,算法有:集中式算法、民主协商算法(分布式算法)、民主协商算法 2、分布式锁:实现分布式互斥需要用到分布式锁。 基于数据库的分布式锁; 基于缓存的分布式锁; 基于zookeeper的分布式锁 3、分布式选举:对于一个分布式集群来说,需要对集群节点进程调度、管理,需要通过分布式选举选出leader节点。选举算法有: 长者为大:bully算法 民主投票:Raft算法 具有优先级的民主投票:ZAB算法 4、分布式共识:分布式系统中多个节点之间,彼此对某个状态达成一致结果的过程。常用的算法有: PoW(工作量证明:比特币) PoS(权益证明:以太坊) DPos(委托权益证明:比特股) 5、分布式事务:XA 是一个分布式事务协议,规定了事务管理器和资源管理器接口。事务管理器即类似于使用集中式算法对资源进行协调 二阶段提交方法(2PC):强一致性 三阶段提交方法(3PC):强一致性 基于分布式消息的最终一致性方案
    展开

    作者回复: 赞👍,加油

    
    9
  • xfan
    2019-10-14
    最后一段有些问题 应改为若本进程为写请求,则向比自己序号小的最后一个请求节点注册监听事件,因为写和写之间也是互斥的。

    编辑回复: 这个问题已经修正,非常感谢你的反馈~

    
    6
  • 小咖
    2019-10-26
    这课程买的太赚了
    
    6
  • 卫江
    2019-10-07
    老师,想问一个问题,通过zoomkeeper来实现分布式锁,等发生网络中断的对应的临时节点会消失来实现分布式锁的异常情况,我们知道进程挂掉会触发相应的文件引用计数减一,一般情况下会把连接关闭,但是如果是正常的网络中断引起的临时节点消失,从而其他进程获取锁,但是可能发生网络中断的进程业务并没有处理完成,这个该怎么办?
    共 4 条评论
    5
  • Geek_f6f02b
    2019-10-07
    分布式锁与分布式互斥的关系是什么呢? 我觉得分布式互斥是前提条件或者说实现目的,而分布式锁是手段或者说是实现方法。 还有文章中有2个地方不理解。一个是那个zookeeper实现分布式锁的,写请求为什么说是要等待比自己小的读请求结束,如果是比自己小的写请求就不用等待了吗?我理解是,自己为读请求就等待比自己小的写请求结束,写请求就等待所有比自己小的所有请求结束。另一个不理解也是类似问题,就是下面那个写watch应该是等等比自己小的那个事件就结束添加watch事件吧?
    
    4
  • 钱
    2020-02-14
    阅过留痕 1:锁的本质就是一个标记,通俗点就是一个变量 2:单机锁是多个线程共享的某个变量,操作共享资源前,需要先看这个变量是否为某个值,表示加锁或解锁啦 3:分布式锁是多个进程共享的某个变量,其他的和单机锁类似,当然,操作系统如果挂了,单机也就完全不可用了,如果操作系统没挂,多线程共享某个变量的控制通常是非常健壮的,分布式系统的特点是不会整个集群不可用,不过某台机器不可用的概率非常大,同时网络通信也是不可靠的,所以,分布式锁的可靠性就不好保证了,为了保证他的可靠性就需要引入集群,这样复杂性又会增多了 4:分布式锁很明显是分布式互斥的一种实现方式 5:从面试的角度来讲老师讲解的还不够全面,redis分布式锁的三连击都顶不住,不够细致和全面。
    展开
    
    4
  • 任鹏斌
    2019-10-18
    老师关于redis的分布式锁还有几个问题 1、setnx加过期时间的原子性问题(目前应该已经解决) 2、锁的续期问题 3、如果redis集群或者主从模式下只写入一个节点时挂掉导致锁失效 期望老师答疑时详细说一下
    展开
    
    3
  • 开心小毛
    2019-10-13
    请老师确认一下redis是否会为一个KEY建立等待队列。我以为,Redis的分布式锁根本没有队列,收到setnx返回为0的进程会不断的重试,直到某一次的重试成为DEL命令后第一个到达的setnx从而获得锁,至于此进程在等待获得锁的众多进程中是不是第一个发出setnx的,redis并不关心。
    共 4 条评论
    3
  • 流云
    2020-03-08
    分布式锁是分布式互斥的一种实现,更确切的说是一种集中式分布式互斥算法,由第三方(DB,cache,zk)来充当协调者。
    
    2
  • 厨子
    2020-09-29
    作者其实可以再多写点,说明redis和zk的节点超时的一些原因以及zk的锁为什么要找节点最小的那个节点
    
    1
  • Sancho
    2020-02-03
    老师您好,在读你这篇专栏时,对基于Zookeeper实现的分布式锁有几个疑问? 1.从应用程序角度,对Zookeeper的请求应该只有一个,获取分布式锁请求。这个请求到达Zookeeper后如何被拆分成“读请求”和“写请求”的? 2.文中“Zookeeper实现分布式锁”的第4个步骤,和“解决羊群效应”的第3个步骤中,提到的“节点编号”和“序号”是同一个含义吗? 3.“解决羊群效应”的第3个步骤,没太想明白,可能是存在第1个问题的困扰导致的。能否请老师补充一张时序图。 谢谢。
    展开
    
    1
  • xiaobang
    2019-11-07
    分布式锁实现了分布式互斥的集中式算法?
    
    1
  • Li Shunduo
    2019-10-12
    redis的分布式锁如何实现排队?
    共 2 条评论
    1
  • ahnselina
    2020-12-02
    想象一下,用户 A 想买 1 个吹风机,用户 B 想买 2 个吹风机。在理想状态下,用户 A 网速好先买走了 1 个,库存还剩下 1 个,此时应该提示用户 B 库存不足,用户 B 购买失败。但实际情况是,用户 A 和用户 B 同时获取到商品库存还剩 2 个,用户 A 买走 1 个,在用户 A 更新库存之前,用户 B 又买走了 2 个,此时用户 B 更新库存,商品还剩 0 个。这时,电商就头大了,总共 2 个吹风机,却卖出去了 3 个。 =============================== 没看懂这,在有锁的情况下,用户A和用户B怎么会同时获取到库存呢,不应该是只有一个获取到库存吗
    
    
  • 林通
    2020-11-10
    本进程为写请求,如果比自己序号小的节点中有读请求,则等待。 如果比自己序号小的节点有写请求,就不用等待了吗?
    
    