当前位置: 首页 > news >正文

网站需要哪些东西友情链接交换平台有哪些

网站需要哪些东西,友情链接交换平台有哪些,贵阳的网站建设公司,去哪个网站做农产品推广分布式锁的实现有哪些? 1.Memcached分布式锁 利用Memcached的add命令。此命令是原子操作,只有在key不存在的情况下,才能add成功,也就意味着线程得到了锁。 2.Reids分布式锁 和Memcached的方式类似,利用Redis的setn…

image

image

image

image

image

image

image

image

分布式锁的实现有哪些?

1.Memcached分布式锁

利用Memcached的add命令。此命令是原子操作,只有在key不存在的情况下,才能add成功,也就意味着线程得到了锁。

2.Reids分布式锁

和Memcached的方式类似,利用Redis的setnx命令。此命令同样是原子性操作,只有在key不存在的情况下,才能set成功。(setnx命令并不完善,有替代方案)

3.Zookeeper分布式锁

利用Zookeeper的顺序临时节点,来实现分布式锁和等待队列。Zookeeper设计的初衷,就是为了实现分布式锁服务的。

4.Chubby

Google公司实现的粗粒度分布式锁服务,底层利用了Paxos一致性算法。

如何用Redis实现分布式锁?(以Redis为例)

分布式锁实现的三个核心要素:

1.加锁

最简单的方法是使用setnx命令。key是锁的唯一标识,按业务来决定命名。比如想要给一种商品的秒杀活动加锁,可以给key命名为“lock_sale_商品ID”。而value设置成什么呢?我们先设置为1。加锁的伪代码如下:

setnx(key,1)

当一个线程执行setnx返回1,说明key原本不存在,该线程成功得到了锁;当一个线程执行setnx返回0,说明key已经存在,该线程抢锁失败。

2.解锁

有加锁就有解锁。当得到锁的线程执行完任务,需要释放锁,以便其他线程进入。释放锁的最简单方式是执行del指令,伪代码如下:

del(key)

释放锁之后,其他线程就可以继续执行setnx命令来获得锁。

3.锁超时

如果一个得到锁的线程在执行任务的过程中挂掉,来不及显式地释放锁,这块资源将会永远被锁住,别的线程再也别想进来。

所以,setnx的key必须设置一个超时时间,以保证即使没有被显式释放,这把锁也要在一定的时间后自动释放。setnx不支持超时参数,所以需要额外的指令,伪代码如下:

expire(key,30)

综上所述,实现分布式锁的伪代码如下:

if(setnx(key,1) == 1){expire(key,30)try{do something...}finally{del(key)}
}

但是…这样会有其他问题吗?

image

上面的伪代码存在三个致命的问题:

1.setnx和expire的非原子性

设想一个极端场景,当某线程执行setnx,成功得到了锁:
image

setnx刚执行成功,还未来得及执行expire指令,节点1Duang的一声挂掉了

image

这样一来,这把锁就没有设置过期时间,变得“长生不老”,别的线程再也无法获得锁了。

如何解决?setnx指令本身是不支持传入超时时间的,幸好Redis2.6.12以上版本为set指令增加了可选参数,伪代码如下:

set(key,1,30,NX)

这样就可以取代setnx指令

2.del导致误删

又一个极端场景,假如某线程成功得到了锁,并且设置的超时时间是30秒。

image

如果某些原因导致线程B执行的很慢很慢,过了30秒都没执行完,这时候锁过期自动释放,线程B得到了锁。

image

随后,线程A执行完了任务,线程A接着执行del指令来释放锁。但这时候线程B还没执行完,线程A实际上删除的是线程B加的锁

image

如何避免这种情况呢?可以在del释放锁之前做一个判断,验证当前的锁是不是自己加的锁。

具体的实现,可以在加锁的时候把当前线程ID当做value,并在删除之前验证key的value是不是自己线程的ID。

加锁:

String threadId = Thread.currentThread().getId()
set(key,threadId,30,NX)

解锁:

if(threadId.equals(redisClient.get(key))){del(key)
}

但是这样做又隐含了一个新的问题,判断和释放锁是两个独立操作,不是原子性

所以这块可以用Lua脚本来实现:

String luaScript = 'if redis.call('get',KEYS[1]) == ARGV[1] then returnredis.call('del',KEYS[1]) else return 0 end';redisClient.eval(luaScript,Collections.singletonList(key),Collections.singltonList(threadId));

这样一来,验证和删除过程就是原子操作了。

3.出现并发的可能性

第二点的场景中,虽然我们避免了线程A误删掉key的情况,但是同一时间有A、B两个线程在访问代码块,仍然不完美。

如何解决呢?我们可以让获得锁的线程开启一个守护线程用来给快过期的锁“续航”

image

当过去了29秒,线程A还没有执行完,这时候守护线程会执行expire指令,为这把锁“续命”20秒,守护线程从第29秒开始,每20秒执行一次。

image

当线程A执行完任务,会显式关掉守护线程。

image

另一种情况,如果节点1忽然断电,由于线程A和守护线程在同一个进程,守护线程也会停下。这把锁到了超时的时候,没人给它续命,也就自动释放了。

image

http://www.ritt.cn/news/9638.html

相关文章:

  • Wordpress 域名授权插件seo服务外包客服
  • 网站左右箭头素材百度关键词推广工具
  • 同时优化几个网站站内关键词自然排名优化
  • 学美工难吗东莞seo排名外包
  • 长沙做网站排名杭州余杭区抖音seo质量高
  • 扁平化风格 网站seo关键词选择及优化
  • 网站平台选择百度下载安装
  • 百度 特定网站搜索企业seo如何优化
  • 羊肉口报关做网站南宁网络推广有限公司
  • php做网站的技术难点山东济南seo整站优化费用
  • wordpress 仿糗百seo公司怎么样
  • 怎么做网站文件验证宁波网络推广平台
  • 4399小游戏网页版在线玩江北seo页面优化公司
  • 成都php网站建设百度推广的定义
  • 网站建设优化佛山河南网站推广电话
  • 尉氏网站建设网页推广方案
  • 徐州网站建设哪家好刷外链
  • 家装设计网页版qq群排名优化软件
  • 广州专业网站设计当前疫情十大热点
  • 江北区城乡建设部网站首页提高网站排名
  • 内蒙古自治区党风廉政建设网站深圳龙岗区优化防控措施
  • 网站开发计划书范文百度在线识别图片
  • 在线购物网站的设计宁波seo整站优化软件
  • 网站用oracle做数据库开展网络营销的企业
  • 创造与魔法官方网站做自己友情链接可以随便找链接加吗
  • 万维网的网站数字营销策略有哪些
  • 棋牌游戏在哪做网站上海发布最新情况
  • wordpress搭建的网站能干什么新闻头条最新消息
  • 旅游网站的功能有哪些如何做好推广引流
  • 中天建设集团有限公司西南分公司二十条优化疫情措施