🐙

Github ActionのCronジョブが破棄されやすい時間帯のお話

2023/06/30に公開

Github ActionにはCronジョブがあるわけです
しかしこのCron、アクション予約としてキューに入れても、実際に動くかどうかに関しては保証していません。予定入れたけど、別のプロセスで忙しすぎてキャンセル。そんなイメージ

なので例えば、
"n分毎にログを取って、その結果をデータベースに記録する。このプロセスは絶対行われなければいけない"
ということを行うには不向きなわけです(1敗)

この記事では実際に5分毎のログ機能を実装しようとして失敗した経験を元に、データが欠落した頻度を調べて、逆にジョブが通りやすい時間を調べてみた。そんな記事

ジョブが捨てられた失敗例

失敗したGithub Actionに使ったymlファイルはこんな感じ。

name: freq
on:
  schedule:
    - cron: '*/5 * * * *'
  workflow_dispatch:
env:
  HOST: ${{ secrets.HOST }}
  USER: ${{ secrets.USER }}
  PASSWD: ${{ secrets.PASSWD }}
  DB: ${{ secrets.DB }}
  CAPATH: ${{ secrets.CAPATH }}
jobs:
  freq:
    runs-on: ubuntu-latest 
    steps:
      - uses: actions/checkout@v3
      - run: pip install mysql
      - run: python freq.py

Actionの発火条件onに関して、scheduleのcronを用いて5分ごとにfreq.pyを実行しています

freq.pyはmysqlデータベースに現在時刻(とログ)を保存していくプログラムです。中身はmysqlライブラリ使っているだけなので割愛

たしかに5分ごとにジョブを実行する設定なのだけど、Cronジョブが放棄されて歯抜けができてしまっていた

めげずにこの歯抜けのログを観察して、Cronジョブが落ちやすい時間帯を確かめて見ます
転んでもタダでは起きないとはこのことか

ジョブ実行回数の集計

一週間くらい放置して、時刻ごとのジョブ実行頻度をヒストグラムにしたものがこれです
縦軸が実行に成功した回数の合計。横軸が実行した時刻を表します

みると0:00あたりと12:00あたりが特に成功回数が少ないですね。キリのいい値なのでなんとなく知ってた。日本時間で言う9時あたり

あとやっぱり夜中の利用者少ない間にバッチ処理したい需要が大きいので、0:00あたりは特に少ないみたい
わかりやすい。教科書に書いてあるかの如き、深夜時間帯に実行されてます(時差が考えられているかは知らんけど)

つまり、16:00あたりに設定しておけば時差の都合上、日本での深夜かつ落ちにくい条件で実行できそう。なるほど

時のほうはいつ頃に設定すればいいかはわかった。分のほうはどう設定するのがいい?そう思ってもう一つヒストグラムを用意しました
なんとなく、毎時30分とかキリがいいからジョブが混雑しそうじゃない?ということで、各分ごとに集計した結果を示します

縦軸が実行に成功した回数の合計。横軸が実行した分を表します

n時ぴったりに相当する一番左の部分はわかりやすくジョブの実行数が少ないです
それ意外でも30分以降と以前でのジョブ実行数も異なることがわかります

たしかに、Cronの時間設定どうするか考える時に、40分とか50分にしようとはあまり思わないかも。分はなるべく遅い時刻で実行させるとよさそう。なるほど

まとめ

Github ActionのCron設定をするときに避けた方がいい時間帯はこんな感じ

  • 0時から2時の間
  • 12時あたり
  • 各時で30分より前

つまるところ、日本時刻の時差(9時間)を考慮して15時あたりかつ、35分以降に設定させるのが良いみたい

時差って大事。ちょっと知見が増えました

Discussion