浅谈分布式锁.docxVIP

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
浅谈分布式锁 2021-02-12 前言 随着互联网技术的不断进展,数据量的不断添加,业务规律日趋简单,在这种背景下,传统的集中式系统已经无法满足我们的业务需求,分布式系统被应用在更多的场景,而在分布式系统中访问共享资源就需要一种互斥机制,来防止彼此之间的相互干扰,以保证全都性,在这种情况下,我们就需要用到分布式锁。 分布式全都性问题 首先我们先来看一个小例子: 假设某商城有一个商品库存剩10个,用户A想要买6个,用户B想要买5个,在抱负形态下,用户A先买走了6了,库存削减6个还剩4个,此时用户B应当无法购买5个,给出数量不足的提示;而在真实情况下,用户A和B同时猎取到商品剩10个,A买走6个,在A更新库存之前,B又买走了5个,此时B更新库存,商品还剩5个,这就是典型的电商“秒宰”活动。 从上述例子不难看出,在高并发情况下,假如不做处理将会消灭各种不行预知的后果。那么在这种高并发多线程的情况下,处理问题最有效最普遍的方法就是给共享资源或对共享资源的操作加一把锁,来保证对资源的访问互斥。在Java JDK已经为我们供应了这样的锁,利用ReentrantLcok或者synchronized,即可达到资源互斥访问的目的。但是在分布式系统中,由于分布式系统的分布性,即多线程和多进程并且分布在不同机器中,这两种锁将得到原有锁的效果,需要我们本人实现分布式锁——分布式锁。 分布式锁需要具备哪些条件 1. 猎取锁和释放锁的功能要好 2. 推断能否获得锁必需是原子性的,否则可能导致多个恳求都猎取到锁 3. 网络中缀或宕机无法释放锁时,锁必需被清楚,不然会发生死锁 4. 可重入一个线程中可以多次猎取同一把锁,比如一个线程在执行一个带锁的方法,该方法中又调用了另一个需要相同锁的方法,则该线程可以直接执行调用的方法,而无需重新获得锁; 5.堵塞锁和非堵塞锁,堵塞锁即没有猎取到锁,则连续等待猎取锁;非堵塞锁即没有猎取到锁后,不连续等待,直接前往锁失败。 分布式锁实现方式 一、数据库锁 1. 基于MySQL锁表 该实现方式完全依靠数据库独一索引来实现,当想要获得锁时,即向数据库中插入一条记录,释放锁时就删除这条记录。这种方式存在以下几个问题: (1) 锁没有失效时间,解锁失败会导致死锁,其他线程无法再猎取到锁,由于独一索引insert都会前往失败。 (2) 只能是非堵塞锁,insert失败直接就报错了,无法进入队列进行重试 (3) 不行重入,同一线程在没有释放锁之前无法再猎取到锁 2. 接受乐观锁添加版本号 依据版本号来推断更新之前有没有其他线程更新过,假如被更新过,则猎取锁失败。 二、缓存锁 这里我们次要引见几种基于redis实现的分布式锁: 1. 基于setnx、expire两个命令来实现 基于setnx(set if not exist)的特点,当缓存里key不存在时,才会去set,否则直接前往false。假如前往true则猎取到锁,否则猎取锁失败,为了防止死锁,我们再用expire命令对这个key设置一个超时时间来避开。但是这里看似完善,实则有缺陷,当我们setnx成功后,线程发生特别中缀,expire还没来的及设置,那么就会产生死锁。 处理上述问题有两种方案 第一种是接受redis2.6.12版本以后的set,它供应了一系列选项 EX seconds – 设置键key的过期时间,单位时秒 PX milliseconds – 设置键key的过期时间,单位时毫秒 NX – 只要键key不存在的时候才会设置key的值 XX – 只要键key存在的时候才会设置key的值 其次种接受setnx(),get(),getset()实现,大体的实现过程如下: (1) 线程Asetnx,值为超时的时间戳(t1),假如前往true,获得锁。 (2) 线程B用get 命令猎取t1,与当前时间戳比较,推断能否超时,没超时false,假如已超时执行步骤3 (3) 计算新的超时时间t2,使用getset命令前往t3(这个值可能其他线程已经修改过),假如t1==t3,获得锁,假如t1!=t3说明锁被其他线程猎取了 (4) 猎取锁后,处理完业务规律,再去推断锁能否超时,假如没超时删除锁,假如已超时,不用处理(防止删除其他线程的锁) 2. RedLock算法 redlock算法是redis作者推举的一种分布式锁实现方式,算法的内容如下: (1) 猎取当前时间; (2) 尝试从5个相互独立redis客户端猎取锁; (3) 计算猎取全部锁消耗的时间,当且仅当客户端从多数节点猎取锁,并且猎取锁的时间小于锁的有效时间,认为获得锁; (4) 重新计算有效期时间,原有效时间减去猎取锁消耗的时间; (5) 删除全部实例的锁 redlock算法相对于单节点redis锁牢靠性要更

文档评论(0)

duanbingbing + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档