#制約
Git禁止(協力会社がFTPしか使えないため)
#結論
- Master Serverを建てる
- Master Serverのファイルの更新をlsyncdで監視し、常にS3と同期する
- 任意のタイミングでSlave Server(ELB配下の全EC2インスタンス)をS3と同期する
#イメージ図
だいたいこんな感じ
#Master Server編
###1. S3バケットを作成する
公式サイトに詳しい方法が書いてあります。
S3 バケットを作成する方法 - Amazon Simple Storage Service
###2. AWS CLIを設定する
公式サイトに詳しい方法が書いてあります。
AWS CLI の設定 - AWS Command Line Interface
###3. lsyncdをインストールする
EPELリポジトリを利用してインストールします。
$ sudo yum install --enablerepo=epel lsyncd
###4. lsyncdの設定を変更する
普通の書き方だとファイル名の末尾に/(スラッシュ)
が混入してエラーが出たりうまくsyncしてくれなかったので、
下記のような感じでパースしてあげる必要があります。
komeda-shinjiさんの記事がとても参考になりました。ありがとうございます。
$ sudo vim /etc/lsyncd.conf
source_dir = "/var/www/source"
s3bucket = "files.hoge.com"
prefix = "source"
snscmd = "echo !!! error "
settings {
logfile = "/var/log/lsyncd.log",
statusFile = "/var/log/lsyncd.status",
nodaemon = false,
statusInterval = 1,
delay = 5,
}
cp = function(event)
local src_path = event.sourcePathname
local dst_path = event.targetPathname
if (string.sub(event.source, -1, -1) == "/") then
src_path = string.sub(event.source, 1, -2) .. event.pathname
end
if (string.sub(event.target, -1, -1) == "/") then
dst_path = string.sub(event.target, 1, -2) .. event.pathname
end
local s3cmd = "aws s3 cp '" .. src_path .. "' '" .. dst_path .. "'"
local msg_body = "command failed: " .. s3cmd
local msg = " --message '" .. string.gsub(msg_body, "'", "\"") .. "'"
local runcmd = "rc=0 && [ -f '" .. src_path .. "' ] && for try in 1 2 3; do " .. s3cmd .. "; rc=$?; [ $rc -eq 0 ] && break; done || " .. snscmd .. msg .. " || :"
spawnShell(event, runcmd)
end
rm = function(event)
local src_path = event.sourcePathname
local dst_path = event.targetPathname
if (string.sub(event.source, -1, -1) == "/") then
src_path = string.sub(event.source, 1, -2) .. event.pathname
end
if (string.sub(event.target, -1, -1) == "/") then
dst_path = string.sub(event.target, 1, -2) .. event.pathname
end
local s3cmd = "aws s3 rm '" .. dst_path .. "'"
local msg_body = "command failed: " .. s3cmd
local msg = " --message '" .. string.gsub(msg_body, "'", "\"") .. "'"
local runcmd = "rc=0 && [ ! -f '" .. src_path .. "' ] && for try in 1 2 3; do " .. s3cmd .. "; rc=$?; [ $rc -eq 0 ] && break; done || " .. snscmd .. msg .. " || :"
spawnShell(event, runcmd)
end
mv = function(event)
local src_path = event.o.targetPathname
local dst_path = event.d.targetPathname
if (string.sub(event.o.target, -1, -1) == "/") then
src_path = string.sub(event.o.target, 1, -2) .. event.o.pathname
end
if (string.sub(event.d.target, -1, -1) == "/") then
dst_path = string.sub(event.d.target, 1, -2) .. event.d.pathname
end
local s3cmd = "aws s3 mv '" .. src_path .. "' '" .. dst_path .. "'"
local msg_body = "command failed: " .. s3cmd
local msg = " --message '" .. string.gsub(msg_body, "'", "\"") .. "'"
local runcmd = "rc=0 && [ -f '" .. src_path .. "' ] && for try in 1 2 3; do " .. s3cmd .. "; rc=$?; [ $rc -eq 0 ] && break; done || " .. snscmd .. msg .." || :"
spawnShell(event, runcmd)
end
s3sync = {
maxProcesses = 1,
onCreate = cp,
onModify = cp,
onDelete = rm,
-- onMove = mv,
}
sync {
s3sync,
source = source_dir,
target = "s3://" .. s3bucket .. "/" .. prefix,
}
###5. lsyncdを起動する
$ sudo /etc/rc.d/init.d/lsyncd start
$ sudo chkconfig lsyncd on
$ /etc/rc.d/init.d/lsyncd status
lsyncd (pid 12345) is running...
###6. Sourceを変更する
$ vim /var/www/source/hoge.txt
hogehoge
###7. Sourceの変更がS3に反映しているか確認する
$ tailf /var/log/lsyncd.log
#Slave Server編
###1. AWS CLIを設定する
公式サイトに詳しい方法が書いてあります。
AWS CLI の設定 - AWS Command Line Interface
###2. S3のSourceをローカルに同期するシェルスクリプトを作成する
$ vim /usr/local/bin/s3sync.sh
#!/bin/sh
SOURCE_DIR="/var/www"
S3_BUCKET="files.hoge.com"
PREFIX="source"
TARGET_MASTER="s3://${S3_BUCKET}/${PREFIX}/"
TARGET_LOCAL="${SOURCE_DIR}/${PREFIX}/"
aws s3 sync ${TARGET_MASTER} ${TARGET_LOCAL} --delete
###3. 同期スクリプトをEC2インスタンス起動時に実行するように設定する
$ vim /etc/rc.local
s3sync.sh
exit 0
※ちなみに、rc.localに書かれたスクリプトはroot権限で実行されます。
###4. 任意のタイミングで同期スクリプトを実行する
cronするなり、execするなり
#ボツ案
###Master Server+rsyncパターン
- Master ServerのEC2インスタンスがSPOFになってしまう
- 参考文献:CDP:Clone Serverパターン - AWS-CloudDesignPattern
- 参考文献:【AWS】rsyncでEC2インスタンスを同期 - Qiita
- 参考文献:同期設定(rsync)を今一度整理してみました - Qiita
###s3Syncパターン
- 監視ツールを入れない場合、cronなどで定期的に同期する必要がある
- 参考文献:【aws】オートスケーリング(Auto Scaling)を実際に動かしてみてec2の冗長化に入門する - とりあえずphpとか
- 参考文献:~AutoScalingのコンテンツ同期~ | ナレコムAWSレシピ
###s3fsパターン
- 速度が遅い
- 動作が不安定
- パーミッションバグがある
- 参考文献:AWS s3fsを使って複数EC2インスタンスに共有ストレージを作る – Hiro Fukami's Blog
###NFSパターン
- NFSインスタンス分のコストがかかる
- どうせなら、Amazon EFSの東京リージョンを待ちたい
- 参考文献:CDP:NFS Sharingパターン - AWS-CloudDesignPattern
###AMIを最新にしてから起動するパターン
- ファイル更新の度に起動し直す必要がある
- 参考文献:AutoScaling導入によって得たメリットと気をつけたいポイント - Qiita