通常使用一個list來實現隊列操作,這樣有一個小限制,所以的任務統一都是先進先出,如果想優先處理某個任務就不太好處理了,這就需要讓隊列有優先級的概念,我們就可以優先處理高級別的任務。
實現方式:
(1)單一列表實現
隊列正常的操作是 左進右出(lpush,rpop)
為了先處理高優先級任務,在遇到高級別任務時,可以直接插隊,直接放入隊列頭部(rpush),這樣,從隊列頭部(右側)獲取任務時,取到的就是高優先級的任務(rpop)
相當於普通任務按照隊列結構,碰到高優先級任務,就按照堆棧結構
優點是實現簡單,缺點是高級別任務總是后進先出,適用於簡單的隊列需求,高優先級任務較少的情況。
(2)多隊列實現
使用兩個隊列,一個普通隊列,一個高級隊列,針對任務的級別放入不同的隊列。
獲取任務時也很簡單,redis的BRPOP命令可以按順序從多個隊列中取值。
BRPOP會按照給出的 key 順序查看,並在找到的第一個非空 list 的尾部彈出一個元素。
redis> BRPOP list1 list2 0
list1 做為高優先級任務隊列
list2 做為普通任務隊列
這樣就實現了先處理高優先級任務,當沒有高優先級任務時,就去獲取普通任務。
(3)使用權值實現
如果優先級比較復雜,比如有10幾個甚至更多的優先級別,方法2就不太方便了。
例如有3個級別(1 2 3),用權值來表示
有4個元素需要入隊
a級別1,b級別2,c級別3,d級別3
使用 lpush 把他們入隊,同時設置權值
redis> lpush mylist a redis> set mylist_score_a 1 redis> lpush mylist b redis> set mylist_score_b 2 redis> lpush mylist c redis> set mylist_score_c 3 redis> lpush mylist d redis> set mylist_score_d 3
根據權值排序,並取出排名第一的元素
redis> sort mylist by mylist_score_* limit 0 1
結果為:c,正是我們想要的,c 的級別最高,並且是先進入隊列的
獲取完成后,要移除此元素
redis> lrem mylist 0 c
總結:
方式1最簡單,但實際應用比較局限,方式3可以實現復雜優先級,但實現比較復雜,不利於維護
方式2是推薦用法,實際應用最為合適 方式1、3可以作為redis應用思路的一個拓展
轉自:https://cloud.tencent.com/developer/article/1082893