前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Redis应用之任务队列

Redis应用之任务队列

作者头像
用户4919348
发布2019-04-02 11:00:55
1.1K0
发布2019-04-02 11:00:55
举报
文章被收录于专栏:波波烤鸭波波烤鸭

Redis实现任务队列

1.任务队列

松耦合性

  生产者和消费者无需知道彼此的实现细节,只需要约定好任务的描述格式,这使得生产者和消费者可以由不同的团队使用不同的编程语言编写。

易于扩展

  消费者可以有多个,而且可以分布在不同的服务器中,如下图,借此可以轻易的降低单台服务器的负载。

在这里插入图片描述
在这里插入图片描述

2.Redis实现任务队列

  redis中实现任务队列我们可以通过List中的LPUSH和RPOP命令来实现。如下:

代码语言:javascript
复制
// 无限循环读取任务队列中的内容
while(true){
	String task = rpop("queue");
	if(task != null){
		execute(task);
	}else{
		// 如果没有则等待1秒钟,防止过于频繁的请求数据
		Thread.sleep(1000);
	}
}

  上面的代码实现了一个简单的任务队列,但是还有点不完善,当任务队列中没有任务时消费者每秒都会调用RPOP命令查看是否有新任务,我们想要实现的是如果有新的任务添加进来我们能够立马知道,这时可以使用BRPOP命令来实现,BRPOP命令的作用和RPOP作用是一样的将List中最右侧的元素弹出并返回,唯一不同的是BRPOP是阻塞的。如果没有元素会一直等待到新加元素或超时。代码如下:

代码语言:javascript
复制
// 无限循环读取任务队列中的内容
while(true){
	String task = brpop("queue",0);
	// 执行任务
	execute(task);
}

BRPOP命令接收两个参数:第一个是key,第二个是超时时间,单位是秒,0表示不限制等待时间。打开两个redis-cli实例测试如下:

代码语言:javascript
复制
127.0.0.1:6379> brpop queue 0

进入等待状态。在另一个实例中执行命令

代码语言:javascript
复制
127.0.0.1:6379> lpush queue task
(integer) 1

阻塞的实例立马获取到了结果

代码语言:javascript
复制
127.0.0.1:6379> brpop queue 0
r1) "queue"
2) "task"
(23.39s)

3.优先级队列

  实际环境中我们可能需要监听多个任务队列,有些队列的优先级比较高,需要优先执行,面对这种情况怎么办呢?这种情况下还是使用BRPOP命令来实现。   BRPOP命令可以同时接受多个键,其语法格式为 BRPOP key [key …] timeout,如 BRPOP queue:1 queue:2 0,表示同时检测多个键,如果所有键都没有元素则阻塞。

  1. 如果其中一个键有元素则会从该键中弹出元素。 A实例中
代码语言:javascript
复制
127.0.0.1:6379> blpop queue:1 queue:2 0

B实例中

代码语言:javascript
复制
127.0.0.1:6379> LPUSH queue:2 task
(integer) 1

则实例A中获取的结果

代码语言:javascript
复制
127.0.0.1:6379> blpop queue:1 queue:2 0
1) "queue:2"
2) "task"
(36.98s)
  1. 如果多个键都有元素则按照从左到右的顺序取第一个键的元素,这条是实现优先级队列的关键 向queue:1和queue:2中分别添加一个元素
代码语言:javascript
复制
127.0.0.1:6379> lpush queue:1 task1
(integer) 1
127.0.0.1:6379> lpush queue:2 task2
(integer) 1

然后执行BRPOP命令

代码语言:javascript
复制
127.0.0.1:6379> brpop queue:1 queue:2 0
1) "queue:1"
2) "task1"

  根据BRPOP这个特性我们就可以实现任务队列的优先级了。我们分别使用queue:confirmation.email和queue:notification.email两个键存储发送确认邮件和发送通知邮件两种任务,实现代码如下

代码语言:javascript
复制
while(true){
	String task = brpop("queue:confirmation.email","queue:notification.email",0);
	execute(task);
}

  这时一旦发送了确认邮件的任务被加入到 queue:confirmation.email队列中,无论 queue:notification.email还有多少任务,消费者都会优先完成发送确认邮件的任务。

~ok 到此为止

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年03月17日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Redis实现任务队列
    • 1.任务队列
      • 松耦合性
      • 易于扩展
    • 2.Redis实现任务队列
      • 3.优先级队列
      相关产品与服务
      云数据库 Redis
      腾讯云数据库 Redis(TencentDB for Redis)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档