BullMQをやめる
u1-liquid opened this issue · comments
もっと正確には、Redisベースのキューをやめる
(負荷に耐えられないので)
前提
- HA構成が可能であること(もしくはサーバーレスであること)
- 別途のライセンス費用が発生しないこと
案
- BullMQを使い続ける
- RabbitMQ
- ActiveMQ
- Kafka
- ZeroMQ
とても個人的な観点のPros & Cons
BullMQを使い続ける
この場合、既存のSingle-Node RedisではなくCluster構成に対応させることにする
Pros
- ソースコードの変更が一番少ない
Cons
- Clusterを組まなければならない
- 何も解決されない可能性がある
RabbitMQ
Pros
- 多方面から実績のあるソリューション
- 公式のマネージメントUIがある
Cons
- AMQPなのでクライアントはAMQPライブラリを使えばいいとされているが、node.js用はやや開発が途切れている感がある
- 偶数個のサーバーで運用する必要がある
ActiveMQ
Pros
- 専用のnode.js向けクライアントライブラリがある
- 比較的機能が多いとされている(要確認)
- 公式のWeb Console UIがある
Cons
- HA構成にはZookeeperがいる
- 最近も採用されているかと言うと微妙
Kafka
Pros
- 多方面から実績のあるソリューション
- TPSがとても高い
Cons
- 管理コストも高い
- cliで管理するのがほぼ常識みたいな感じ
- 公式のWeb UIが無い(OSSはある)
ZeroMQ
Pros
- リクエストをすぐ処理することに向いてる気がする
- ブローカーを必要としない実装なので追加で管理するサーバーが増えない
Cons
- メッセージを処理予定だったサーバーが勝手に消える可能性があるという今のioの構造には向かないかも
- ブローカーがないので総計を取るには工夫が必要
RabbitMQ良さそう
実装の方針
- 基本的に全てのオプションを設定ファイルで触れるようにする
- 実装には1つのvhostを、rascalの設定でnamespaceで分けて、queueごとにvhost設定を作くる(rabbitmqサーバー側の設定はだるそう)
- 基本的にrascalのexampleにあるadvanced構成を真似る
- quorum queueを設定するが、これによるリトライは基本的にプロセスが落ちた時(デフォルトで15分のackタイムアウト)にのみ適用する(コード上では参照しない)
クライアントが勝手に死んだときジョブが消える可能性があるためrascalのリトライ機能は使わない、エラーが起きたらdelayキューにメッセージごとのTTLを設定してDLXフローを使う
↑ドキュメント読み間違えた基本的にはrascalのリトライ機能を使ってよさそう- inboxとdeliverはretry回数に合わせて1m,3m,5m,10m,30m,1h,2h,4h,8hのbackoffをさせる、ほかは固定で1mのdelayでよさそう
- misskeyにdashboardは実装しない
- statsはqueueのassertの返り値で表現できそう
- ジョブのリトライ機能も一応実装する
- 溜まったDLQのTTLは14日くらい?
- vhostのconcurrencyは同時に実行可能なジョブの数ではないので注意
同時に実行するジョブの設定はsubscriptionsのprefetchの数
BullMQが重い理由引用
ジョブキューの時間計算量が実行中(待機中ではない)のジョブの数に比例するという性能特性があり、かつ時間計算量がタイムアウトの閾値を超えるとジョブの完了処理がコケるようになり、原理的に2度と状況が改善方向に向かうことはないという性能劣化の正帰還ができあがっていた(ので、全部一度引っこ抜いて待機列に詰め直した) https://misskey.io/notes/9o4bl4yw9bpv0djx
具体的にはこの一行の時間計算量が active リスト(実行中のジョブリスト)の要素数に比例してます。完了したジョブをリストから取り除く処理なんだけれど、増えた待機ジョブに対応してワーカーを増やしまくるなどして実行中のジョブがひとたび急増すると、ここの処理が激重になり、タイムアウトするようになり、つまりジョブは2度と完了せず、不幸が訪れる。ジョブに増加に対応しようとして逆に首が締まる最悪のループに入るわけです。 https://misskey.io/notes/9o4c09uu3gov0eia
結論としては詰め直せばええ https://misskey.io/notes/9o4bn9k6vhcm0ddf