sidekiqについて
シンプルで効率的なRubyのバックグラウンド処理。
Sidekiqは、スレッドを使用して、同じプロセスで同時に多くのジョブを処理します。Railsを必要としませんが、Railsと緊密に統合し、バックグラウンド処理を死ぬほどシンプルにすることができます。
SidekiqはRedisを使ってて管理してます。
今回のやったもの
ですが、毎回手動で確認するも時間の無駄なので早めに自動にしたいと思ってまして、やってみました。
使い方
データをアクセスする
SidekiqはRailsを使ってますがー Redis-cliも使えます!それだと直接DBを操作できます!
$ redis-cli -h 10.XX.XX.XX -p 6379 -n 12 「コマンド」
重要は-n
パラメータです、sidekiqは12番のノードで動いてます。それで色んなキューのデータを見えます、例えばsidekiqの死亡タスクリストを見たいは簡単で見えます:
$ redis-cli -h 10.XX.XX.XX -p 6379 -n 12 zrange sidekiq:dead 0 -1
1) "{\"retry\":3,\"queue\":\"my_queue\",\"class\":\"MyJobs::WorkerJob1\",\"args\":[403006293],\"jid\":\"56ca5a4be4ef23b6f3676f66\",\"enqueued_at\":1665855225.4404187,\"error_message\":\"Endpoint does not exist\",\"error_class\":\" AWS::SNS::Errors::InvalidParameter\",\"failed_at\":1665855225.5153027,\"retry_count\":3,\"retried_at\":1665855459.3232806}"
2) "{\"retry\":3,\"queue\":\"my_queue\",\"class\":\"MyJobs::WorkerJob2\",\"args\":[342105086],\"jid\":\"3413771368fb2b2a027546db\",\"enqueued_at\":1665855398.6243336,\"error_message\":\"Could not connect to MySQL\",\"error_class\":\"AWS::RDS::Errors::NoConnection\",\"failed_at\":1665855398.7288938,\"retry_count\":3,\"retried_at\":1665855640.0306947}"
3) "{\"retry\":3,\"queue\":\"my_queue\",\"class\":\"MyJobs::WorkerJob2\",\"args\":[404318713],\"jid\":\"56104406dc2e252842344dbb\",\"enqueued_at\":1665859144.2329714,\"error_message\":\"Could not connect to MySQL\",\"error_class\":\"AWS::RDS::Errors::NoConnection\",\"failed_at\":1665859144.3381548,\"retry_count\":3,\"retried_at\":1665859416.574747}"
4) "{\"retry\":3,\"queue\":\"my_queue\",\"class\":\"MyJobs::WorkerJob3\",\"args\":[404320461],\"jid\":\"804e1960b48f7cfc904eb22d\",\"enqueued_at\":1665859721.6611075,\"error_message\":\"Could not connect to MySQL\",\"error_class\":\"AWS::RDS::Errors::NoConnection\",\"failed_at\":1665859721.7336028,\"retry_count\":3,\"retried_at\":1665859871.431027}"
5) "{\"retry\":3,\"queue\":\"my_queue\",\"class\":\"MyJobs::WorkerJob3\",\"args\":[400817551],\"jid\":\"3f853435b08b82572b69bacb\",\"enqueued_at\":1665865808.7670307,\"error_message\":\"Could not connect to MySQL\",\"error_class\":\"AWS::RDS::Errors::NoConnection\",\"failed_at\":1665865808.87391,\"retry_count\":3,\"retried_at\":1665866071.994373}"
Jsonのフォーマットで全部のジョブを見えます!
データを変更する
Redisは以外と単純です、データを入れられる、データを削除する、それだけです、Updateとかはあんまり使わらないし、IDとかもないです、ノードの中では色んなのキューはあって、そのキューの中はメンバーがあります。
データを入れたいとき:
$ redis-cli -h 10.XX.XX.XX -p 6379 -n 12 lpush "「キューの名前」" "「メンバー」"`
例えば:
$ redis-cli -h 10.XX.XX.XX -p 6379 -n 12 lpush "sidekiq:queue:my_queue" "{\"retry\":3,\"queue\":\"my_queue\",\"class\":\"MyJobs::WorkerJob3\",\"args\":[400817551],\"jid\":\"3f853435b08b82572b69bacb\",\"enqueued_at\":1665865808.7670307,\"error_message\":\"Could not connect to MySQL\",\"error_class\":\"AWS::RDS::Errors::NoConnection\",\"failed_at\":1665865808.87391,\"retry_count\":3,\"retried_at\":1665866071.994373}"
1件ずつをするのがちょっと大変なのでスクリプトを入れる!
必須なもの:
- 死亡のリストを取る
- リストの全部を取るの方がいいので:
-
$ redis-cli -h 10.XX.XX.XX -p 6379 -n 12 zrange sidekiq:dead 0 -1 > ファイル.log
- キューの名前:
-
さっきJsonだと気づいたらなので
jq
コマンドを使えます!echo "{\"retry\":3,\"queue\":\"default\",\"class\":\"DropTmpTableWorker\",\"args\":[\"tmp_julien_test_tmp_table\"],\"jid\":\"7b1b36e00383906568f3bf2d\",\"enqueued_at\":1661332354.1658273,\"error_message\":\"Invalid parameter: Endpoint Reason: Endpoint does not exist for endpoint arnarn:aws:sns:ap-northeast-1:600552931410:endpoint/GCM/85989/24276665-d2cd-3d3a-90d5-6f6902d860a9\",\"error_class\":\"AWS::SNS::Errors::InvalidParameter\",\"failed_at\":1661332354.3494694,\"retry_count\":3,\"retried_at\":11666466992.0864118}" | jq . { "retry": 3, "queue": "default", "class": "DropTmpTableWorker", "args": [ "tmp_julien_test_tmp_table" ], "jid": "7b1b36e00383906568f3bf2d", "enqueued_at": 1661332354.1658273, "error_message": "Invalid parameter: Endpoint Reason: Endpoint does not exist for endpoint arnarn:aws:sns:ap-northeast-1:600552931410:endpoint/GCM/85989/24276665-d2cd-3d3a-90d5-6f6902d860a9", "error_class": "AWS::SNS::Errors::InvalidParameter", "failed_at": 1661332354.3494694, "retry_count": 3, "retried_at": 11666466992.086412 }
もっと便利はこちら
echo "{\"retry\":3,\"queue\":\"default\",\"class\":\"DropTmpTableWorker\",\"args\":[\"tmp_julien_test_tmp_table\"],\"jid\":\"7b1b36e00383906568f3bf2d\",\"enqueued_at\":1661332354.1658273,\"error_message\":\"Invalid parameter: Endpoint Reason: Endpoint does not exist for endpoint arnarn:aws:sns:ap-northeast-1:600552931410:endpoint/GCM/85989/24276665-d2cd-3d3a-90d5-6f6902d860a9\",\"error_class\":\"AWS::SNS::Errors::InvalidParameter\",\"failed_at\":1661332354.3494694,\"retry_count\":3,\"retried_at\":11666466992.0864118}" | jq '.queue' "default"
-
それで毎ジョブを自動にキューを取れる。
- retry_countを少なくにする、もう死亡に入ったのでそのパラメータを変更しないと一気に死亡に戻ります
- Sidekiqのコードでそれを対応しなきゃ
- もう一回パラメータをjqしてからJsonで戻すこと
retry_params=$(echo "$line" | jq '.retry_count = 0 | @json')
- redis-cliを使いながらジョブを入れて、死亡のキューのジョブを削除
redis-cli -h $REDIS -p $PORT -n $SEED lpush "sidekiq:queue:${queue//\"/}" "${retry_params}"
redis-cli -h $REDIS -p $PORT -n $SEED lpush "sidekiq:queue:${queue//\"/}" "${retry_params}"
それで無事に再実行が自動でできます!
最後のファイルはこんな感じです:
REDIS=10.XX.XX.XX
PORT=XXXX
SEED=12
redis-cli -h $REDIS -p $PORT -n $SEED zrange sidekiq:dead 0 -1 > ファイル.log
while read line; do
queue=$(echo "$line" | jq '.queue')
retry_params=$(echo "$line" | jq '.retry_count = 0 | @json')
redis-cli -h $REDIS -p $PORT -n $SEED lpush "sidekiq:queue:${queue//\"/}" "${retry_params}"
redis-cli -h $REDIS -p $PORT -n $SEED ZREM "sidekiq:dead" "${line}"
done < ファイル.log
注意点
色々やってみてたら、jq
コマンドで変なバグが見つかりました、数字の文字制限がありました。
echo "{\"retry\":3,\"queue\":\"default\",\"class\":\"DropTmpTableWorker\",\"args\":[\"tmp_julien_test_tmp_table\"],\"jid\":\"7b1b36e00383906568f3bf2d\",\"enqueued_at\":1661332354.1658273,\"error_message\":\"Invalid parameter: Endpoint Reason: Endpoint does not exist for endpoint arnarn:aws:sns:ap-northeast-1:600552931410:endpoint/GCM/85989/24276665-d2cd-3d3a-90d5-6f6902d860a9\",\"error_class\":\"AWS::SNS::Errors::InvalidParameter\",\"failed_at\":1661332354.3494694,\"retry_count\":3,\"retried_at\":11666466992.0864108}" | jq .
{
"retry": 3,
"queue": "default",
"class": "DropTmpTableWorker",
"args": [
"tmp_julien_test_tmp_table"
],
"jid": "7b1b36e00383906568f3bf2d",
"enqueued_at": 1661332354.1658273,
"error_message": "Invalid parameter: Endpoint Reason: Endpoint does not exist for endpoint arnarn:aws:sns:ap-northeast-1:600552931410:endpoint/GCM/85989/24276665-d2cd-3d3a-90d5-6f6902d860a9",
"error_class": "AWS::SNS::Errors::InvalidParameter",
"failed_at": 1661332354.3494694,
"retry_count": 3,
"retried_at": 11666466992.08641
}
1件だけは違いありまして、\"retried_at\":11666466992.0864108
がjsonに入ってますが、jq
を入れたら、"retried_at": 11666466992.08641
になってます、.086408
から.08641
になってます。。
今回は死亡を削除したい場合は全く同じパラメータじゃないと削除できないのでご注意ください。