Tresure Data社のワークフローエンジンdigdagを使っていて困ったことがあったので、それのメモ
##現象
エラーとならずに1週間以上も処理が走り続けていた。
##No space left on device
digdagのログを確認すると、「No space left on device」というメッセージが表示されていました。
こちらはデバイスの容量がないときに出るエラーとのことですが、今回はinodeが足りていないようでした。
incodeとはUNIX系OSで使用されるファイルシステムの名称で、ファイルの所有者やアクセス権、サイズ、作成日時、場所などを管理しているものでそれが足りていない。つまりファイル数が多すぎたようでした!
$ df -i
Filesystem Inodes IUsed IUse% Mounted on
/dev/xda1 1048756 1048755 100% /
##原因
ファイルが多い原因を突き止めていたところdigdagのログファイルが溜まりに溜まっているということが原因のようでした。
ログはWebで以下のように確認することができますが、実ファイルは「~/log/digdag/yyyy-mm-dd/」以下に溜まり続けます。
スケジュールJOBで毎時間2つの処理が走っていてそれが4月から溜まりに溜まって1月に限界となったようです。
##対策1:ログのアーカイブ
まずはログをアーカイブしました。月に1回ぐらいしていたら問題ないと思います。
注意点としてはログのアーカイブをするとWebでログが確認できなくなります。
##対策2:timeoutの設定
今回エラーに気付くのが遅れた原因として、エラーメールが飛んでいなかったためです。
エラーの際にメールが飛ぶ設定はしていたのですが、そもそもエラーとならずに走り続けていたのでメールが飛んでいませんでした。
そこでtimeoutの設定をします。60分以内に終わらなければ、エラーとし、+noticeの処理を実行後、_errorの処理を実行します。
# 60分以内に終わらなければエラー
sla:
duration: 00:60:00
fail: true
+notice:
echo>: timeout err!!
_error:
mail>: tmpl/error_timeout.txt
subject>: timeout error!!
to: [abcd@gmail.com]
##追記:timeoutの処理
実際に上記で試していたらslaでfail:trueとしても処理自体は止まらないみたいです。
# 60分以内に終わらなければエラー
sla:
duration: 00:60:00
fail: true
+notice:
echo>: timeout err!!
+task:
#処理の途中で60分を超えても
#notice処理をしてから戻ってくる
_error:
mail>: tmpl/error_timeout.txt
subject>: timeout error!!
to: [abcd@gmail.com]
そこで強制終了の処理を無理やり入れました。強制終了は
$ digdag kill <attempt-id>
で可能です。ただdigdagではsession-idは取得できるもののattempt-idは取得できません。(そもそもsessionは取れてattemptが取れないってどうなのと思いますが。。。)
そこでshで取得します。また強制終了をすると_errorの処理が走らないので、強制終了の前にメールを送信しておきます。
# 60分以内に終わらなければエラー
sla:
duration: 00:60:00
fail: true
+notice:
+mail:
mail>:
data: timeout error
subject: ERROR!! timeout error (session:${session_id})
to: [abcd@gmail.com]
+kill_task:
sh>: tasks/_kill_job.sh ${session_id}
echo>: timeout err!!
+task:
#省略
#!/bin/sh
session_id=$1
get_attempts=`digdag attempts ${session_id}`
echo $get_attempts
is_attempt=0
is_id=0
for i in $get_attempts; do
if [ $is_attempt -eq 1 ] && [ $is_id -eq 1 ]; then
attempt_id=$i
#複数回処理をしている場合が、あるので初期化しておく
is_attempt=0
is_id=0
fi
if [ $i = "attempt" ]; then
is_attempt=1
fi
#attempt idと続く場合にフラグを立てる
if [ $is_attempt -eq 1 ] && [ $i = "id:" ]; then
is_id=1
fi
done
echo $attempt_id
digdag kill $attempt_id
shellはほぼ初めて書いたので、お粗末ですが、ご了承ください。
##参考
No space left on device とエラーが出るときの対処法
「分かりそう」で「分からない」でも「分かった」気になれるIT用語辞典
digdagのsla/fail/error/waitについてのメモ