自动草稿

甚么是分布式控制系统锁?

我们好,我是jack xu,那时跟我们聊一聊分布式控制系统锁。具体而言说下甚么是分布式控制系统锁,当他们在进行下订货减库存量,抢票,选课,T246这些销售业务情景时,如果在该处没锁的掌控,会引致很轻微的问题。段小宇多处理器的小伙子们知道,为的是防止数个内存同时继续执行同几段标记符,他们可以用 synchronized URL或 JUC 里头的 ReentrantLock Canillac掌控,但目前基本上任何人两个控制系统都是布署几台电脑的,FPS布署的应用领域极少,synchronized 和 ReentrantLock 充分发挥不出任何人促进作用,这时就须要两把自上而下的锁,来替代 JAVA 中的 synchronized 和 ReentrantLock。

分布式控制系统锁的同时实现形式盛行的主要就有四种,依次是如前所述内存 Redis 的同时实现形式,如前所述 zk 临时性次序结点的同时实现以及如前所述资料库行锁的同时实现。他们先而言下该 Jedis 中的 setnx 指示来构筑这把锁。

Jedis读法

采用 Redis 做分布式控制系统锁的路子是,在 redis 中增设两个值表示加了锁,接着释放出来锁的这时候就把这个 key 删掉。路子是很单纯,但在采用操作过程上要防止一些坑,他们先看下上锁的标记符:

/**
* 试著以获取分布式控制系统锁
*
*@paramjedis Redis应用领域程序
*@paramlockKey 锁
*@paramrequestId 允诺标记
*@paramexpireTime Jamnagar天数
*@return与否以获取获得成功
*/
publicstaticbooleantryGetDistributedLock(Jedis jedis, String lockKey, String requestId,intexpireTime){// set全力支持数个模块 NX(not exist) XX(exist) EX(seconds) PX(million seconds)String result = jedis.set(lockKey, requestId,“NX”,“EX”, expireTime);if(LOCK_SUCCESS.equals(result)) {returntrue;
}returnfalse;
}

这段标记符很单纯,主要就说下这儿用的指示是 SET key value [EX seconds|PX milliseconds] [NX|XX] [KEEPTTL],而没采用 SETNX EXPIRE 的指示,原因是 SETNX EXPIRE 是两条指示无法保证原子性,而 SET 是原子操作。那这儿为甚么要增设超时天数呢?原因是当两个应用领域程序获得了锁在继续执行任务的操作过程中挂掉了,来不及显式地释放出来锁,这块资源将会永远被锁住,这将会引致死锁,所以必须增设两个超时天数

释放出来锁的标记符如下:

/**
* 释放出来分布式控制系统锁
*
*@paramjedis Redis应用领域程序
*@paramlockKey 锁
*@paramrequestId 允诺标记,当前工作内存内存的名称
*@return与否释放出来获得成功
*/
publicstaticboolean releaseDistributedLock(Jedis jedis,StringlockKey,StringrequestId) {Stringscript =“if redis.call(get, KEYS[1]) == ARGV[1] then return redis.call(del, KEYS[1]) else return 0 end”;Objectresult = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));if(RELEASE_SUCCESS.equals(result)) {returntrue;
}returnfalse;
}

这儿也有两点注意的地方,第一是解铃还须系铃人,怎么理解呢,就是 A 加的锁 B 不能去 del 掉吧,不然岂不是全乱套了,谁加的锁就谁去解,他们一般把 value 设为当前内存的 Id,Thread.currentThread().getId(),接着在删的这时候判断下是不是当前内存。第二点是验证和释放出来锁是两个独立操作,不是原子性,这个怎么解决呢?采用 Lua 脚本,即 if redis.call(get, KEYS[1]) == ARGV[1] then returnredis.call(del, KEYS[1]) else return 0 end,它能给他们保证原子性。

Redisson读法

Redisson 是 Java 的 Redis 应用领域程序之一,提供了一些 API 方便操作 Redis。但 Redisson 这个应用领域程序可有点厉害,他们先打开官网看下 github.com/redisson/re…

这个目录里头有很多的功能,Redisson 跟 Jedis 定位不同,它不是两个单纯的 Redis 应用领域程序,而是如前所述 Redis 同时实现的分布式控制系统的服务,他们可以看到还有 JUC 包下面的类名,Redisson 帮他们搞了分布式控制系统的版本,比如 AtomicLong,直接用 RedissonAtomicLong 就行了。锁只是它的冰山一角,并且它对主从,哨兵,集群等模式都全力支持,当然了,单结点模式肯定是全力支持的。

在 Redisson 里头提供了更加单纯的分布式控制系统锁的同时实现,他们来看下它的用法,相当的单纯,两行标记符搞定,比 Jedis 要单纯的多,而且在 Jedis 里须要考虑的问题,它都已经帮他们封装好了。

他们来看下,这儿以获取锁有很多种的形式,有公平锁有读写锁,他们采用的是 redissonClient.getLock, 这是两个可重入锁。

现在我把程序启动一下

打开 Redis Desktop Manager 工具,看下到底它存的是甚么。原来在上锁的这时候,写入了两个 HASH 类型的值,key 是锁名称 jackxu,field 是内存的名称,而 value 是 1(即表示锁的重入次数)。

小伙子伴可能觉得我在一派胡言,没关系,他们点进去看下它的源码是具体同时实现的。

点进 tryLock() 方法的 tryAcquire() 方法,再到-

1.本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
2.分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
3.不得使用于非法商业用途,不得违反国家法律。否则后果自负!
4.本站提供的源码、模板、插件等其他资源,都不包含技术服务请大家谅解!
5.如有链接无法下载或失效,请联系管理员处理!
6.本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!