Lsyncdを使って、Linux上のファイルを（ほぼ）リアルタイムにS3にアップロードする

# 概要
Linuxサーバー上の特定のディレクトリにファイルの追加・削除・変更があった際に、（ほぼ）リアルタイムにS3上にアップロードを行える。
サーバー上の特定のディレクトリが、頻繁に更新が発生しディレクトリ内のファイル数が多い際など、通常のS3Syncなどでは全ファイル対象で同期するので、ちょっと同期するだけでも日が暮れてしまう。のを何とかするため。

Lsyncdて便利だけど、すぐ荒ぶるのよね・・・ぼそっ

## Lsyncdについて
Linux の kernel 2.6.13以降に組み込まれている inotify　を利用し、
ファイルの追加・削除・変更などをトリガーとしてファイルの同期を行うしくみ。

## LsyncdコマンドのS3への専用化
S3同期専用のLsyncdコマンド「Lsyncd_s3」をソースからインストールする。

### 備考
ディレクトリAの同期先がサーバー、ディレクトリBの同期先がS3となるような場合など、1つのLsyncdコマンド内でサーバー・S3と複数の動機先を指定できるが、
対象ディレクトリが多くなるにつれて、とくにS3の同期が（あまり）安定しないため、S3専用のLsyncdプロセスを用いている。

## monitのインストール
荒ぶられるLsyncd様の怒りを鎮めるために、monitをインストールまでを行う、優しさ仕様

# Lsyncdコマンドのインストールと設定
## ソースの展開とインストール
```bash:コマンド
cd /usr/local/src
# srcディレクトリへ移動
 
wget https://lsyncd.googlecode.com/files/lsyncd-2.1.5.tar.gz
tar zxvf lsyncd-2.1.5.tar.gz
# ソースのダウンロードと解凍

cd lsyncd-2.1.5
# 解凍したディレクトリへ移動

./configure --prefix=/usr/local/lsyncd_s3 --program-suffix=_s3
# インストールパスの明示的な指定と、パッケージでインストールされたLsyncdとの混同を防ぐため、コマンドの語尾に「_s3」と指定

make
make install
# コンパイル＆インストール
```

## 起動スクリプト
※Lsyncdパッケージに含まれる起動スクリプトを拝借

```bash:/etc/init.d/lsyncd_s3
#!/bin/bash
#
# chkconfig: - 85 15
# description: Lightweight inotify based sync daemon
#
# processname:  lsyncd_s3
# config:       /etc/lsyncd_s3.conf
# config:       /etc/sysconfig/lsyncd_s3
# pidfile:      /var/run/lsyncd_s3.pid

# Source function library
. /etc/init.d/functions

# Source networking configuration.
. /etc/sysconfig/network

# Check that networking is up.
[ "$NETWORKING" = "no" ] && exit 0

LSYNCD_OPTIONS="-pidfile /var/run/lsyncd_s3.pid /etc/lsyncd_s3.conf"
# lsyncd_s3 用に変更
if [ -e /etc/sysconfig/lsyncd_s3 ]; then
  . /etc/sysconfig/lsyncd_s3
fi
# lsyncd_s3 用に変更

RETVAL=0

prog="lsyncd_s3"
thelock=/var/lock/subsys/lsyncd_s3
# lsyncd_s3 用に変更

start() {
	[ -f /etc/lsyncd_s3.conf ] || exit 6
# lsyncd_s3 用に変更
        echo -n $"Starting $prog: "
        if [ $UID -ne 0 ]; then
                RETVAL=1
                failure
        else
                daemon /usr/local/lsyncd_s3/bin/lsyncd_s3 $LSYNCD_OPTIONS
# lsyncd_s3 用に変更
                RETVAL=$?
                [ $RETVAL -eq 0 ] && touch $thelock
        fi;
        echo
        return $RETVAL
}

stop() {
        echo -n $"Stopping $prog: "
        if [ $UID -ne 0 ]; then
                RETVAL=1
                failure
        else
                killproc lsyncd_s3
                RETVAL=$?
# lsyncd_s3 用に変更
                [ $RETVAL -eq 0 ] && rm -f $thelock
        fi;
        echo
        return $RETVAL
}

reload(){
        echo -n $"Reloading $prog: "
        killproc lsyncd_s3 -HUP
# lsyncd_s3 用に変更
        RETVAL=$?
        echo
        return $RETVAL
}

restart(){
        stop
        start
}

condrestart(){
    [ -e $thelock ] && restart
    return 0
}

case "$1" in
  start)
        start
        ;;
  stop)
        stop
        ;;
  restart)
        restart
        ;;
  reload)
        reload
        ;;
  condrestart)
        condrestart
        ;;
  status)
        status lsyncd_s3
        RETVAL=$?
        ;;
  *)
        echo $"Usage: $0 {start|stop|status|restart|condrestart|reload}"
        RETVAL=1
esac

exit $RETVAL
```


## lsyncd_s3.conf の設定例

```bash:/etc/lsyncd_s3.conf
settings{
  logfile = "/var/log/lsyncd/lsyncd_s3.log",
# 出力ログを指定
  statusFile = "/tmp/lsyncd_s3.stat",
# ステータスファイルを指定
  statusInterval = 1,
  nodaemon = false,
  delay    = 15,
}

-- ------- s3 ------- 
# LsyncdはLua言語で書かれているので、コメントアウトは −− らしい。
s3sync = {
    maxProcesses = 1,
    onCreate = "[ -f ^source^pathname ] && aws s3 cp ^source^pathname ^target^pathname || true",
    onModify = "[ -f ^source^pathname ] && aws s3 cp ^source^pathname ^target^pathname || true",
    onDelete = "[ -f ^source^pathname ] && aws s3 rm ^target^pathname || true",
--  onMove = "aws s3 mv ^target^o.pathname ^target^d.pathname",
# onCreate,onModify,onDelete,onMove それぞれのトリガー毎の挙動を定義する
# 運用上 mv でLsyncdがコケることが多かったので、今回は mv をコメントアウト
}

sync {
  s3sync,
  source = "/home/hogeuser/images01",
  target = "s3://hoge-imagedata/images01",
}
# ディレクトリ"/home/hogeuser/images01"を バケット"hoge-imagedata"内の"images01"へと同期する
sync {
  s3sync,
  source = "/home/hogeuser/images02",
  target = "s3://hoge-imagedata/images02",
# ディレクトリ"/home/hogeuser/images02"を バケット"hoge-imagedata"内の"images02"へと同期する
}
```

### 事前準備
aws コマンドを利用するので、下記などを参考に該当のS3バケットに接続ができる用準備をしておく。
[AWS CLI のインストールと設定](http://docs.aws.amazon.com/ja_jp/kinesis/latest/dev/kinesis-tutorial-cli-installation.html)

## Lsyncdの起動
```bash:コマンド
/etc/init.d/lsyncd_s3 start
```

# monit の インストールと設定
## monit のインストール
yum コマンドでインストールする場合、epelリポジトリが必要です。

```bash:コマンド
yum install monit
```

## monit の設定

### アラート送信の全般設定

```bash:/etc/minit.conf
set daemon 60

include /etc/monit.d/*

set mailserver 127.0.0.1
# アラート発生時のメール送信に利用するSMTPサーバーを指定
set alert hogehoge@hogehoge.com
# アラート送信先メールアドレス

set mail-format {
from: monit@hogehoge.com
# メール送信元アドレス
subject: $HOST : $SERVICE - $EVENT
message: Monit
ACTION  : $ACTION
SERVICE : $SERVICE
at $DATE on $HOST.
DESCRIPTION : $DESCRIPTION
}
```

### プロセス監視の設定

```bash:/etc/monit.d/lsyncd_s3
check process lsyncd_s3
    with pidfile "/var/run/lsyncd_s3.pid"
    # LsyncdのPIDファイルの指定
    start program "/etc/init.d/lsyncd_s3 start"
    stop program "/etc/init.d/lsyncd_s3 stop"
    # プロセスのスタート・停止コマンドの指定
    if 3 restarts within 3 cycles then unmonitor
    # 3回再起動に失敗したら、監視の停止
```

## monit の起動
```bash:コマンド
/etc/init.d/monist start
```

# 以上！
これで、Lsyncd_S3様は、機嫌よくS3と動機し続けてくれるはず！！