## 後日談(2014.8.6)
やってみてわかったんですが、
rsyncだとS3への反映が遅いのと、設定間違えて更新頻度上がりすぎて課金地獄というリスクもあり、ちょっと使い勝手悪かったです。
いまだと、CloudFrontは配信元のExiresを優先してくれたり、HostなどのHTTPヘッダーや
Cookieを通過しそれぞれを考慮してキャッシュしてくれるようになっているので、普通のMT(非S3)+CloudFrontの方がお勧めだったりします。
[CloudFront + S3以外 というのも有力な選択肢だと思ってる](
http://blog.takeyu-web.com/2014/08/cloudfront-s3.html)
---
オーバースペックですが、練習も兼ねて、このブログを[MovableType6
AWS版](
http://www.sixapart.jp/movabletype/aws/)(micro
インスタンス) + [S3](
http://aws.amazon.com/jp/s3/) + [CloudFront](
https://aws.amazon.com/jp/cloudfront/)に移行しました。
## 構成
シンプルにこんな感じです。

- MT6(
AWS) micro
インスタンス
- S3FS
-
rsync
- S3 StaticWebHosting
- CloudFront
詳しい導入手順はあとでまとめて書きます。
また、AMIのアップデートの度にいちいち手作業は面倒なので、Chefレシピを書いておきたい。
### MT6(
AWS) micro
インスタンス
MTライセンス料無料がやっぱりありがたい。
通常の管理画面操作は高速で快適。再構築中などで負荷がかかっていなければ。
- [CPUバースト対策](
http://unching-star.hatenablog.jp/entry/2014/05/02/145200)
- [
Movable Type for
AWS(AMI)(
Amazon Linux AMI 2013.09)
yumエラー対策](
http://blog.takeyu-web.com/mt/2014/05/movable-type-for-awsamiamazon-linux-ami-201309-yum.html)
### S3FS
静的ファイルはすべてS3上に配置します。これにより、MTサーバ側が非力でも、コンテンツ配信の負荷は気にしなくてよくなるほか、たとえサーバが落ちてもページを表示することができます。
S3
APIを使用してアップロードする
プラグインや、s3cmdを使って自力で同期する
スクリプトを書く方法もあるのですが、今回はもっとも手軽で確実なS3FSと
rsyncを利用することにしました。
[s3fs-
fuse](
https://github.com/s3fs-fuse/s3fs-fuse)
これを使うことで、S3を
NFSのように扱うことができます。便利。
「他のS3クライアントと互換性がない」と言われ続けていたS3FSですが、昨年の1.68で対応済みとなっています。
[
ChangeLog for S3FS](
https://github.com/s3fs-fuse/s3fs-fuse/blob/master/ChangeLog)
[Issue 27: Feature Request: Compatability with other S3FS clients](
http://code.google.com/p/s3fs/issues/detail?id=27)
そのままMTの書き出し先にしてもよいですが、アクセスのたびにHTTPリクエストが発生するため、非常に遅いので、僕は
rsyncで同期を取るようにしています。
###
rsync
こんな感じの
スクリプトで同期しています。
`/etc/cron.d/s3sync`
```
SHELL=
/bin/sh
* * * * * root /bin/
bash /app/
movabletype/tools/s3sync.sh > /dev/null 2>&1
```
`/app/
movabletype/tools/s3sync.sh`
```
bash
#!/bin/
bash
LOCKFILE=/tmp/s3sync.lockfile
(
flock -n 200 || exit 1
/usr/bin/
rsync -avz --delete-after /data/file/static/ /mnt/blog.takeyu-web.com/
) 200>$LOCKFILE
```
### S3 Static Web Hosting
これを設定しないと、S3に置くだけでは`
http://blog.takeyu-web.com/mt/`のようなアクセスの時、`/mt/index.html`を返すことができません。
有効にすることでManagement Console上に表示されるエンドポイント(`Endpoint: bucketname.s3-website-ap-northeast-1.amazonaws.com`というやつ)をCloudFrontのOriginに設定します。
### CloudFront
S3は確かに安心なのですが、レスポンスは遅いので表示の高速化を行いたいときはCDNを組み合わせます。ここでは同じく
AWSのCloudFrontを利用しました。
とりあえず気をつけるのは、Originは自動補完されるS3のバケット名ではなく、StaticWebHostingのエンドポイントを指定することぐらいです。(小一時間ハマりました)
※なお、CloudFrontは別にS3でなくてもOriginに指定できるので、無理に使う必要はないです。
## 検討中のこと
### CloudFront側へのキャッシュ制御
MinimumTTLは有効期限を長くするために使うものなので、コレではない。
S3オブジェクトの
メタデータで指定できるが、いちいち設定できないので自動化したいところ。
AWS APIで
スクリプトを書く?
参考:[CloudFrontのキャッシュ有効期限を1時間にする(S3オリジン) - suz-lab](
http://blog.suz-lab.com/2011/06/cloudfront1s3.html)
### 更新から反映までのタイムラグ
Expiresの件とも絡んできますが
更新 → S3に同期 → CloudFrontキャッシュ切れ
ということでタイムラグが気になります。
更新の際に記事のHTMLだけでもS3にコピーの上、CloudFront の
API を叩いて Invalidating Object を登録するとかしたほうがいいかも。
## 発展可能性?
実証サイトはまだ作っていませんが、この仕組みを発展させてELBとたくさんのmicro
インスタンスを組み合わせることで、ユーザーログインや検索も高いスケーラビリティをもって実現できる・・・と思います。たぶん。

基本的に管理
インスタンス以外にはファイルは置かないことがポイント。それによりスケールアウトしやすくなります。
※DataAPIによるサムネイル生成など、管理用
インスタンス以外からの静的ファイル更新がある場合は、もうひと工夫要るでしょう
※DataAPIへのアクセスはクロス
ドメインになるので、[DataAPICORSAllowOrigin
環境変数](
http://www.movabletype.jp/beta/60/dataapicorsalloworigin.html)を使用することになるでしょう