Carpe Diem

備忘録。https://github.com/jun06t

BLPOPで優先順位を付けてタスクキューを実行

概要

タスクキューを操作する時に、特定の処理が他の処理よりも先に実行できるよう優先順位を付けたいケースがあります。
RedisのBLPOPは複数のリストを処理してくれるのでそれを実現できます。

前提

以下の優先度を決めたキューがあるとします。

キュー名 優先度 入ってるタスク
queue:high ht1, ht2, ht3
queue:middle mt1, mt2, mt3
queue:low lt1, lt2, lt3

動作検証

テストデータ

データを入れて実験します。

127.0.0.1:6379> rpush queue:high ht1 ht2 ht3
(integer) 3
127.0.0.1:6379> rpush queue:middle mt1 mt2 mt3
(integer) 3
127.0.0.1:6379> rpush queue:low lt1 lt2 lt3
(integer) 3

コマンド

BLPOPは複数のリストを引数に与えることができ、左のリストから順に処理するロジックなので左側から優先度が高いキューを入れていきます。

127.0.0.1:6379> blpop queue:high queue:middle queue:low 1

最後の引数はブロックする際のタイムアウトです。データが無ければ1秒間ブロックします。0を指定するとデータが挿入されるまでブロックされます。

実行結果

以下のようにpopされます。ちゃんと優先度高の方から順にpopされていることがわかります。

127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:high"
2) "ht1"
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:high"
2) "ht2"
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:high"
2) "ht3"
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:middle"
2) "mt1"
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:middle"
2) "mt2"
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:middle"
2) "mt3"
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:low"
2) "lt1"
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:low"
2) "lt2"
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:low"
2) "lt3"
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
(nil)
(1.05s)

途中でqueue:highにタスクをpushすれば、middleやlowの途中でもhighが優先してpopされます。

127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:high"
2) "ht1"
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:high"
2) "ht2"
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:high"
2) "ht3"
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:middle"
2) "mt1"
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:middle"
2) "mt2"
127.0.0.1:6379> rpush queue:high ht1  // 挿入
(integer) 1
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:high"
2) "ht1"
127.0.0.1:6379> blpop queue:high queue:middle queue:low 1
1) "queue:middle"
2) "mt3"

まとめ

RedisのBLPOPを使うと簡単に優先度をサポートしたタスクキューを実装できます。

ソース