FTPで受信したファイルをイベントドリブンで処理させてみる

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ウィスキー、シガー、パイプをこよなく愛する大栗です。 AWSでファイルのアップロード等は通常S3を使用していると思いますが、深遠な理由によりEC2上でFTPサーバを使用する場合が有ると思います。S3と異なりEC2はファイルが消える可能性が残っているので、ファイルの受信後にすぐ処理を行いと思います。ここではlsyncdを使用して対応してみました。

lsyncd

lsyncdはrsyncdと連動してリモートサーバへファイルのミラーリングを行うソフトウェアです。 lsyncdでは監視しているファイルのイベント処理をフックして外部の処理を行えますでの、それを利用します。

lsyncd_s3

各種設定

環境

以下の環境で試しています。

OS    :Cent OS 6.5 FTP   :vsftpd 2.2.2 lsyncd:lsyncd 2.1.4

設定

FTP

diff vsftpd.conf.org vsftpd.conf

12c12
< anonymous_enable=YES
---
> anonymous_enable=NO
81,82c81,82
< #ascii_upload_enable=YES
< #ascii_download_enable=YES
---
> ascii_upload_enable=YES
> ascii_download_enable=YES
97c97
< #chroot_list_enable=YES
---
> chroot_list_enable=YES
99c99
< #chroot_list_file=/etc/vsftpd/chroot_list
---
> chroot_list_file=/etc/vsftpd/chroot_list
105c105
< #ls_recurse_enable=YES
---
> ls_recurse_enable=YES
119a120,128
> 
> pasv_promiscuous=YES
> 
> pasv_min_port=50000
> pasv_max_port=50030
> 
>

chroot_list

ftpuser

ここでftpuserというOSユーザも作成しています。

lsyncd

lsyncdの設定は"/usr/share/doc/lsyncd-2.1.4/examples/lecho.lua"を元に作成しました。

/etc/lsyncd.conf

-----
-- User configuration file for lsyncd.
--
-- This example uses local bash commands to keep two local
-- directory trees in sync.
--

-----
-- for testing purposes. just echos what is happening.
--

settings = {
        logfile = "/var/log/lsyncd.log",
        statusFile = "/tmp/lsyncd.stat",
        nodeamon = false,
}

echo = {
        maxProcesses = 1,
        onStartup = "echo telling $(date --rfc-3339=seconds) about ^source | tee -a /tmp/lsyncd_status.txt",
        onCreate  = "echo create  $(date --rfc-3339=seconds) ^sourcePath | tee -a /tmp/lsyncd_status.txt",
        onDelete  = "echo delete  $(date --rfc-3339=seconds) ^sourcePath | tee -a /tmp/lsyncd_status.txt",
        onModify  = "echo modify  $(date --rfc-3339=seconds) ^sourcePath | tee -a /tmp/lsyncd_status.txt",
        onMove    = "echo move    $(date --rfc-3339=seconds) ^o.sourcePath -> ^d.sourcePath | tee -a /tmp/lsyncd_status.txt",
}

sync{echo, source="/home/ftpuser", target="/tmp/dst/"}

このように、onCreateやonDelete、onModifyで外部コマンドを呼び出して、対象のファイルのパスを "/tmp/lsyncd_status.txt" へ保存しています。

動作確認

ftp経由でファイルをアップロードします。

ファイルのアップロード

ftp> put text1.txt

出力ファイル(/tmp/lsyncd_status.txt)

create 2014-11-20 06:02:28+00:00 /home/ftpuser//text1.txt
modify 2014-11-20 06:02:28+00:00 /home/ftpuser//text1.txt

Vvsftpdではファイルアップロード時に、一度保存した後にファイルの変更を行っているようです。

ファイルの削除

ftp経由でファイルを削除します。

ftp> del text1.txt

出力ファイル(/tmp/lsyncd_status.txt)

delete 2014-11-20 06:02:32+00:00 /home/ftpuser//text1.txt

ディレクトリの作成

ftp経由でディレクトリを作成します。

ftp> mkdir abd_dir

出力ファイル(/tmp/lsyncd_status.txt)

create 2014-11-20 06:00:45+00:00 /home/ftpuser//abc_dir/

ディレクトリの削除

ftp経由でディレクトリを削除します。

ftp> rmdir abd_dir

出力ファイル(/tmp/lsyncd_status.txt)

delete 2014-11-20 06:00:56+00:00 /home/ftpuser//abc_dir/

2014/11/20 18:25 追記

アップロードされたファイルをS3へ保存する例を書いてみました。"s3://lsyncd-to-s3-20141120"というS3バケットへ保存します。ここではmaxProcessesを10にして並列度を10にします。

/etc/lsyncd.conf

-----
-- User configuration file for lsyncd.
--
-- This example uses local bash commands to keep two local
-- directory trees in sync.
--

-----
-- for testing purposes. just echos what is happening.
--

settings = {
        logfile = "/var/log/lsyncd.log",
        statusFile = "/tmp/lsyncd.stat",
        nodeamon = false,
}

echo = {
        maxProcesses = 10,
        onStartup = "echo telling $(date --rfc-3339=seconds) about ^source | tee -a /tmp/lsyncd_status.txt",
        onCreate  = "aws s3 cp ^sourcePathname ^targetPathname | tee -a /tmp/lsyncd_status.txt",
        onDelete  = "aws s3 rm ^targetPathname | tee -a /tmp/lsyncd_status.txt",
        onModify  = "aws s3 cp ^sourcePathname ^targetPathname | tee -a /tmp/lsyncd_onModify.txt",
        onMove    = "echo move    $(date --rfc-3339=seconds) ^o.sourcePath -> ^d.sourcePath | tee -a /tmp/lsyncd_status.txt",
}

sync{echo, source="/home/ftpuser", target="s3://lsyncd-to-s3-20141120"}

この状態で1001.dat〜1010.datまでの10個のファイルを保存すると、以下の様に10プロセスが平行してアップロードできる事が分かります。

top - 09:06:34 up 17 min,  3 users,  load average: 0.80, 0.26, 0.26
Tasks: 187 total,   1 running, 186 sleeping,   0 stopped,   0 zombie
Cpu(s): 27.9%us,  6.2%sy,  0.0%ni, 64.2%id,  0.0%wa,  0.8%hi,  1.0%si,  0.0%st
Mem:  15297700k total,  1663452k used, 13634248k free,     8520k buffers
Swap:        0k total,        0k used,        0k free,  1072620k cached

  PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                      
 2183 root      20   0 1122m  37m 4676 S 31.3  0.3   0:00.94 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1008.dat s3://lsyncd-to-s3-20141120/da
 2168 root      20   0 1122m  39m 4676 S 30.3  0.3   0:00.91 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1003.dat s3://lsyncd-to-s3-20141120/da
 2173 root      20   0 1122m  37m 4676 S 29.3  0.3   0:00.88 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1005.dat s3://lsyncd-to-s3-20141120/da
 2171 root      20   0 1122m  39m 4672 S 28.9  0.3   0:00.87 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1007.dat s3://lsyncd-to-s3-20141120/da
 2175 root      20   0 1122m  37m 4672 S 28.9  0.3   0:00.87 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1001.dat s3://lsyncd-to-s3-20141120/da
 2181 root      20   0 1122m  39m 4676 S 28.9  0.3   0:00.87 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1009.dat s3://lsyncd-to-s3-20141120/da
 2185 root      20   0 1122m  39m 4672 S 28.9  0.3   0:00.87 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1010.dat s3://lsyncd-to-s3-20141120/da
 2167 root      20   0 1122m  39m 4672 S 28.6  0.3   0:00.86 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1004.dat s3://lsyncd-to-s3-20141120/da
 2179 root      20   0 1122m  39m 4676 S 28.3  0.3   0:00.85 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1006.dat s3://lsyncd-to-s3-20141120/da
 2166 root      20   0 1122m  39m 4676 S 27.6  0.3   0:00.83 /usr/bin/python /usr/bin/aws s3 cp /home/ftpuser//data/1002.dat s3://lsyncd-to-s3-20141120/da
 1691 root      20   0 15028 1368  992 R  0.3  0.0   0:00.93 top

 

さいごに

lsyncdをファイルレプリケーションツールではなく、ファイルイベント検知フレームワークとして使用してみました。今回はechoを行っただけでしたが、同様に外部コマンドを呼ぶ事でftp受信後の自動バックアップ等も実装可能だと思いますので、皆さんで工夫してみて下さい。