关系经济人类预测化学自然
中准网
自然科学
知识物理
化学生物
地理解释
预测理解
本质社会
人类现象
行为研究
经济政治
心理结构
关系指导
人文遗产

终于懂什么是分布式锁

4月8日 望北海投稿
  为什么要有分布式锁?
  模拟一个秒杀接口:
  商品表:
  单机情况下,用Jmeter发送1000个请求过来:
  由于加了sychronized进行方法同步,结果正常。
  现在模拟集群环境,还是用上面的接口,但启动两个服务,分别是8080和8081端口,用nginx负载均衡到两个tomcat,用Jmeter发送1000个请求到nginx:
  发现库存并没有1000,并且控制的库存量打印有重复。
  结论:
  我们在系统中修改已有数据时,需要先读取,然后进行修改保存,此时很容易遇到并发问题。由于修改和保存不是原子操作,在并发场景下,部分对数据的操作可能会丢失。在单服务器系统我们常用本地锁来避免并发带来的问题,然而,当服务采用集群方式部署时,本地锁无法在多个服务器之间生效,这时候保证数据的一致性就需要分布式锁来实现。MySql分布式锁
  基于数据库的分布式锁,常用的一种方式是使用表的唯一约束特性。当往数据库中成功插入一条数据时,代表只获取到锁。将这条数据从数据库中删除,则释放锁。CREATETABLEdatabaselock(idBIGINTNOTNULLAUTOINCREMENT,resourcevarchar(1024)NOTNULLDEFAULTCOMMENT资源,lockidvarchar(1024)NOTNULLDEFAULTCOMMENT唯一锁编码,countint(11)NOTNULLDEFAULT0COMMENT锁的次数,可重入锁,PRIMARYKEY(id),UNIQUEKEYuiqlockid(lockid))ENGINEInnoDBDEFAULTCHARSETutf8mb4COMMENT数据库分布式锁表;
  当我们想要获得锁时,可以插入一条数据
  INSERTINTOdatabaselock(resource,lockid,count)VALUES(resource,lockid,1);
  注意:在表databaselock中,lockid字段做了唯一性约束,可以是机器的mac地址线程编号,这样如果有多个请求同时提交到数据库的话,数据库可以保证只有一个操作可以成功(其它的会报错:ERROR1062(23000):Duplicateentry‘1’forkey‘uiqlockid’),那么我们就可以认为操作成功的那个请求获得了锁。
  当需要释放锁的时,可以删除这条数据:
  DELETEFROMdatabaselockwheremethodnameresourceandcustidlockid
  可重入锁:
  UPDATEdatabaselockSETcountcount1WHEREmethodnameresourceANDcustidlockid
  伪代码:publicvoidtest(){SSif(!checkReentrantLock(resource,lockid)){lock(resource,lockid);加锁}else{reentrantLock(resource,lockid);可重入锁1}业务处理unlock(resource,lockid);释放锁}
  这种实现方式非常的简单,但是需要注意以下几点:这种锁没有失效时间,一旦释放锁的操作失败就会导致锁记录一直在数据库中,其它线程无法获得锁。这个缺陷也很好解决,比如可以做一个定时任务去定时清理。这种锁的可靠性依赖于数据库。建议设置备库,避免单点,进一步提高可靠性。这种锁是非阻塞的,因为插入数据失败之后会直接报错,想要获得锁就需要再次操作。如果需要阻塞式的,可以弄个for循环、while循环之类的,直至INSERT成功再返回。这种锁也是非可重入的,因为同一个线程在没有释放锁之前无法再次获得锁,因为数据库中已经存在同一份记录了。想要实现可重入锁,可以在数据库中添加一些字段,比如获得锁的主机信息、线程信息等,那么在再次获得锁的时候可以先查询数据,如果当前的主机信息和线程信息等能被查到的话,可以直接把锁分配给它。Redis分布式锁
  Redis锁主要利用Redis的setnx命令。加锁命令:SETNXkeyvalue,当键不存在时,对键进行设置操作并返回成功,否则返回失败。KEY是锁的唯一标识,一般按业务来决定命名。解锁命令:DELkey,通过删除键值对释放锁,以便其他线程可以通过SETNX命令来获取锁。锁超时:EXPIREkeytimeout,设置key的超时时间,以保证即使锁没有被显式释放,锁也可以在一定时间后自动释放,避免资源被永远锁住。if(setnx(key,1)1){expire(key,30)try{TODO业务逻辑}finally{del(key)}}
  使用SpingBoot集成Redis后使用分布式锁:
  可以看到打印的日志不再有重复的库存量,最小的库存量与数据库中的一致。
  Redis分布式锁可能存在一些问题:
  1。设置过期时间
  A客户端获取锁成功,但是在释放锁之前崩溃了,此时该客户端实际上已经失去了对公共资源的操作权,但却没有办法请求解锁(删除KeyValue键值对),那么,它就会一直持有这个锁,而其它客户端永远无法获得锁。
  在加锁时为锁设置过期时间,当过期时间到达,Redis会自动删除对应的KeyValue,从而避免死锁。
  2。SETNX和EXPIRE非原子性
  如果SETNX成功,在设置锁超时时间之前,服务器挂掉、重启或网络问题等,导致EXPIRE命令没有执行,锁没有设置超时时间变成死锁。Redis2。6。12之后Redis支持nx和ex操作是同一原子操作。
  3。锁误解除
  如果线程A成功获取到了锁,并且设置了过期时间30秒,但线程A执行时间超过了30秒,锁过期自动释放,此时线程B获取到了锁;随后A执行完成,线程A使用DEL命令来释放锁,但此时线程B加的锁还没有执行完成,线程A实际释放的线程B加的锁。
  通过在value中设置当前线程加锁的标识,在删除之前验证key对应的value判断锁是否是当前线程持有。可生成一个UUID标识当前线程
  4。超时解锁导致并发
  如果线程A成功获取锁并设置过期时间30秒,但线程A执行时间超过了30秒,锁过期自动释放,此时线程B获取到了锁,线程A和线程B并发执行。
  一般有两种方式解决该问题:
  将过期时间设置足够长,确保代码逻辑在锁释放之前能够执行完成。
  为获取锁的线程增加守护线程,为将要过期但未释放的锁增加有效时间。
  更好的方法是是使用Redission,WatchDog机制会为将要过期但未释放的锁增加有效时间。
  5。redis主从复制
  A客户端在Redis的master节点上拿到了锁,但是这个加锁的key还没有同步到slave节点,master故障,发生故障转移,一个slave节点升级为master节点,B客户端也可以获取同个key的锁,但客户端A也已经拿到锁了,这就导致多个客户端都拿到锁。
  使用RedLock
  首先生成多个Redis集群的Rlock,并将其构造成RedLock。如果循环加锁的过程中加锁失败,那么需要判断加锁失败的次数是否超出了最大值,这里的最大值是根据集群的个数,比如三个那么只允许失败一个,五个的话只允许失败两个,要保证多数成功。加锁的过程中需要判断是否加锁超时,有可能我们设置加锁只能用3ms,第一个集群加锁已经消耗了3ms了。那么也算加锁失败。2,3步里面加锁失败的话,那么就会进行解锁操作,解锁会对所有的集群在请求一次解锁。
  可以看见RedLock基本原理是利用多个Redis集群,用多数的集群加锁成功,减少Redis某个集群出故障,造成分布式锁出现问题的概率。ZooKeeper分布式锁
  1。多个客户端创建一个锁节点下的一个接一个的临时顺序节点
  2。如果自己是第一个临时顺序节点,那么这个客户端加锁成功;如果自己不是第一个节点,就对自己上一个节点加监听器
  3。当某个客户端监听到上一个节点释放锁,自己就排到前面去了,此时继续执行步骤2,相当于是一个排队机制。
  使用Curator框架进行加锁和释放锁
  来源:
  https:segmentfault。coma1190000038330434
投诉 评论 转载

支付平台主动参与健康支付习惯与环境的养成文杨生成无现金社会是眼下的热点话题,但无现金社会并非完全不用现金。某些支付平台炒作无现金社会概念,是一种过度的宣传,完全的非现金无现金并不符合经济的规律。移动支付日……为什么不等华为P60直接入手Mate50?内行人说出三个原因国内的手机品牌比较多还就是有一定的好处,就在前两个月骁龙8Gen2旗舰扎堆发布之后,国内的新旗舰手机还并没有全部发布完,在接下来的半个月之间还将有几款重磅产品发布,而这些产品笔……华米Amazfit跃我TRex2手表,全天候伙伴终于等到轨迹作为平日总是喜欢在户外折腾的爱好运动人士,对这些年曾经用过的运动装备的吐槽常年不断,续航时间短,定位不够精准,功能不够强大,外观不够好看,恶劣环境下不耐造等,总能找出一两个槽点……火车站常见的举牌大妈住宿一晚仅需30元?过来人满是套路在出远门的时候,大多数国人们都会选择搭乘火车出行。(此处已添加小程序,请到今日头条客户端查看)因为火车不仅有着较低的票价,而且上面还有着舒适的卧铺可供乘客们休息。值……在地球赤道附近的物体重量会轻,原因是什么?地球作为宇宙的天体之一,也遵循着宇宙的物理法则。我们生活在地球上,对自己的重量都比较关心,想要通过控制重量维持身材,但是同样的物体在地球极地或赤道,重量也会出现变化,这一……北方最适合居住的城市冬天有暖气,夏天不开空调,海景不输三亚北方城市中,如果挑选一个最适合定居的,你会选择哪一个?究竟是最近炙手可热的威海,还是美丽如画的日照;是千年古都洛阳,还是避暑胜地大同。答案都不是,在我心中最接近此标准的是……湿疹我有一方,屡用不爽,今日公之于众【方名】:滋阴除湿汤【来源】:朱仁康《朱仁康临床经验集》【组成】:生地、元参、当归、丹参、茯苓、泽泻、白鲜皮、蛇床子。【主治】:亚急性、慢性、泛发性湿疹、慢性……欧美网友谈JDG夺冠这把的MVP我会给到JDG。JKL2022LPL夏季总决赛,由JDG成功问鼎银龙杯。外网Reddit论坛的网友也对总决赛整个bo5中所有选手的表现做出热议,详细内容如下:JackeyLove就像除了我自己……喉癌怎么预防,有这几个方法喉癌是一种发生在喉部的恶性肿瘤,是可以分为原发性还有继发性两种的,在严重的时候会导致患者死亡,需要及时在日常生活上做到戒烟戒酒,及时治疗慢性炎症,有个良好的环境,避免大声喊叫,……安卓手机好评排行华为Mate50Pro第二,小米12SUlt在先后公布完安卓手机性能榜单和性价比榜单之后,安兔兔近日又总结了一份安卓手机好评TOP10排行榜。这次的好评榜单变化还是挺大的,首先是此前好评榜常客三星,这次没能入选。其次是相……即将在NBA复出的十大代表球员2223的NBA赛季是NBA第76个赛季,将会在10月18日重燃战火,目前各球队和球员都在积极地进行赛季备战,其中亦包括了一些与球迷久违、已经休养很久的NBA球员。在即将……终于懂什么是分布式锁为什么要有分布式锁?模拟一个秒杀接口:商品表:单机情况下,用Jmeter发送1000个请求过来:由于加了sychronized进行方法同步,结果正常。……
CBA三消息辽宁悍将复出暴扣,林书豪化身教练,高诗岩目标夺冠为什么6080岁才是最好的年龄?母鸡驾考攻略实用的个倒车技巧送给倒车难的西北胜迹武威天祝哈溪的壹拾陆号院子是岳钟琪将军的行营踏板车什么牌子好大多数造句用大多数造句大全科学用植物制成的环保塑料,你用过吗?出轨后男人错误的处理方法五种犯傻行为千万别做不孝有三无后为大什么意思不孝有三是哪三种内附详细林萧名言圆管真假鉴别图真真假假轻松辨
体育教学的提问要讲究度不贪杯关于端午节的日记300字5篇“金牌雇主”是企业赢得人才的关键点当事人重伤害缓刑怎么争取汽车电池也能3D打印?这家新晋独角兽不想活在“宁德时代”热评 玩物丧智高考数学解答题答题技巧系统动画比拼!ColorOSMIUI谁更对个你的胃口?barragan什么品牌秋天的美根据真人真事改编,六部法律电影推荐

友情链接:中准网聚热点快百科快传网快生活快软网快好知文好找菏泽德阳山西湖州宝鸡上海茂名内江三亚信阳长春北海西安安徽黄石烟台沧州湛江肇庆鹤壁六安韶关成都钦州