- N +

关于分布式锁原理-redis分布式锁,zookeeper分布式锁

原标题:关于分布式锁原理-redis分布式锁,zookeeper分布式锁

导读:

首先分布式锁和我们平常讲到的锁原理基本一样,目的就是确保。在多个线程并发时,只有一个线程在同一刻操作这个业务或者说方法、变量。...

文章目录 [+]

首要分布式锁和咱们往常讲到的锁原理根本相同,意图便是保证,在多个线程并发时,只需一个线程在同一刻操作这个事务或许说办法、变量。

在一个进程中,也便是一个jvm 或许说运用中,咱们很简略去处理操控,在jdk java.util 并发包中现已为咱们供给了这些办法去加锁, 比方synchronized 关键字 或许Lock 锁,都能够处理。

可是咱们现在的运用程序如whiteeeen果只布置一台效劳器,那并发量是很差的,假如一同有上万的恳求那么很有或许形成效劳器压力过大,而瘫痪。

想想双十一 和 三十晚上十点分支付宝红包等事务场景,天然需求用到多台效劳器去一同处理这些事务,那么这些效劳或许会有上百台一同处理,

可是请咱们咱们想一想,假如有100台效劳器 要处理分红包的事务,现在假定有1亿的红包,1千万怎样戒撸个人分,金额随机,那么这个事务场景下是不是有必要保证这1千万个人终究分的红包金额总和等于1亿。

假如处理欠好~~每人分到100万,那马云爸爸估量大年初一,就得宣告破产了~~

1,惯例锁会形成什么状况?

首要说一下咱们为什么要搞集群,简略了解便是,需求量(恳求并发量)变大了,一个工人处理才能有限,那就多招一些工人来一同处理。

假定1千万个恳求均匀分配到100台效劳器上,每个效劳器 接纳10w的恳求(这10w个恳求并不是在同一秒中来的,或许是在1,2个小时内,能够联想下咱们三十晚上开红包,比及10.20开端,有的人立马开了,有的人是不是比及12点了才想起来~)

那这样的话,均匀到每一秒上的恳求也就不到1千个,这种压力一般的效劳器仍是能够接受的。

榜首个恳求到来后,是不是需求在1亿里边给他分一部分钱,金额随机,假定榜首个人分到了100,那是不是要在这1亿中减去100块,剩余99999900 块~

第二个用户再来分,金额随机,这次分200块,那是不是就需求在剩余的99999900块中再减去200块,剩余99999700 块。

比及第10w个用户来,一看还有1000w,那这1000w全成他的了。

等所以在每个效劳器中去分1亿,也便是10w个用户分了一个亿,终究总计有100个效劳器,要分100亿。

假如真这样了,尽管马云爸爸不会破产(据最新计算马云有2300亿人民币),那分红包的开发项目组,以及产品司理,能够GG了~

简化结构图如下:

关于分布式锁原理-redis分布式锁,zookeeper分布式锁

2,分布式锁怎样去处理?

那么为了处理这个问题,让1000万用户只分1亿,而不是100亿,这个时分分布式锁就派上用处了。

分布式锁能够把整个集群就当作是一个运用相同去处理,那么也就需求这个锁,要独立于每一个效劳之外,而不是在效劳里边。

假定榜首个效劳器接纳到用户1的恳求后,那么这个时分,他就不能只在自己的运用中去判别还有多少钱能够分了,而需求去外部恳求专门担任办理这1亿红包的人(效劳),问他:哎,我这儿要分100块,给我100。

办理红包的妹子(效劳)一看,还有1个亿,那好,给你100块,然后剩余999萧博瀚99900块。

第二个恳求到来后,被效劳器2获取,持续去问询,办理红包的妹子,我这边要分10块,办理红包的妹子先查了下还有邱云光99999900,那就说:好,给你10块。那就剩余99999890块

比及第1000w个恳求到来后,效劳器100吕述国拿到恳求,持续去问询,办理红包的妹子,你要100,妹子翻了翻白眼,对你关于分布式锁原理-redis分布式锁,zookeeper分布式锁说,就剩1块了,爱要不要,那这个时分就只能给你1块了(1块也是钱啊,买根辣条仍是能够的)。

这些恳求编号1,2不代表履行的先后次序,正式的场景下,应该是 100台效劳器每个效劳器持有一个恳求去拜访担任办理红包的妹子(效劳),那在管红包的妹子那里一同会接纳到100个恳求,这个时分就需求在担任红包的妹子那里加个锁就能够了(抛绣球),你们100个效劳器谁拿到锁(抢到绣球),谁就进来和我谈,我给你分,其他人就等着去吧

经过上面的分布式锁的处理后,马云爸爸总算定心了,决定给红包团队每人加一个鸡腿。

简化关于分布式锁原理-redis分布式锁,zookeeper分布式锁的结构图如下:

关于分布式锁原理-redis分布式锁,zookeeper分布式锁

3,分布式锁的完结有哪些?

提到分布式锁的完结,仍是有许多的,有数据库方法的,有redis分布式锁,有zookeeper分布式锁等等

咱们假如选用redis作为分布式锁,那么上图中负“责红包的妹子(效劳)”,就能够替换成redis,请自行脑补。

3.1,为什么redis能够完结分布式锁?

首要redis是单线程的,这儿的单线程指的是网络恳求模块运用了一个线程(所以不需考虑并发安全性),即一个线程处理一切网络恳求,其他模块仍用了多个线程。

在实践的操作中进程大致是这姿态的:

效劳器1要去拜访发红包的妹子,也便是redis,那么他会在redis中经过"setnx key v我和三个小女子alue" 操作设置一个key 进去,val澳门追凶ue是啥不重要,重要的是要有一个key,也便是一个符号,并且这个key你爱叫啥叫啥,只需一切的效劳器设置的key相同就能够。

假定咱们设置一个,如下图

关于分布式锁原理-redis分布式锁,zookeeper分布式锁

那么咱们能够看到会回来一个1,那就代表了成功。

假如再来一个恳求去设置相同的key,如下图:

这个时分会回来0,那就代表失利了。

那么咱们就能够经过这个操作去判别是不是当时能够拿到锁,关于分布式锁原理-redis分布式锁,zookeeper分布式锁或许说能够去拜访“担任发红包的妹子”,假如回来1,那我就开端去履行后边的逻辑,假如回来0,那就阐明现已被人占用了,我就要持续等候。

当效劳器1拿到锁之后,进行了事务处理,完结后,还需求开释锁,如下图所示:

删去成功回来1,那么其他的效劳器就能够持续重复上面的过程去设置这个key,以到达获取锁的意图。

当然以上的操作是在redis客户端直接进行的,通进程序调用的三生不幸撞上你话,必定就不能这么写,比方jav星灵溯停刊a 就需求经过jedis 去调用,可是整个处理逻辑根本都是相同的

经过上面的方法,咱们好像是处理我国最强音林军了分布式锁的问题,可是想想还有没有什么问题呢??

对,问题仍是有的,或许会有死锁的问题发作,比方效劳器1设置完之后,获取了锁之后,遽然发作了宕机。

那后续的删去key操作就无法履行,这个key会一向在redis中存在,其他效劳器每次去查看,都会回来0,他们都会认为有人在运用锁,我需求等。

为了处理这个死锁的姐恋问题,咱们就就需求给key 设置有效期了。

设置的方法有2种

1,榜首种便是在set完key之后,直接设置key的有效期 "expire key timeout" ,为key设置一个超时时刻,单位为second,超越这个时刻锁会主动开释,防止死锁。

这种方法相当于,把锁持有的有效期,交给了redis去操控。假如时刻到了,你还没有给我删去key,那redis就直接给你删了,其他效劳器就能够持续去setnx获取锁。

2,第二种方法,便是把删去key权力交给其他的效劳器,那这个时分就需求用到value值了,

比方效劳器1,设置了value 也便是 timeout 为 当时时刻+1 秒 ,这个时分效劳器2 经过get 发现时刻现已超越体系当时时刻了,那就阐明效劳器1没有开释锁,效劳器1或许出问题了,

效劳器2就开端履行删去key操作,并且持续履行setnx 操作。

可是这块有一个问题,也便是,不但你效劳器2或许会发现效劳器1超时了,效劳器3也或许会发现,假如刚好,效劳器2,setnx操作完结,效劳器3就接着删去,是不是效劳器3也能够setnx成功了?

那就等所以效劳器2和效劳器3都拿到锁了,那就问题大了。这个时分怎样办呢?

这个时分需求用到 “GETSET key value” 指令了。这个指令的意思便是获取当时key的值,并且设置新的值。

假定服修身别传务器2发现key过期了,开端调用 getset 指令,然后用获取的时刻判别是否过期,假如获取的时刻仍然是过期的,那就阐明拿到锁了。

假如没有,则阐明在效劳2履行getset之前,效劳器3或许也发现锁过期了,并且在效劳器2之前履行了getset操作,从头设置了过母亲和孩子期时刻。

那么效劳器2就需求抛弃后续的操作,持续等候效劳器3开释锁或许去监测key的有效期是否过期。

这块其实有一个关于分布式锁原理-redis分布式锁,zookeeper分布式锁小问题是,效劳器3现已修改了有效期,拿到锁之后,效劳器2,也修改了有效期,可是没能拿到锁,可是这个有效期的时刻现已被在效劳器3的根底上有添加一些,可是这种影响其实仍是很小的,简直能够忽略不计。

3.2,为什么zookeeper能够完结分布式锁?

百度百科是这么介绍的:ZooKeeper是一个分布式的,开放源码的分布式运用程序和谐效劳,是Google的Chubby一个开源的完结,是Hadoop和Hbase的重要组件。

那关于咱们初度知道的人,能够了解成ZooKeeper就像是咱们的电脑文件体系,咱们能够在d盘中创立文件夹a,并且能够持续在文件夹a中创立 文件夹a1,a2。

那咱们的文件体系有什么特色??那便是同一个目录下文件名称不能重复,相同ZooKeeper也钱伟红蜀汉英雄传修改器是这样的。

在ZooKeeper一切的节点,也便是文件夹称作 Znode,并且这个Znode节点是能够存储数据的。

咱们能够经过“ create /zkjjj nice” 来创立一个节点,这个指令就表明,在跟目录下创立一个zkjjj的节点,值是nice。相同这儿的值,和我在前面说太傅宠妻写实的redis中的相同,没什么含义,小振平你随便给。

别的ZooK嗯啊唔eeper能够创立4种类型的节点,分别是:

1,持久性节点

2,持久性次序节点

3,暂时性节点

4,暂时性次序节点

首要说下持久性节点和暂时性节点的差异,持久性节点表明只需你创立了这个节点,那不管你ZooKeepe张民弢r的客户端是否断开衔接,ZooKeeper的效劳端都会记载这个节点。

暂时性节点刚好相反,一旦你ZooKeeper客户端断开了衔接,那ZooKeeper效劳端就不再保存这个节点。

再说下次序性节点,次序性节点是指,在创立节点的时分,ZooKeeper会主动给节点编号比方0000001 ,0000002 这种的。

终究说下,zookeeper有一个监听机制,客户端注册监听它关怀的目录节点,当目录节点发作改变(数据改动、被删去、子目录节点添加删去)等,zookeeper会告诉客户端。

下面咱们持续结合咱们上面的分红包场景,描绘下在zookeeper中怎么加锁。

假定效劳器1,创立了一个节点 /zkjjj ,成功了,那效劳器1就获取了锁,效劳器2再去创立相同的锁,那么他就会失利,这个时分他就就只能监听这个节点的改变。

比及效劳器1,处理完事务,删去了节点后,他就会得关于分布式锁原理-redis分布式锁,zookeeper分布式锁到告诉,然后去创立相同的节点,获取锁处理事务,再删去节点,后续的100台效劳器与之相似

留意这儿的100台效劳器并不是挨个去履行上面的创立节点的操作,而是并发的,当效劳器1创立成功,那么剩余的99个就都会注册监听这个节点,等告诉,以此类推。

可是咱们有没有留意到,这儿仍是有问题的,仍是会有死锁的状况存在,对不对?

当效劳器1创立了节点后挂了,没能删去,那其他99台效劳器就会一向等告诉,那就完蛋了。。。

这个时分呢,就需求用到暂时性节点了,咱们前面说过了,暂时性节点的特色是客户端一旦断开,就会丢掉,也便是当效劳器1创立了节点后,假如挂了。

那这个节点会主动被删去,这样后续的其他效劳器,就能够持续去创立节点,获取锁了。

可是咱们或许还需求留意到一点,便是惊群效应:举一个很简略的比如,当你往一群鸽子中心扔一块食物,尽管终究只需一个鸽子抢到食物,但一切鸽子都会被惊扰来抢夺,没有抢到..

便是当关于分布式锁原理-redis分布式锁,zookeeper分布式锁效劳器1节点有关于分布式锁原理-redis分布式锁,zookeeper分布式锁改变,会告诉其他的99个效劳器,可是终究只需1个效劳器会创立成功,这样98仍是需求等候监听,那么为了处理这种状况,就需求用到暂时次序性节点

大致意思便是,之前是一切99个效劳器都监听一个节点,现在便是每一个效劳器监听自己前面的一个节点。

假定100个效劳器一同发来恳求,这个时分会在 /zkjjj 节点下创立 100 个暂时次序性节点 /zkjjj/000000001, /zkjjj/000000002,一向到 /zkjjj/000000100,这个编号就等所以现已给他们设置了获取锁的先后次序了。

当001节点处理结束,删去节点后,002收到告诉,去获取锁,开端履行,履行结束,删去节点,告诉003~以此类推。

有好的文章希望我们帮助分享和推广,猛戳这里我要投稿

返回列表
上一篇:
下一篇: