redis+lua脚本实现分布式布署任务优先级队列

3 篇文章 0 订阅
1 篇文章 0 订阅

脚本的起因是获取redis的优先级计数器后,需要对当前优先级自增。在多个进程或者分布式下,原子命令无法作到隔离比如

线程A,B,C

  1. A.get
  2. B.get
  3. A.incr
  4. C.get 
  5. ...

而我想要的是

  1. A.get
  2. A.incr
  3. B.get
  4. B.incr
  5. ...

redis multi方案直接毙了,因为我要获取中间的结果集,所以最后选择lua脚本方案,关于lua自行度娘吧

1.解决表的读取排序问题,网上很多方案是table.sort,太烦,反正我的值固定就三个,直接一个数组加表,干就是了。

2.两段循环解决,次数判定问题。(嵌套循环也无所谓O(n2)的复杂度,这么少的次数。。忽略吧)

3.最后返回哪个任先级

local key = "task:async:count"
local prioritySort={"high","normal","low"}
local priority = {
	["low"]=1,
	["normal"]=3,
	["high"]=5,
}

local function setGetPriority(key)

	local priorityDefault
	local newData = {}
	local data = redis.call('hGetAll', key)

	if(next(data) == nil) then
		priorityDefault = 'high'
	else
		for i, v in pairs(data) do
			if(i % 2 == 1 ) then
				newData[v] = tonumber(data[i+1])
			end
		end
		for index, value in pairs(prioritySort) do
			if(newData[value]==nil or newData[value] < priority[value]) then
				priorityDefault = value
				break
			end
		end
	end

	if(priorityDefault == nil) then
		if(not redis.call('del', key)) then
			return false
		end
		priorityDefault = "high" 
	end

	if(redis.call('hIncrBy', key, priorityDefault, 1)) then
		return priorityDefault
	else
		return false
	end


end

return setGetPriority(key)

最后贴个画的草图,草创方案,后期再优化,欢迎指教

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值