北京奥运会男篮冠军

admin · 2016-09-01

1.导语

  正在营业开荒中像订单写入,正常需求单线程来包管订单写入数据库,防备数据屡次被拔出。

  近来,有两台容器,当次序运转时,会发送众份通告,那末需求包管同暂时刻只要一个过程(一台容器)来运转,此时用散布式锁处理该成绩。

  业界也有很众处理这类计划,这里以redis散布式锁来处理。

  简朴来讲便是采取golang redis库完成上面计划便可。

   2.redis的散布式锁完成

  2.1 setnx+expire

  setnx key value,将key配置为value,当键不存正在时,才调告捷,若键存正在,甚么也不做,告捷前往1,障碍前往0。

  SETNX本质上便是SET IF NOT Exists的缩写。

  

setnxkeyvalexpirekeyseconds

 

  然而,上述两个操纵不拥有原子性,即使实施完第一条指令利用卓殊或许重启了,锁将无奈过时。

  2.2 lua剧本

  既然是原子性无奈包管,那就采取实施lua剧本的原子性,将上述两个操纵封装到lua剧本中便能够完成。

  

ifredis.call(setnx,KEYS[1],ARGV[1])==1thenredis.call(expire,KEYS[1],ARGV[2])elsereturn0end;

 

  2.3 带领TTL的set

  从 Redis 2.6.12 版本先导, SET 号令的举止能够经由过程一系列参数来改正。

  

SETkeyvalue[EXseconds][PXmilliseconds][NX

 

  将字符串值 value 闭系到 key 。

  即使 key 一经持有其余值, SET 就覆写旧值,渺视范例。

  关于某个原来带有生活年光(TTL)的键来讲, 当 SET 号令告捷正在这个键上实施时, 这个键原有的 TTL 将被铲除。

   EX second :配置键的过时年光为 second 秒。SET key value EX second 后果同等于 SETEX key second value 。 PX millisecond :配置键的过时年光为 millisecond 毫秒。SET key value PX millisecond 后果同等于 PSETEX key millisecond value 。 NX :只正在键不存正在时,才对键举办配置操纵。SET key value NX 后果同等于 SETNX key value 。 XX :只正在键一经存正在时,才对键举办配置操纵。

  直接利用或许存正在如下成绩:

   超时解锁招致并发

  比方:即使线程 A 告捷获取锁并配置过时年光 30 秒,但线程 A 实施年光越过了 30 秒,锁过时主动开释,此时线程 B 获取到了锁,线程 A 和线程 B 并发实施。

  A、B 两个线程产生并出现显是不被答应的,正常有两种方法处理该成绩:

  处理计划:1)确保代码正在过时年光以前开释。2)为获取锁的线程扩张保卫线程,为将要过时但未开释的锁扩张有用年光。

  锁被其余线程误删除。

  比方:即使线程 A 告捷获取到了锁,而且配置了过时年光 30 秒,但线程 A 实施年光越过了 30 秒,锁过时主动开释,此时线程 B 获取到了锁;随后 A 实施落成,线程 A 利用 DEL 号令来开释锁,但此时线程 B 加的锁尚未实施落成,线程 A 本质开释的线程 B 加的锁。

  处理计划是:经由过程正在 value 中配置方今列程加锁的标识,正在删除以前验证 key 对应的 value 判决锁是不是方今列程持有。可天生一个 UUID 标识方今列程,利用 lua 剧本做验证标识息争锁操纵。

  进修著作:

  https://xiaomi-info.github.io/2019/12/17/redis-distributed-lock/

  https://zhuanlan.zhihu.com/p/115848078

文章推荐:

nba2k18传奇版

cba2k巨星时刻

nba2k11没声音

大赢家篮球比分