さくらレンタルサーバーでバッチをkillされたくなければ高負荷な時間を短くせよ。 - hsksnote

さくらレンタルサーバーでバッチをkillされたくなければ高負荷な時間を短くせよ。

すごいあたり前のことを書くのですが、この結論に至るまでに色々試して、さくらのレンタルサーバ

で重い処理を流した時の挙動なんかも見えてきましたので、そのあたりを書きます。


前段

えー、共用レンタルサーバーを借りていると、重くて時間のかかるバッチ処理は強制的にKillされます。

僕がさくらレンタルサーバーで動かしてるwebサービス404 Not Found」でも、一日一回動くバッチ処理があって、開発中にそれがことごとくKillされてしまった。

その処理は、登録されてる誕生日をチェックして、1週間後ならtweetするということをやる。流れはこんな感じ。

  1. DBから、誕生日が今から1週間後のユーザーを取得する。(以下は取得したユーザーごとに)
  2. ユーザーのほしい物リストスクレイピングして、ほしい物リストにある商品のタイトルをすべて取得する。
  3. Twitter APIから、ユーザーのfollowersとfriendsを最大2000人ずつ取得して、両方のリストにあるユーザーをランダムで100人取得する。
  4. 上記データを使って、ほしい物のタイトルとほしい物リストURLtweetする。
    • ユーザーがmention付きでつぶやく設定にしていたら、3.で取得したユーザーへのmentionも含めてつぶやく。
      • 複数名まとめてつぶやく
      • 一度つぶやいてから次につぶやくまで10秒間隔を空ける。
    • tweetの内容は「404 Not Found」で見てみてください。

このうち2,3が重い処理で、4.は軽いけどたくさんつぶやく場合は時間がかかる。

何回かテストしたけど、2/3ぐらいの確率で3.の処理中にkillされた。

運良く4まで動いても、そこで確実にkillされた。

ちなみに2.の処理は30秒くらい、3.の処理は50秒くらいかかっている。


さくらさんに問い合わせたところ

さくらのレンタルサーバではサーバの負荷対策のため、一定以上のメモリを
使用しているプロセスや、一定時間以上起動し続けているプロセスは自動的に
強制終了を行うよう設定を行っております。

そして具体的な数値は非公開とのこと。じゃあ試してみんとわからんな!


試行錯誤

どんな条件でkillされるかわからないから、いろいろ試して条件を探ってみた。

  • もしかして処理時間が長いと全部killされるんじゃないか
    • テスト1:1秒ごとにechoで数字を吐くバッチを動かしてみる。
      • 結果:見事5分間完走。パチパチパチ。
    • テスト2:4.の処理だけ単独で動かしてみる。sleepの時間も伸ばして。
      • 結果:8時間かけて処理完走。
    • 結論:処理時間の長さだけではkillされない。
  • 一時的にでも負荷の高くなるプロセスが、一定時間以上動作するとkillされるのではないか。
    • テスト:2,3の処理を、それぞれ単独で実行
      • 結果:2.の処理は1/2くらいの確率でkillされた。処理開始からkillされるまでの時間は最短で25秒。3.の処理は100%完走。
  • 2.の処理でメモリを食い過ぎてるんじゃないか
    • スクレイピングはページごとに関数を呼んで必要なデータだけ取得してるから、関数が終わったらメモリは解放されるはず。
  • 2.の処理の負荷が高すぎるんじゃないか
    • テスト:2.の処理で処理するHTMLのページ数を5ページに制限。これまでは9ページのスクレイピングを実施していた。
      • 結果:100%処理完走。
    • でもスクレイピングは並列で実行しているわけではないので、瞬間の負荷は変わっていないはず。

ここまでのテストで、ある程度高負荷な状態が一定時間以上続いたらkillされるのではないか、という仮説を得た。

あと高負荷な状態を短くすることで、長いバッチも動かせるようになった。よかった。


結論

こんなことで苦労するならさくらのVPS

借りたほうがいい。

あと「404 Not Found」をよろしくたのみますよ。