キューとジョブ
仕事をワーカーに渡し、
落ちたら取り返す
リレーショナルデータベースのキュー用テーブルは、手数の増えたロックの慣習にすぎません。kevy には本物のキューが 2 つあります。ジョブを失っても許されるならリスト、許されないならコンシューマグループつきのストリームです。
2 つの、どちらを使うか
リストを使うのは、やり直しが安く、ワーカーが作業中に落ちる見込みが低いときです——メールの送信、キャッシュの暖機、CDN パスの無効化。BRPOP は仕事が来るまでブロックするので、ワーカーはポーリングしません。
ストリームを使うのは、ジョブを失ってはならないときです。コンシューマグループは各メッセージを、ちょうど 1 つのワーカーに渡し、渡したことを覚えています。ワーカーが確認応答の前に落ちても、メッセージは保留リストに残り、別のワーカーが引き取れます——ストリームが存在する理由はまさにそれであり、それが、キューと願望との違いです。
手順——やり直せる仕事には、リスト
# producer
LPUSH jobs:email '{"to":"ada@example.com","tpl":"welcome"}'
# worker — blocks until there is something, up to 30 seconds
BRPOP jobs:email 30
-> 1) "jobs:email"
2) "{\"to\":\"ada@example.com\",\"tpl\":\"welcome\"}"
# a delayed job: the score is when it is due.
# ZPOPMIN.BELOW is kevy's own — it takes only what is actually due,
# and stops at the first job that is not.
ZADD jobs:due 1783875499 '{"id":"j-91"}'
ZPOPMIN.BELOW jobs:due 1783875500
-> 1) the job payload
2) 1783875499
手順——失えない仕事には、ストリーム
# once, at setup
XGROUP CREATE jobs:pay g1 $ MKSTREAM
# producer
XADD jobs:pay * order 4410 amount 8400
# worker: read, then work, then acknowledge
XREADGROUP GROUP g1 worker-3 COUNT 1 BLOCK 5000 STREAMS jobs:pay >
XACK jobs:pay g1 1783875499458-0
# the worker died before XACK. another one takes over:
XAUTOCLAIM jobs:pay g1 worker-7 60000 0-0
# claims anything idle for more than 60 s
# what is still outstanding, and who has it
XPENDING jobs:pay g1
何を差し出すことになるか
ストリームは、ただではありません。MAXLEN による切り詰めはストリームの重みを計算し直すため、ストリーム全体に対して O(N) です。XADD のたびではなく、定期的に切り詰めてください。XREADGROUP の COUNT が制限するのは渡される量であって、走査される量ではありません。未配信の末尾は、まず全体が実体化されます。またマルチシャードのサーバーでは、複数のキーにまたがる BLPOP は、Redis の厳密な左から右への優先順を守りません。接続自身のシャードにあるキーが、先に処理されます。これらはすべてリファレンスに、コマンドごとに書いてあります。