00:00
目前为止,我们的分布式所呢依然存在一个问题,只有三点,故障问题。现在呢,我们的red release呀,只有单台服务器,那么一旦这台服务器挂掉了,那么咱所有的分布所机制都被失效,那怎么办呢?所以呢,在企业开发里面啊,我们的玩通常呢,会玩red集群。那比如说呢,我们会搭建组从集群,并配合一定的哨兵机制啊,一旦组挂掉了,我们可以把从呢升级为主。好,那我们来看一下,如果我们搭建这种组成机群的话,那么锁呢,会出现什么问题呢?首先我们是100,幺零这个应用程序,假如呢,它已经从组里面获取到锁了。因为获取锁的过程啊,本质呢,是一个类似于set这样的一个操作啊,它是一个写的操作,那么写的操作呀,它肯定会到达我们的主节点。那么于是呢,在主节点里面已经获取到锁了。
01:02
那回到锁之后啊,那么重要,同步数据它需要一个过程。首先呢主啊,他需要把这个写的操作进入到IDB日志,或者呢是I日志里面去啊,那么它需要发生IO操作。那么然后呢,从呢需要去拉取主的日志,让他需要发生网络操作啊,所以这个过程呢,相对来说还是比较耗时的。那么可能会出现什么情况呢?从还没来得及同步数据呢,然后组呢,就已经挂掉了。那么此时再配合分性的哨兵,然后呢,我们这个从啊,它就会升级为一个新的主了。啊,它变成一个新的主了。啊,那么然后呢,10086啊,在高引发情况下,那么它突然也发送个请求过来,那么需要获取锁。
02:00
那么新的组他不知道有人获一道锁了,因为还没来得及同步数据的这个旧的组就已经挂掉了,那么新的组是不知道的啊。那么于是呢,10086就从这个新的组这里。又获取了一把锁。那么此时呢?两个请求就并发了,导致我们的所提制失效。那么戒烟呢?可能会出现我们的超卖现象啊。好,那么这是咱们这个。在第七个特征啊,在所在集群集群情况下可能会导致所机制失效,那么原因呢,是这样子的啊,首先第一步。我们的客户端程序,比如说10010,它从主中获取数据啊,获取锁了哈。那么此时啊,从还没来得及同步数据,那么主挂了就挂了,那么于是。
03:10
从升级为升级为主,那么紧接着咱的另外一个后端程序。客户端程序程序10086从就从新主中获取到所,那么导致所机制。所机制那么失效啊,失效那怎么办呢?好,那我们就需要。红色犯法了。红锁算法是官方为我们提供的一种算法机制。那么它的全称呢?或者英文名,我们称之为redlo。那么red呢?是red的前三个字母,我们可以翻译成红。
04:03
Lock呢,我们可以翻译成所,所以呢,简称呢红色三八。那轰动算法呢,它是ready特有的啊,那么其他地方呢,是没有这样的一个算法的。那这个算法到底是怎么一回事呢?我们可以呢,通过这样的一个连接地址来去查看官方文档。当然呢,它是英文的。那么在我的课件上有一段中文描述啊,是我们根据官方文档的英文翻译过来的。那这段描述啊,我们也不去读它了啊,我们可以呢,直接看一张图。那么结合这张图来去看一下红薯算法,它是怎么工作的啊,又是怎么一回事?那么首先我们还是需要有多个release子节点,那么这些子节点呢,它们之间是没有组成关系的,咱前面分析过。如果我们是单台release的话,容易出现单点故障问题,一旦我这台release挂掉了,那么咱的分布式否呢就无法使用了。
05:02
所以呢,我们必须有要有多台release节点。那么这多个热力节点之间是没有组成关系的,也没有哨兵机制。那么它们是相互完全独立的啊,那咱最好呢,给它放在不同的服务器上面,或者呢,放在不同的虚拟机里面。相互之间是不知道的。那我们现在呢,有一个客户端程序,比如1001这样的一个应用程序,它需要去获取锁,那么怎么获取锁呢?又该怎么去释放锁呢?首先来看获取锁怎么去获取。那获取所失呀,首先第一步我们需要先获取应用程序自己的系统当前时间。自己的当前时间,OK,那会到当前时间之后啊,第二步我们开始依次从这多个节点上。那么来去获取所。那么这个货解锁怎么获取锁呢?
06:02
哎,那么比如说我们之前呢,使用set NX来一火计索,那比如说呢,我们之前呢,使用set的KV啊NXEX的一火一素。那再变行时呢,我们可以通过H塞那么来去获取索,那获取索的方式呀,跟以前一样,例如我们是塞NX的获取索哈,那么此时呢,我这五个基点都通过塞NX分别来去获取索。那么这个K和value必须得要一样。好,那么这来第二步,那么第一步怎么回事呢?咱刚才分析过了,我要获取系统当前当前时间,谁的当前时间是应用程序的当前时间。会到当前时间之后啊,我们第二步咱开始依次到每个基点上来去获取所,比如说咱可以通过SNX指令依次的一或一所12345这样的一个顺序。
07:04
那么然后呢,K和V必须得是一样的啊。那么然后呢,我们在呃,这多个节点上获取锁的时候,那咱最好呢,有个超时时间,因为你是依次获取的。如果我们没有一个超时间的话,就有可能会出现什么情况呢?比如第一台服务器可能已经挂掉了,已经宕机了。那么从自带服下来就火取锁,一直尝试火取锁,尝试火炬锁,那么一直获取不到,因为它宕机了。那怎么办呢?那后面这几台服务器可能是健康的节点是健康的,虽然他们是健康的,但是呢,他们没有机会去获取,因为都在第一台服务器这个位置阻塞着。那所以呢,咱只要给他一个超时时间,如果超过一定时间依然没有获取到锁,我们要尽快从下一个节点中得去获取锁,因为下一个节点可能是健康的啊,咱不能在一个节点上把时间给浪费完了。
08:04
好,那么这是咱们啊,第二个啊。那么然后第三个啊,我们开始去。啊,第二步呢,我们是依次获取锁啊,然后并且要有一个超时时间啊,以避免呢被某一个。宕机了的节点给阻塞住了。超时时间。那么第三步。我们要去计算你获取所所消耗的这个时间啊,那比如说呢,我这个节点消耗了十五十五秒,那这个地点呢,消耗了十秒,这个地点呢也消耗了十秒。那么加在一起呢,可能就已经30多秒了。那我的获期时间可能才30秒,结果呢,你这获取锁就消耗了35秒。那么此时呀。这个呢也是无效的啊,因为呢时间太长了。那我们计算这个消耗时间,嗯,消耗时间,那么这个消耗时间要远远小于我们的过期时间的情况下,那么咱们才认为呢。
09:09
是已经获取到锁了哈,啊,这个时间呢,大家可以认为是锁定时间,比如咱是30秒嘛,咱之前都设置为30秒。啊,自动锁定时间,当然了,我们还有什么自动续期什么之类的啊。那么这样的话呢,咱就认为没有自动续期的情况下啊,这是我们的锁定时间。那如果呃,小于这个锁定时间的情况下,我们啊,才认为这个获取所呢是合法的,否则呢,是无效的啊。那么其实要想获取所成功,必须要满足两个条件才可以,首先呢是消耗时间,那么小于我们的锁定时间。那并且。并且。我们半数以上获取锁成功才算获取锁成功啊,比如这个节点获取锁失败了,那么这个节点的获取锁成功了,这个节点获取锁失败了,但是这两个节点能获取所成功了,那已经超过百除了。
10:09
咱可以认为呢,获取锁已经成功啊,半数以上。啊,同时满足这两个条件才可以啊。好,那么然后呢,第四步如果获取锁成功了。那我们还得要去。那算一下还剩余多少锁定时间?那比如说呢,我后解锁呀,可能这个地方呢,我花了这个一秒钟,这个地方呢,可能花了两秒钟,那这个地方呢,可能也花了两秒钟,当然我们这里比较夸张啊,那么真实情况下呢,可能也就几几毫秒那就可以了。那我们这个地方呢,也可能花了两秒钟,他可能花了一秒钟,但总共花了多少秒呢?总共花了八秒钟。那我们剩余锁定时间还剩22秒。那我们应该是初始这个锁定时间,那么减去一个减去一个消耗时间,减去第三步计算的那个消耗时间啊。
11:05
那么然后呢,就等于我们剩余的这个锁定时间。好,那么时间到了之后呢,我们也会自动去解锁。好,那么第五步,如果我们获取锁失败了,那怎么办呢?好,我们只要把所有的基点给解锁。比如说呢,你可能没有超过半数啊,你只有这两个节点获取所成功了,这三个节点都获取所失败了。那再被有数的话呢,你可能有半数以上会到锁了,但是呢,你超时了,可能你35秒才获取到锁,我锁定时间是30秒,你35秒才获取到锁,虽然获取到了,但是呢,时间太长了。我们也认为火炬所失败了啊。那我们呃,怎么办呢?此时要对所有节点等于释方程数。来释放锁,否则那么这个节点不就死锁了吗?被你一直给锁住了啊,你如果不释放的话。那么有同学说了,那么嗯,我只要对这些成功的节点雷释放锁不就可以了吗?像这种失败的,我需要去释放锁吗?
12:08
哎,需要因为呢,你不知道具体是哪个节点成功了,哪个节点失败了,你可能可能只是知道呢,半数以上已经成功了。所以呢,咱最好呢,对所有的节点来去释放锁,如果你没有设置锁成功,那你来去D指令的时候,执行D指令的时候,那么营养条件是零的。那么如果呢,你已经获取所成功的情况下,你第要指定的一项条数呢,肯定是一对吧,肯定是一,所以呢啊,你都去执行D要指令来释放所就可以了。啊,没有什么影响。大家对所有啊节点来去释放锁啊,如果火炬锁失败了。好,这咱们这个加速的过程就分这五个步骤。啊,那么解锁该怎么去解锁呢?那么解锁呢,其实很简单,比如说呢,我这货解锁成功了,然执行完业务逻辑之后呢,我要进行解锁,那么解锁的话,咱只要对每一个节点来执行DL指令,那就可以解锁了呀。
13:07
那具体要不要用读法脚本,那我们要看具体场景啊。那么如果对吧,你要追求原子性,要防止误酸,那么你可以呢,去使用卢瓦胶,本来就释放素啊,没有什么问题,那对每个基点呢,来于释放缩啊。好,这是咱们这个红图算法的一个基本过程。
我来说两句