golang基于redis lua封装的优先级去重队列
时间:2022-05-06
本文章向大家介绍golang基于redis lua封装的优先级去重队列,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
前两天由于某几个厂商的api出问题,导致后台任务大量堆积,又因为我这边任务流系统会重试超时任务,所以导致队列中有大量的重复任务。这时候我们要临时解决两个事情,一件事情,让一些高质量的任务优先执行; 另一件事情, 要有去重。 rabbitmq不能很好的针对这类情况去重、分优先级。
这时候我又想到了我最爱的redis… 去重? list + set 就可以解决, 优先级,zset + zrange + zrem 也可以解决… 但问题这几个命令非原子,那么怎么让他们原子? 写模块 or redis lua script . 首先在 redis 4.x 写了个简单的module,但写完了发现一件颇为重要的事情,我们线上的是3.2 …. 然后又花了点时间改成redis lua的版本。项目本身的功能实现很简单,复杂的是创意 !!!
项目名: redis_unique_queue
, 项目地址,https://github.com/rfyiamcool/redis_unique_queue
该文章后续会有更新, 原文地址, http://xiaorui.cc/?p=4828
主要功能介绍:
使用redis lua script 封装的去重及优先级队列方法, 达到了组合命令的原子性和节省来往的io请求的目的.
去重队列:
不仅能保证FIFO, 而且去重.
优先级去重队列:
按照优先级获取任务, 并且去重.
使用方法:
# xiaorui.cc
# PriorityQueue
NewPriorityQueue(priority int, unique bool, r *redis.Pool)
Push(q string, body string, pri int) (int, error)
Pop(q string) (resp string, err error)
# UniqueQueue
NewUniqueQueue(r *redis.Pool) *UniqueQueue
UniquePush(q string, body string) (int, error)
UniquePop(q string) (resp string, err error)
more..
下面是优先级去重队列的例子:
package main
// xiaorui.cc
import (
"fmt"
"github.com/rfyiamcool/redis_unique_queue"
)
func main() {
fmt.Println("start")
redis_client_config := unique_queue.RedisConfType{
RedisPw: "",
RedisHost: "127.0.0.1:6379",
RedisDb: 0,
RedisMaxActive: 100,
RedisMaxIdle: 100,
RedisIdleTimeOut: 1000,
}
redis_client := unique_queue.NewRedisPool(redis_client_config)
qname := "xiaorui.cc"
body := "message from xiaorui.cc"
u := unique_queue.NewPriorityQueue(3, true, redis_client)
// 3: 3个优先级,从1-3级
// true: 开启unique set
u.Push(qname, body, 2)
// 2, 优先级
fmt.Println(u.Pop(qname))
}
单单使用 去重队列的例子:
package main
import (
"fmt"
"github.com/rfyiamcool/redis_unique_queue"
)
func main() {
fmt.Println("start")
redis_client_config := unique_queue.RedisConfType{
RedisPw: "",
RedisHost: "127.0.0.1:6379",
RedisDb: 0,
RedisMaxActive: 100,
RedisMaxIdle: 100,
RedisIdleTimeOut: 1000,
}
redis_client := unique_queue.NewRedisPool(redis_client_config)
qname := "xiaorui.cc"
u := unique_queue.NewUniqueQueue(redis_client)
for i := 0; i < 100; i++ {
u.UniquePush(qname, "body...")
}
fmt.Println(u.Length(qname))
for i := 0; i < 100; i++ {
u.UniquePop(qname)
}
fmt.Println(u.Length(qname))
fmt.Println("end")
}
需要改进地址也是很多, 比如 加入批量操作, 对于redis连接池引入方法改进等.
- 如何下载安装Weka机器学习工作平台
- Dubbo 源码解析 —— LoadBalance
- 如何处理机器学习中类的不平衡问题
- 【死磕Java并发】—– Java内存模型之重排序
- Mask R-CNN源代码终于来了,还有它背后的物体检测平台
- 37个TOP实例命令,超过一半你肯定都没见过
- 利用TensorFlow生成图像标题
- 保存并加载您的Keras深度学习模型
- 简单、通用的JQuery Tab实现
- Dubbo源码解析 - 远程暴露
- 使用FastText(Facebook的NLP库)进行文本分类和word representatio...
- 声音分类的迁移学习
- 【死磕Java并发】—– J.U.C之AQS:CLH同步队列
- 使用Python完成你的第一个学习项目
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法