深入理解redis散布式锁和消息队列
最近博主在看redis的时候发现了两种redis使用方式,与之前redis作为缓存区别,利用的是redis可设置key的有效时间和redis的BRPOP命令。
散布式锁
由于目前一些编程语言,如PHP等,不能在内存中使用锁,或如Java这样的,需要一下更加简单的锁校验的时候,redis散布式锁的使用就足够满足了。
redis的散布式锁其实就是基于setnx方法和redis对key可设置有效时间的功能来实现的。基本用法比较简单。
public boolean tryLock(String lock,long expireTime){ String expire = String.valueOf(System.currentTimeMillis() + expireTime + 1); Long result = jedis.setNx(lock,expire); if(result == 1L){ jedis.expire(lock, expireTime); return true; } //判断超时key可能未删掉 String currentValue = jedis.get(lock); if(Long.parseLong(currentValue) < System.currentTimeMillis()){ jedis.set(lock, expire); jedis.expire(lock, expireTime); return true; } return false; } //expire是key的值,这里是为了避免运行超时锁被其他线程拿走以后误删锁 public unlock(String lock,String expire){ String value = jedis.get(lock); if(value != null && value != expire && Long.parseLong(value) > System.currentTimeMillis()) jedis.del(lock); }
这里就是我根据redis的机制写的加锁和解锁方法。现在redis不推荐使用setNx了,而是直接使用set命令set(lock, expire,"NX", expireTime,"EX"),
可以直接包括了setNx和expire的作用。
消息队列
消息队列主要利用在网络服务中异步任务的实现,redis可以充当消息队列实现生产者/消费者模型和定阅/发布模型。
生产者/消费者模型
生产者/消费者模型需要存在生产者和消费者两方,而在redis中队列的存储和获得可以作为消息队列被生产者和消费者使用,这里就不用Java代码写了,使用redis命令来讲明。
其实redis在其中做的或者缓存的作用,LPUSH queue task
,将task放到queue队列里面,这里略微偏题一句,其实redis有lpush和rpush,意思就是从左侧插入队列和从右侧插入队列。这就是生产者的部份,将任务插入到指定队列中。
消费者的部份有点类似,就是使用BRPOP queue 10
,固然这里的BRPOP也有对应的BLPOP,由于队列是按顺序取任务的,所以这边做的是左侧插入,右侧取出。这里需要注意的是,redis有BRPOP和RPOP,之所以用BRPOP的缘由是这个有一个等待,就是命令中的10,这是一个等待时间,以秒为单位,意思是如果队列中是空的,那末我先不返回,我等待10秒,如果期间有新的任务插入,那末我就取新的任务返回,或者没有的话,返回空。
另外BRPOP还支持优先级,就是BRPOP queue:1 queue:2 queue:3 10
,这个意思是顺序获得,如果queue:1没有取到任务,到queue:2去取,顺次往后。
定阅/发布模型
定阅/发布模型简单来讲就是由发布者向所有定阅者发送任务,任何定阅者都可以获得任务,这里redis的实现就是使用定阅命令。
发布者可使用publish channel task来发布相关的任务,而定阅者则是使用subscribe channel,这是一个监听命令,redis会一直监听这个channel,如果发布者发布新的任务,监听命令会返回任务,直到定阅者主动退出监听。但是redis也为这个设置超时,保证监听的有效性,默许如果60s内没收到消息就异常退出,固然这个可配置。
本篇文章到此结束,如果您有相关技术方面疑问可以联系我们技术人员远程解决,感谢大家支持本站!
文章来源:丸子建站
文章标题:深入理解redis散布式锁和消息队列
https://www.wanzijz.com/view/69345.html