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分布式锁和消息队列的更多相关文章
- 循序渐进 Redis 分布式锁(以及何时不用它)
场景 假设我们有个批处理服务,实现逻辑大致是这样的: 用户在管理后台向批处理服务投递任务: 批处理服务将该任务写入数据库,立即返回: 批处理服务有启动单独线程定时从数据库获取一批未处理(或处理失败)的 ...
- Lua脚本在redis分布式锁场景的运用
目录 锁和分布式锁 锁是什么? 为什么需要锁? Java中的锁 分布式锁 redis 如何实现加锁 锁超时 retry redis 如何释放锁 不该释放的锁 通过Lua脚本实现锁释放 用redis做分 ...
- Redlock:Redis分布式锁最牛逼的实现
普通实现 说道Redis分布式锁大部分人都会想到:setnx+lua,或者知道set key value px milliseconds nx.后一种方式的核心实现命令如下: - 获取锁(unique ...
- redis分布式锁小试
一.场景 项目A监听mq中的其他项目的部署消息(包括push_seq, status, environment,timestamp等),然后将部署消息同步到数据库中(项目X在对应环境[environm ...
- Redis分布式锁的实现
前段时间,我在的项目组准备做一个类似美团外卖的拼手气红包[第X个领取的人红包最大],基本功能实现后,就要考虑这一操作在短时间内多个用户争抢同一资源的并发问题了,类似于很多应用如淘宝.京东的秒杀活动场景 ...
- Redis分布式锁实现简单秒杀功能
这版秒杀只是解决瞬间访问过高服务器压力过大,请求速度变慢,大大消耗服务器性能的问题. 主要就是在高并发秒杀的场景下,很多人访问时并没有拿到锁,所以直接跳过了.这样就处理了多线程并发问题的同时也保证了服 ...
- Redis分布式锁实战
什么是分布式锁 在单机部署的情况下,要想保证特定业务在顺序执行,通过JDK提供的synchronized关键字.Semaphore.ReentrantLock,或者我们也可以基于AQS定制化锁.单机部 ...
- 死磕 java同步系列之redis分布式锁进化史
问题 (1)redis如何实现分布式锁? (2)redis分布式锁有哪些优点? (3)redis分布式锁有哪些缺点? (4)redis实现分布式锁有没有现成的轮子可以使用? 简介 Redis(全称:R ...
- 自己写了个简单的redis分布式锁【我】
自己写了个简单的redis分布式锁 [注意:此锁需要在每次使用前都创建对象,也就是要在线程内每次都创建对象后使用] package redis; import java.util.Collection ...
随机推荐
- 如何按内容筛选dom
有时候我们需要按照dom的text内容去筛选,那么可以用jQuery的contains筛选 写法 $("div:contains(aaa)") 筛选出内容包含aaa的div 另外 ...
- 织梦DedeCMS调用二级子栏目或者多级栏目的方法
图2 当前栏目typeid值为3,所以代码如下: {dede:channelartlist typeid='3,3'} <a href="{dede:field name='typeu ...
- php面向对象1
类和对象的关系 首先看一段代码 var_dump()后的结果 注意 一个对象系统自动分配一个对象标识符!
- vue初学实践之路——vue简单日历组件(1)
---恢复内容开始--- 最近做的项目有一个需求,需要有一个日历组件供预定功能使用,之前的代码过于繁琐复杂,所以我采用vue重写了这个组件. npm.vue等等安装. 只是一个简单的日历组件,所以并不 ...
- 进程控制fork与vfork
1. 进程标识符 在前面进程描述一章节里已经介绍过进程的两个基本标识符pid和ppid,现在将详细介绍进程的其他标识符. 每个进程都有非负的整形表示唯一的进程ID.一个进程终止后,其进程ID就可以再次 ...
- Bash中的字符串变量扩展
1.向尾部方向的最小化删除 (%) $pathname="/usr/bin/local/bin"$echo ${pathname%/bin*}/usr/bin/local 2.向尾 ...
- scrapy抓取淘宝女郎
scrapy抓取淘宝女郎 准备工作 首先在淘宝女郎的首页这里查看,当然想要爬取更多的话,当然这里要查看翻页的url,不过这操蛋的地方就是这里的翻页是使用javascript加载的,这个就有点尴尬了,找 ...
- python list有关remove的问题
在python 中进行一次简单的列表循环,当用到remove时出现了一个很有趣的现象, 代码如下: a=range(30) for i in a : if i%4!=0: a.remove(i) 这段 ...
- java wait 和notify
这几天自己学习了一下线程的知识,wait 方法使当前的线程等待,notify 方法 唤醒当前的线程的方法 th 线程在5的时候进行wait,此时主线程继续执行, 主线程执行到9的时候 唤醒 th 线程 ...
- 详解ES6中的 let 和const
前 言 JRedu ECMAScript 6 是 JavaScript 语言教程,全面介绍 ECMAScript 6 新引入的语法特性. ES6 与上一个版本 ES5 的所有不同之处,对涉及的语 ...