Redis 實現隊列優先級


Redis 實現隊列優先級

原創 2015-12-25 杜亦舒 性能與架構

通常使用一個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_a 3

redis> lpush mylist d
redis> set mylist_score_a 3


根據權值排序,並取出排名第一的元素


redis> sort mylist by mylist_score_* limit 0 1


結果為:c,正是我們想要的,c 的級別最高,並且是先進入隊列的


獲取完成后,要移除此元素


redis> lrem mylist 0 c


總結


方式1最簡單,但實際應用比較局限,方式3可以實現復雜優先級,但實現比較復雜,不利於維護


方式2是推薦用法,實際應用最為合適


方式1、3可以作為redis應用思路的一個拓展


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM