複数の VM で cron のタイミングをずらす
前々から気になってはいたんですが、 VMware を使って複数の Linux ゲストOSを起動している場合、デフォルト設定ではそれぞれほぼ同時にシステム cron ジョブを実行し始めます。とくに slocate パッケージを導入している場合、 locate コマンド用のデータベースを更新するために凄い勢いで HDD にアクセスしにいきます。先日のサーバー電源吹っ飛び事件のこともあり、だんだん怖くなってきたので(笑)このあたりを改善することにしました。
具体的には、システム crontab を変更してジョブの実行タイミングをずらしてやります。大した作業ではありませんが、システム crontab 変更の手順からご紹介しようと思います。
システム crontab の変更方法
一般的な UNIX 互換システムでは、システムの cron ジョブは "/etc/crontab" に記述されています。 Gentoo Linux ではここに毎時、毎日、毎週、毎月などのエントリーがデフォルトで記述されており、それぞれ "/etc/cron.hourly", "/etc/cron.daily", "/etc/cron.weekly", "/etc/cron.monthly" の各ディレクトリにあるスクリプトを実行するようになっています(実際にはもうちょっと複雑です。詳細は後述)。毎日の朝 3 時ごろに HDD がカリカリ言い出すのは、 "/etc/cron.daily/slocate" が実行されて locate コマンド用のデータベースが更新されるからです。したがって、このシステム crontab の内容を変更すれば、各ジョブの起動時間を制御できるわけです。
"/etc/crontab" の書式は通常の crontab と同じですが、 6 番目のフィールドにコマンドを実行するユーザーを指定します。つまり、通常の crontab は以下の書式になりますが、
<分> <時> <日> <月> <曜日> <コマンド>
システム crontab("/etc/crontab")は以下のようになります。
<分> <時> <日> <月> <曜日> <ユーザー名> <コマンド>
それだけ気をつければ、後の要素は通常ユーザーの crontab と変わりません。もし使っている cron が vixie-cron であれば、単純に "/etc/crontab" を編集するだけで設定を変更できます。 dcron や fcron などの場合は、編集後に以下のコマンドを実行する必要があります。
crontab /etc/crontab
システム crontab の変更方法がわかったら、次はシステム crontab の中身を見ていきましょう。
システム crontab の中身
実際のシステム crontab にはどんな内容が書いてあるのでしょうか。 Gentoo Linux のデフォルトでは、 "/etc/crontab" の内容は以下のようになっているはずです(コメントは省略しています)。
# Global variables SHELL=/bin/bash PATH=/sbin:/bin:/usr/sbin:/usr/bin MAILTO=root HOME=/ # check scripts in cron.hourly, cron.daily, cron.weekly and cron.monthly 0 * * * * root rm -f /var/spool/cron/lastrun/cron.hourly 1 3 * * * root rm -f /var/spool/cron/lastrun/cron.daily 15 4 * * 6 root rm -f /var/spool/cron/lastrun/cron.weekly 30 5 1 * * root rm -f /var/spool/cron/lastrun/cron.monthly */10 * * * * root test -x /usr/sbin/run-crons && /usr/sbin/run-crons
上半分は環境変数の設定ですので、あまり重要ではありません。実際に cron ジョブを定義しているのは下半分のエントリーなのですが、なにやら変な小細工をしている雰囲気ですね。上 4 つは定期的に "/var/spool/cron/lastrun" 以下のファイルを削除していて、最後のひとつは 10 分ごとに "/usr/sbin/run-crons" というスクリプトを実行しています。
どうやら、 run-crons スクリプトが "/var/spool/cron/lastrun" 以下のファイルのタイムスタンプを監視していて、もしそれらのファイルが一定時間変更されていないか、もしくはファイル自体が存在しなければ、対応する "/etc/cron.*" 内のスクリプトを実行するようになっているようです。
なぜこんな回りくどいことをしているのかというと、実は私も正確には知りません(^^ゞ。 run-crons スクリプトの中を軽く覗いた限りですが、以下の 2 点が理由だと思います。
- 複数のシステム cron ジョブが同時に実行されるのを防ぐ。
- システムがシャットダウンされていたなどでジョブが実行されていなかった場合に、速やかに実行する。
いずれにせよ、システムの cron ジョブの実行タイミングを変更するには、単純に上 4 つのエントリーの実行時間を変更するだけでよさそうです。
システム crontab を変更する
ちょっと説明が長くなってしまいました。けっきょく、今回の目的を達成するには、 "/etc/crontab" 内の run-crons の実行以外のエントリーの実行時間をずらしてやれば良さそうです。例を示すまでもないとは思いますが、私の備忘録も兼ねて設定を載せておきます。私のところではメールサーバーと Web サーバーの 2 つのゲストOSが稼動しているので、両方とも載せておきますね。
まず、メールサーバーのほう。
30 * * * * root rm -f /var/spool/cron/lastrun/cron.hourly 1 3 * * * root rm -f /var/spool/cron/lastrun/cron.daily 1 5 * * 6 root rm -f /var/spool/cron/lastrun/cron.weekly 1 6 1 * * root rm -f /var/spool/cron/lastrun/cron.monthly */10 * * * * root test -x /usr/sbin/run-crons && /usr/sbin/run-crons
そして、 Web サーバーはこんな感じ。
0 * * * * root rm -f /var/spool/cron/lastrun/cron.hourly 1 4 * * * root rm -f /var/spool/cron/lastrun/cron.daily 31 5 * * 6 root rm -f /var/spool/cron/lastrun/cron.weekly 31 6 1 * * root rm -f /var/spool/cron/lastrun/cron.monthly */10 * * * * root test -x /usr/sbin/run-crons && /usr/sbin/run-crons
fcron, dcron の場合、 "/etc/crontab" を変更した後に上述の crontab コマンドを実行するのを忘れないでください。
私はお寝坊さんなので朝 7 時前に作業をすることはほとんどなかろうということで、ジョブの実行タイミングを 6 時台まで伸ばし、双方交互にジョブを実行するようにしました。とくに locate コマンドのデータベース更新を行う daily のジョブは双方とも 1 時間の間隔を空けるようにしています。これで、2 つの VM が同時に locate データベースを更新するようなことはなくなるでしょう。やれやれ。
ということで、本日はとくに VMware で複数の Linux ゲストOSを実行している状況のために、システム cron ジョブの実行タイミングをずらす方法をご紹介しました。「俺は早朝に頭の回転が良くなるんだから、 cron ジョブの実行は昼頃にしてくれ!」なんて人にもお勧めです(笑)。では、今回はこのへんで。
詳しくはこちらの記事をどうぞ!
この記事にコメントする