按照自己的理解写口水子话,有错请指正。
场景一
现在数据库的一张表有一条数据,里面有个字段istrue=true,假设用来判断是否给作者1个亿(=true就给)。现在有俩个公司(为服务器)。他们从数据库拿出这条数据,然后根据istrue来判断给我一个亿。给我钱后,把istrue设置为false,以后拿出来再判断的时候就不会给钱了。但是现在一个公司去请求这条数据,发现为true,就准备给我钱,此时另一家公司也去拿到了这条数据,因为我和前一家公司还在交易数钱,还没有成功所以不会修改数据库这条数据的状态,导致后面来的这家公司拿到的istrue也是等于true.所以这家公司也需要给我一个亿,这样我就拿到了2个亿,公司就不干了啊,所以需要一个锁。
场景二
现在为了防止上面的情况,俩个公司决定加一个锁,但是这个锁必须要有一些特性。第一原子性:简单理解就是如果俩个公司一起加锁,必须保证只能有一个公司加锁成功,不然俩个公司都成功了,他们都以为自己是拿到锁的那个人,最后还是要给我2个亿。第二过期时间:本来的逻辑是得到锁的公司,再把钱给了我,把数据库的istrue的状态修改了,然后释放锁,但是不正常的逻辑就是这家公司上锁了,但是中途挂了,发现拿不出1个亿跑路了,带着锁的钥匙跑路了,另一家公司本来有1个亿,但是没钥匙,一直卡在外面,我就拿不到一分钱,所以我就不干了啊。所以必须给这个锁加一个过期时间,你半小时还没给我转账打钱,我就把这个锁撬了,让他失效。这时候,神器出现了,Redis.它具有原子性:单一的线程,内部串行执行,加锁的时候还可以设置过期时间。有人会问了:万一我加锁成功,但是设置过期时间的时候挂了怎么办,还不是最后拿不到钱。不用担心,Redis的命令setnx帮助我们解决,它加锁设置过期时间一起的具有原子性,要不都成功,要不都失败。不会有第三种情况。
场景三
上面有了神器,但是我们知道Redis一般是集群(保证Redis的高可用,提高Redis的读写性能),怎么理解呢?假设现在是3台redis组成的集群。
然后现在来个一个请求(带着一个key为“简书”),需要redis集群你把这个“简书”资源给我锁上,然后Redis按照请求的要求给你锁上,并存在了3台redis中的一台。现在来了另外一个请求,它也带着(一个key为“简书”),它也要求Redis集群给我锁上,可是会出现一个问题,就是Redis在判断这个名为“简书”的资源是否有加锁的时候,它刚好没去存了key的那台机器上判断,就导致了误判。这时候前面的加锁就毫无意义了呀。所以我们就需要相同的key值必须命中同一台redis,(前提是这台Redis没有挂掉)。所以就有了Hash一致性算法这个算法我们另外写学习,假设现在我们有了这个功能了,相同的key会命中同一台机器。这样我们就解决了Redis是集群的问题。
场景四
上面的场景已经差不多了,但是还有毛病,人人都是挂掉的时候,机器也不例外啊,现在同样来了一个请求(带着一个key为“简书”),Redis加了这个锁,然后告诉这个请求方,我加锁成功了,你可以打钱了,请求方收到后就准备给我打钱了,但是很不巧,Redis刚好成功告诉可以打钱了,然后就挂掉了。现在来个另一家公司的另外一个请求(带着一个key为“简书”),本来是命中那个挂掉的机器,但是它挂了,所以,为了高可用,Redis集群肯定有应急方案的(也就是一致性Hash算法的容错性和可扩展性),暂时后面学习,Redis就会把这个key存在另外的机器上,这就导致了原本加锁的意义也没有了,最后还是给我打了2个亿。这时候不要慌,这种情况redis作者给我们考虑了,提出了RedLock红锁的算法,在redisson中也对红锁进行了实现。会用redisson就行
redisson使用手册:[点我跳转下载]https://cloud.189.cn/t/VveuuiAJBf2y (访问码:uq2t)
redlock算法大概是这样的:
客户端需要进行的操作:
1、获取当前时间(单位是毫秒)。
2、轮流用相同的key和随机值在N个节点上请求锁,在这一步里,客户端在每个master上请求锁时,会有一个和总的锁释放时间相比小的多的超时时间。比如如果锁自动释放时间是10秒钟,那每个节点锁请求的超时时间可能是5-50毫秒的范围,这个可以防止一个客户端在某个宕掉的master节点上阻塞过长时间,如果一个master节点不可用了,我们应该尽快尝试下一个master节点。
3、客户端计算第二步中获取锁所花的时间,只有当客户端在大多数master节点上成功获取了锁(在这里是3个),而且总共消耗的时间不超过锁释放时间,这个锁就认为是获取成功了。
4、如果锁获取成功了,那现在锁自动释放时间就是最初的锁释放时间减去之前获取锁所消耗的时间。
5、如果锁获取失败了,不管是因为获取成功的锁不超过一半(N/2+1)还是因为总消耗时间超过了锁释放时间,客户端都会到每个master节点上释放锁,即便是那些他认为没有获取成功的锁。












网友评论