Linux::Inotify2

皆さん、こんにちは。
アドウェイズエンジニアの孟です。

今日は perl の話をしたいと思います。
perlLinux::Inotify2 というモジュールの使い方を紹介します。

inotifyってなに?
ファイルシステムのイベント監視をしてくれる機能です。Linux 2.6.13 カーネルから組み込まれたそうです。

inotifyを使って何ができるの?
サーバ間の同期作業は普段 rsync でされている方が多いのではないでしょうか。例えば、定期的に cron で rsync を叩いて同期させるパターンが多いように思います。
 
例えばフロントの web サーバ。ユーザがこのサーバに何かをアップロードして、これを複数台ある他の web サーバへ同期しないといけない時。しかもこれがすごく重要で、リアルタイムで反映してほしいと。そういう場合 inotify を使うと超便利です。

(そもそも共有ストレージを使え!っていう声もあると思いますが、ほとんどの障害が共有ストレージで発生してるからね!あかん)

inotify の何が便利かというと、ユーザがファイルをアップするディレクトリを inotify で監視しておくと、ファイルが生成されたり、削除された際に、ファイルシステムからイベント情報をリアルタイムでキャッチすることができるのです。そして、事前に書いておいたコールバックを呼び出して、様々な処理を実行することが出来ます。

コールバックには、ファイルの名前やパスなどの情報が渡されるので、これを使うとファイルを他のサーバへ同期させたりすることがリアルタイムでできてしまいます。


サンプルを用意しました。/tmp 監視用の script です。

#! /usr/bin/perl
use Linux::Inotify2;
use AnyEvent::IO;

my $path = "/tmp";

my $no = Linux::Inotify2->new;
my @events = qw(
    IN_ACCESS IN_MODIFY IN_ATTRIB IN_CLOSE_WRITE
    IN_CLOSE_NOWRITE IN_OPEN IN_MOVED_FROM IN_MOVED_TO
    IN_CREATE IN_DELETE IN_DELETE_SELF IN_MOVE_SELF
);

$no->watch(
    $path,
    IN_MODIFY | IN_MOVED_TO | IN_MOVED_FROM | IN_CREATE | IN_DELETE,
    sub {
        my $e = shift;
        my $filename = $e->fullname;
        for (@events){
            if ($e->$_){
                print "$_: $filename\n";
                last;
            }
        }
    });
    my $inotify_w = AnyEvent->io (
        fh => $no->fileno, poll => 'r', cb => sub { $no->poll }
    );

1 while $no->poll;


↑の script を動かして、/tmp の下でファイルを操作してみてください。
ファイルの変更、移動、新規追加、削除、4つのイベントを監視するようしてます。


以上です。