motionの画像ファイルをs3fsを使いamazon S3に保存する
以前のエントリーでmotionの書き出し先をsshfs上に行う記事を掲載しました。
今回リモート書き出し先の選択肢としてamazon S3を検討してみたいと思います。
1. amazon S3のバケットを用意する
通常と同じ方法でS3のバケットを用意します。その際、IAMでAmazonS3FullAccessのユーザーを作成し、Access Key IDとSecret Access Keyを取得しておきます。
2. Raspberry Piにs3fsをインストール
$ sudo aptitude install fuse-utils automake build-essential pkg-config libfuse-dev libcurl4-openssl-dev libxml2-dev
$ cd /usr/local/src
$ sudo git clone https://github.com/s3fs-fuse/s3fs-fuse.git
$ sudo chown -R pi:pi s3fs-fuse
$ cd s3fs-fuse/
$ ./autogen.sh
$ ./configure
$ make
$ sudo make install
FUSEとs3fsのmakeに必要なパッケージをaptitudeを使ってインストールします。
その後、s3fs-fuseのgithubリポジトリからmasterをcloneします。ネットの情報ですとgooglecodeからzipファイルをダウンロードするように書いてある物が多いですが、そちらの更新は止まっており最新版はgithubにありますので注意しましょう。実は最初自分もその間違いを犯してしまいました。
あとは普通にmakeしてmake installします。特に問題なくインストールできました。
3. s3fsの設定
$ echo "<Access Key ID>:<Secret Access Key>" | sudo tee /etc/passwd-s3fs
$ sudo chmod 640 /etc/passwd-s3fs
$ sudo mkdir /mnt/s3fs
Access Key IDとSecret Access Keyをコロンで繋いだ物を/etc/passwd-s3fsとして保存します。今回s3fsのマウント用のディレクトリは/mnt/s3fs/にしました。
4. s3fsのマウント
$ sudo s3fs <バケット名> /mnt/s3fs/ -o allow_other
これでエラーが表示されなければマウント成功です。
5. motionの画像ファイルの書き出し先を変更
$ sudo vi /etc/motion/motion.conf
-----
target_dir /mnt/s3fs
-----$ sudo service motion restart
これでファイルの書き出し先がs3fs上になりました。
しかし、、、ファイルが書き出されません。失敗です。
色々と試してみましたが、motionを起動した途端s3fsが応答を返さなくなります。motionを停止してもs3fsは無応答のまま。この状態でバケットの中身をWebなどで見てもファイルは書き出されていません。
これはmotionが動画ファイルを書き出しますが、そのファイルハンドルがオープンになったままなのが原因ではないかと推測しています(あくまで推測です)。
6. cronでrsyncする方法をためしてみる
そこでmotionのファイル自体はローカルのSDカード上に書き出し、定期的にcronでrsyncする方法をためしてみました。
すると、2点問題がでました。
- "rsync: failed to set times on "/mnt/s3fs/.": Input/output error (5)"エラーが発生する
- ファイルの書き込みが体感で遅い
1の問題はs3fsのFUSE実装でファイルのtouch動作が出来ないためと思われます。これはS3に"Last Modified"属性はあるもののFile Stat的な属性変更の仕組みが無い事によるのかもしれません。
2の問題は通常のファイル転送にくらべ遅さを感じた、としか言いようがありません。「あれ、こんなにS3の転送って遅かったっけ?」と思いました。
7. s3fsの転送時間を計測してみる
ただ「感じた」だけでは仕方がありませんので実測してみます。
転送用のファイルを以下のコマンドでSDカード上に作成します。
$ dd if=/dev/zero of=zero_1M.dat count=1 bs=1M
$ dd if=/dev/zero of=zero_10M.dat count=10 bs=1M
$ dd if=/dev/zero of=zero_15M.dat count=15 bs=1M
$ dd if=/dev/zero of=zero_20M.dat count=20 bs=1M
これで1MB, 10MB, 15MB, 20MBのファイルが用意できました。
- s3fs, sshfs, localの3つを比べる
- localは同一ファイルシステム上の単純なコピー
- 転送は単純にcpコマンドで行う
- 1MB, 10MB, 15MB, 20MBのファイルをそれぞれ10回転送し平均時間を計測
- 時間の計測にはtimeを利用( $ time cp zero_1M.dat /mnt/s3fs/. )
- s3fsのバケットがTokyoリージョンにあるので、sshfs用のサーバもEC2のTokyoリージョンに用意
結果が以下です。
水色がs3fs、灰色がsshfs、黄色がlocalです。
localが爆速なのは当たり前ですがs3fsがsshfsに比べ倍近く遅いことが解ります。また、sshfs, localの二つにくらべs3fsのオーバーヘッドが1秒以上ある事がわかります。
今回のmotionの画像ファイルサイズが1MB前後で、設定によっては1秒間に数枚作成される事を考えると、このオーバーヘッドは痛いです。
8. 結論
これだけのテストで結論を出すのは早計かもしれませんが、少なくとも単純なファイルシステムとしてs3fsを使ってmotionの画像ファイルをS3上に保存するのは難しいようです。
S3のバケットのプロパティで細かな設定が可能ですので、そういった利点を生かすのであれば選択肢としてあげられるかも知れませんが、この利用方法だけに限定すれば少しオーバースペックのようにも感じました。
sshfsもs3fsもFUSEベースのファイルシステムなので、この性能差はs3fsの実装にあるのではないかと考えられますが、それ以上の事は今回は解りませんでした。
しかしs3fsは設定が簡単である事や手軽にS3が利用出来るので、利点と欠点を把握した上で活用したいソリューションです。