Skip to content

Instantly share code, notes, and snippets.

@parkjy76
Last active April 6, 2019 05:49
Show Gist options
  • Select an option

  • Save parkjy76/b869b8a62946d4af246285b1cb78bf65 to your computer and use it in GitHub Desktop.

Select an option

Save parkjy76/b869b8a62946d4af246285b1cb78bf65 to your computer and use it in GitHub Desktop.
Disqueとは

Disque

https://github.com/antirez/disque

disqueはRedisの作者が開発したメモリベースの分散メッセージブローカである。

  • ゴールは"Redis as a jobs queue"である。
  • redisのようにシングルスレッドで動作する。 これはredis.ioにも言及されたように同じことだと思われる
  • 現在のバージョンは1.0 betaでプロダクト環境にはまだ合わないかもしれないと書いてある。

基本動作

disqueは分散され失敗に丈夫なメッセージブローカでメッセージを交換するためのプロセスの間に位置するミドルウェアとして動作する。 disqueではjobという単語を使っているが結局文字列のメッセージを意味するもので同じ意味で扱える。

disqueは順次的にコピーされるjob queueであって新しいjobが追加されるとW個のnodeにコピーされ、完了するとクライアントにjob idを返すようにしている。

disqueはat-least-onceat-most-onceをサポートしている。 retry timeを0, replicateを1にするとat-most-onceになる。この際に必ずreplicateを1する必要はないがメッセージを複数個コピーする必要もないからだ。 その以外はat-least-onceになる at-least-onceとat-most-onceはmessage毎に指定可能だ。

disqueはすべてのノードが同じ役割をする分散システムである(マルチマスタ) producerとconsumerはどんなnode接続しても構わないしロードとクライアントのリクエストによって自動でnode間でメッセージが交換される。

disqueはCAP Theoremのeventually consitent APに該当する。

disqueは信頼性を担保で低遅延非同期コマンドをサポートしている メッセージを追加すると該当nodeに保存してそのままIDをクライアントに返し バックグラウンドではnodo間のコピーが行われるのがその例だ。 こんな場合にコピーに問題なく完了されたか保証がないがクライアント側はリクエストの応答時間を減らせる

disqueはconsumerによって消費されたメッセージがACKされないと指定したretry時間後自動でrequeueされる機能持っている。 明示的にACKをするとメッセージは一回だけ転送される。

disqueはメッセージが生成される順で保存する時間はnodeの壁時計によって同じnode内では生成された順で転送される。 でもrequeue、auto-balancing、node間の時間差で順番が変わる場合があるがランダムで転送されることではない。基本的に先に入ったメッセージは先に転送されるようにしている。

disqueは各jobがfine-grained controlが出きるように三つの時間関連のパラメタは一つのコピー関連のパラメタを提供している。 (replicate, delay, retry, ttl)

disqueは永続化のためdiskに保存可能。

※ disqueはFIFOが厳しく守られてないため技術的に言うとメッセージキューと呼ばれるよりメッセージブローカ方が正しい。でもIT業界の観点ではメッセージキューとは一般的なブローカと軽く区別するために時々使わると思う。

ACKs, Retry

クライアントは同じjobが複数回転送を防止するためACKを使用するとこができる。これはクライアントにメッセージが正常に転送されたことをdisqueに知らせるためである。

jobは複数のnodeに同じjob idでコピーされるが通常は一つのnodeに限ってqueuedの状態で存在する。 jobは4つ状態を持つが特にactivequeuedかを確認する。

GETJOBなどで消費されたメッセージはqueuedからactiveに状態が変わる。activeの状態のjobはキューに存在しないためまたGETJOBで拾えない。

ACKsメッセージによって確定(削除)されないとretry時間を過ぎたメッセージはrequeueされ状態はqueuedになってGETJOBなどで消費可能になる。

ENQUEUE/DEQUEUEコマンドで直接jobの状態をqueued/activeに変更できる。

FASTACK

disqueで使われてる一般的なACKはnode間で交換するコマンドが多くて処理費用が高い。 FASTACKは交換回数を減らしてオーバーヘッドが減らして高速化したものだ 半面ネットワーク上の問題であるnodeに削除コマンドが伝われてないことがあったらjobは再度消費される信頼性の問題が起きる可能性がある。

Dead letter queue

多くの場合メッセージキューはdead letter queueというものを実装している。これはメッセージが転送される度に失敗したり諸費される前にTTLを過ぎたりした場合など何らかの理由で処理出来ないメッセージを算出するための特別なキューのこと。

Disk永続化

Append Only File(AOF)を使ってjobの生成と追放がdiskにロギングされ(with configurable fsync policies) 再起動時に再度ロードされる。

Job ID

jobを識別するためのjob idは下記のように40文字の文字列になっていて D-dcb833cf-8YL1NT17e9+wsA/09NqxscQI-05a1 また4つの部分で区別される D- | dcb833cf | 8YL1NT17e9+wsA/09NqxscQI | 05a1

  • D- はprefix
  • dcb833cfはメッセージが生成されたnodeのIDの頭から8バイト
  • 8YL1NT17e9+wsA/09NqxscQIは144bitのpseudo-random部分でbase64でエンコードされたもので/dev/urandomで生成されたseedとjob IDのカウントをSHA1にした上位の144bitを使用
  • 05a1はjobのTTLでjobを解析せずに破棄出来るようにするためである。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment