前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >golang基于redis lua封装的优先级去重队列

golang基于redis lua封装的优先级去重队列

作者头像
李海彬
发布2018-03-28 10:57:56
9110
发布2018-03-28 10:57:56
举报
文章被收录于专栏:Golang语言社区Golang语言社区
前言:

前两天由于某几个厂商的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, 而且去重.

优先级去重队列:

按照优先级获取任务, 并且去重.

使用方法:

代码语言:javascript
复制
# 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..

下面是优先级去重队列的例子:

代码语言:javascript
复制
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))
}

单单使用 去重队列的例子:

代码语言:javascript
复制
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连接池引入方法改进等.

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2017-10-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Golang语言社区 微信公众号,前往查看

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

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

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