« 2010年8月 | メイン | 2010年10月 »

2010年9月

2010年9月30日 (木)

Amazon SQSに入門してみました

こんにちは。大橋です。

今日はAmazon SQSについてです。

サイトを運営していると、ときどきメッセージキューで非同期に
処理をしたいなという箇所がよくあります。

また、最近、当社ではセールスフォースとAmazon EC2の併用など、異なる
クラウド環境を使ったシステムをを扱っており、その連携方法を日々調査しています。

1箇所のサーバ環境だけならば、GearmanやQ4Mなど自前インストール型のキュー
使えばよいかと思うのですが、クラウド環境間の連携などを考えると、
グローバルに利用できるメッセージ伝達方式の方が望ましいケースもあります。

そこで、今回Amazon SQSに触手を伸ばし、入門してみました。
今日は、その記録を残します。

【Amazon SQSを利用開始する】

Amazon Web サービスのアカウントにサインアップし、
Amazon SQS
のページで「Amazon SQSの利用を申し込む」
をすればOKです。

【料金はすごく安い】

課金はリクエスト数によるものととデータ転送量によるものの2系統です。

リクエスト課金は 10,000回のAmazon SQSリクエストに付き0.01ドル。
ほとんどお金かかりません。

データ転送量は米国&欧州とアジア(シンガポール)で異なりますが、
たとえば、米国&欧州では10TB(テラバイト!!)までのデータ受信で
0.15ドル。同一RegionでEC2と送受信するものは課金されません。

すごくすごく気軽に使える値段です。(個人で利用しても気にならない価格です)

【少ないAPIで使えるシンプルな設計】

機能が少ないともいえますが、シンプルに使えます。

だいたいのことはには、以下の4つを使ってできます。

(1) CreateQueue    :  メッセージキューを作成する
(2) SendMessage   : メッセージキューにメッセージを送信
(3) ReceiveMessage  : メッセージキューからメッセージを受信
(4) DeleteMessage  : メッセージキューからメッセージを削除

もちろん、他にもAPIはいろいろありますが、ちょっと試すだけならば
これでOKです。

キューを作成したあと、以下の絵のような流れで処理をすることになります。
Amazon SQSではメッセージは8192バイトが最大なので、もし大きなデータを
渡したい場合はAmazon S3やAmazon SimpleDBなど外部のデータストアに置いて
おき、そのポインタをメッセージに入れるのがよいです。

Sqs

【メッセージ保存期間と視認性について】

メッセージは4日間、キューに保存されます。

また、あるクライアントがReceiveMessageしたあとは、他のクライアントは一定期間、
同一のメッセージが見えなくなります。

見えなくなる時間(視認できなくなる時間)はAPI経由で設定でき、30秒から12時間まで
設定できます。

もしAというクライアントがメッセージαを取得したあと、なにかしらの処理に
失敗した場合、メッセージαは、一定期間(30秒~12時間)のあとに、他のクライアントから
見えるようになります。

もちろん、そのAというクライアントが処理に成功し、メッセージ削除APIを
キューに対して呼び出した場合は、その後、他のクライアントから見えなくなります。

【使い方 ~Perlで実際に使ってみる~】

PHP編やJava編はいずれ機会があったら書きます。
とりあえず、Perlから使ってみます。

先ほどの絵でいうところのSendMessageする側(Process1)が「メッセージ送信側」、ReceiveMessageする側が「メッセージ受信側」(Process2)とします。

やりとりするメッセージはサンプルなので「Hello, World」とします。
メッセージ送信側がキューに対して'Hello, World'とメッセージをいれ、
メッセージ受信側はそのメッセージをキューから取得、画面に表示して
キューからメッセージを削除しています。

実運用ではメッセージは処理を依頼する内容やデータのポインタになります。
また、メッセージ受信側では、時間がかかる処理をするなど、なにかしらの
処理をします。

なお、Perlから使うにはモジュールのインストールが必要です。Amazon::SQS::SimpleというモジュールがCPANにありますので、サンプルプログラムを使うには以下のモジュールをインストールしてから実行する必要があります。

Amazon::SQS::Simpleモジュール

以下、サンプルプログラムです。

・メッセージ送信側

#!/usr/bin/env perl                                                                                                                       
# sqs_msg_sender.pl                                                                                                                       

use strict;
use warnings;

use Amazon::SQS::Simple;

my $access_key = $ENV{AWS_ACCESS_KEY};
my $secret_key = $ENV{AWS_SECRET_KEY};

# SQSオブジェクトを作成します。                                                                                                           
my $sqs = new Amazon::SQS::Simple( $access_key, $secret_key );

# キューを作成します。作成済みの場合に実行してもそのままキューがある状態になります。                                                      
my $q = $sqs->CreateQueue('sample_flect_queue');

# キューにメッセージを送付します。                                                                                                        
$q->SendMessage('Hello World');

exit 0;

・メッセージ受信側

#!/usr/bin/env perl                                                                                                                       
# sqs_msg_receiver.pl                                                                                                                     

use strict;
use warnings;

use Amazon::SQS::Simple;

my $access_key = $ENV{AWS_ACCESS_KEY};
my $secret_key = $ENV{AWS_SECRET_KEY};

# SQSオブジェクトを作成します。                                                                                                           
my $sqs = new Amazon::SQS::Simple( $access_key, $secret_key );

# キューオブジェクトを取得します。                                                                                                        
my $q = $sqs->CreateQueue('sample_flect_queue');

# キューからメッセージを取得します。                                                                                                      
my $msg = $q->ReceiveMessage();

# メッセージの内容を出力してみます。                                                                                                      
print $msg->MessageId() . "\n";
print $msg->MessageBody() . "\n";

# キューからメッセージを削除します。ReceiptHandleというのを使います。                                                                     
$q->DeleteMessage( $msg->ReceiptHandle() );

exit 0;


【すぐに使えて高い信頼性があることについて】

メッセージキューは機能は非常にシンプルですが、同じようなキューを
自前で構築して、Amazon SQS並みの信頼性を保とうと思うとけっこう大変です。

たとえば、Q4MのようにMySQLを使うタイプのメッセージキューを自前で
構築した場合、1台くらいサーバが落ちてもメッセージをロストすることなく、
なおかつ、クライアントからのメッセージ送受信のリクエストをさばきつづける、
となると、必要な構築コストはかなり大きいです。

複数台のサーバが必要で、MySQLのレプリケーションをしたり、あるいは
DRBDで複数台のデータを同期させたり・・・、とかとか。ちょっと手間がかかりますね。

その点、Amazon SQSはAmazonが複数のサーバやデータセンターで冗長化していて大量のリクエストが来ても、ちゃんと止まらずにさばいてくれます。

そういったメッセージキューシステムを自前で作らなくても
すぐに本番システムレベルの信頼性で使える、というのは場合によっては
大幅なコスト削減になるんではないかと思います。

もちろん、パフォーマンス面など適合しないケースもあるかと思いますが、
クラウドな環境ではひとつの選択肢になるのではないかと考えています。

【制限や注意事項もあります】

基本的な注意事項は「メッセージ保存期間と視認性について」のところで
書いたとおりのこと、それと、メッセージが8192バイトが最大なので、
大きいデータの受け渡しが必要なときはS3などにデータをおき、その
ポインタ情報(URL)をやりとりするように、ということがあります。

その他に重要なポイントとしては

 (1) 同一のメッセージが複数回受信できてしまうことがある。
 (2) メッセージはキューに入れた順番どおりには受信できない。

ということです。

これはAmazon SQSが複数のサーバや複数のデータセンターを使って
運営されているためのようですが、注意が必要です。

(1)については場合によっては、Amazon SQS以外のデータストア
(Amazon SimpleDBなど)にどこまでのメッセージ処理ができたか、
などの情報を持っておく必要があります。
その辺はシステムの要求などによりケースバイケースだと思いますが、注意が必要です。

【まとめ&今後取り組むこと】

初期調査、入門だけなのに、記事が少しながくなってしまったので、今日は
これくらいにしておきます。

現在、私が行っているAmazon SQSの調査の最終ゴールは当社が現在力を入れている
Saleforceのシステムと連携させてみることです。

ちゃんと連携できたらまた記事にしますので、待っていてください。

なお、当社はAmazon Web Servicesに力を入れると同時に、Salesforce事業も
展開中です。現在、こういったいろいろなクラウドプラットフォームを使って
お客様によいソリューションを提供したい、というエンジニアの方を
大募集中です。もし、興味のある方は以下からご連絡いただけると幸いです。

http://www.flect.co.jp/recruit/index.html

Amazon SQSに入門してみました

こんにちは。大橋です。

今日はAmazon SQSについてです。

サイトを運営していると、ときどきメッセージキューで非同期に
処理をしたいなという箇所がよくあります。

また、最近、当社ではセールスフォースとAmazon EC2の併用など、異なる
クラウド環境を使ったシステムをを扱っており、その連携方法を日々調査しています。

1箇所のサーバ環境だけならば、GearmanやQ4Mなど自前インストール型のキュー
使えばよいかと思うのですが、クラウド環境間の連携などを考えると、
グローバルに利用できるメッセージ伝達方式の方が望ましいケースもあります。

そこで、今回Amazon SQSに触手を伸ばし、入門してみました。
今日は、その記録を残します。

【Amazon SQSを利用開始する】

Amazon Web サービスのアカウントにサインアップし、
Amazon SQS
のページで「Amazon SQSの利用を申し込む」
をすればOKです。

【料金はすごく安い】

課金はリクエスト数によるものととデータ転送量によるものの2系統です。

リクエスト課金は 10,000回のAmazon SQSリクエストに付き0.01ドル。
ほとんどお金かかりません。

データ転送量は米国&欧州とアジア(シンガポール)で異なりますが、
たとえば、米国&欧州では10TB(テラバイト!!)までのデータ受信で
0.15ドル。同一RegionでEC2と送受信するものは課金されません。

すごくすごく気軽に使える値段です。(個人で利用しても気にならない価格です)

【少ないAPIで使えるシンプルな設計】

機能が少ないともいえますが、シンプルに使えます。

だいたいのことはには、以下の4つを使ってできます。

(1) CreateQueue    :  メッセージキューを作成する
(2) SendMessage   : メッセージキューにメッセージを送信
(3) ReceiveMessage  : メッセージキューからメッセージを受信
(4) DeleteMessage  : メッセージキューからメッセージを削除

もちろん、他にもAPIはいろいろありますが、ちょっと試すだけならば
これでOKです。

キューを作成したあと、以下の絵のような流れで処理をすることになります。
Amazon SQSではメッセージは8192バイトが最大なので、もし大きなデータを
渡したい場合はAmazon S3やAmazon SimpleDBなど外部のデータストアに置いて
おき、そのポインタをメッセージに入れるのがよいです。

Sqs

【メッセージ保存期間と視認性について】

メッセージは4日間、キューに保存されます。

また、あるクライアントがReceiveMessageしたあとは、他のクライアントは一定期間、
同一のメッセージが見えなくなります。

見えなくなる時間(視認できなくなる時間)はAPI経由で設定でき、30秒から12時間まで
設定できます。

もしAというクライアントがメッセージαを取得したあと、なにかしらの処理に
失敗した場合、メッセージαは、一定期間(30秒~12時間)のあとに、他のクライアントから
見えるようになります。

もちろん、そのAというクライアントが処理に成功し、メッセージ削除APIを
キューに対して呼び出した場合は、その後、他のクライアントから見えなくなります。

【使い方 ~Perlで実際に使ってみる~】

PHP編やJava編はいずれ機会があったら書きます。
とりあえず、Perlから使ってみます。

先ほどの絵でいうところのSendMessageする側(Process1)が「メッセージ送信側」、ReceiveMessageする側が「メッセージ受信側」(Process2)とします。

やりとりするメッセージはサンプルなので「Hello, World」とします。
メッセージ送信側がキューに対して'Hello, World'とメッセージをいれ、
メッセージ受信側はそのメッセージをキューから取得、画面に表示して
キューからメッセージを削除しています。

実運用ではメッセージは処理を依頼する内容やデータのポインタになります。
また、メッセージ受信側では、時間がかかる処理をするなど、なにかしらの
処理をします。

なお、Perlから使うにはモジュールのインストールが必要です。Amazon::SQS::SimpleというモジュールがCPANにありますので、サンプルプログラムを使うには以下のモジュールをインストールしてから実行する必要があります。

Amazon::SQS::Simpleモジュール

以下、サンプルプログラムです。

・メッセージ送信側

#!/usr/bin/env perl                                                                                                                       
# sqs_msg_sender.pl                                                                                                                       

use strict;
use warnings;

use Amazon::SQS::Simple;

my $access_key = $ENV{AWS_ACCESS_KEY};
my $secret_key = $ENV{AWS_SECRET_KEY};

# SQSオブジェクトを作成します。                                                                                                           
my $sqs = new Amazon::SQS::Simple( $access_key, $secret_key );

# キューを作成します。作成済みの場合に実行してもそのままキューがある状態になります。                                                      
my $q = $sqs->CreateQueue('sample_flect_queue');

# キューにメッセージを送付します。                                                                                                        
$q->SendMessage('Hello World');

exit 0;

・メッセージ受信側

#!/usr/bin/env perl                                                                                                                       
# sqs_msg_receiver.pl                                                                                                                     

use strict;
use warnings;

use Amazon::SQS::Simple;

my $access_key = $ENV{AWS_ACCESS_KEY};
my $secret_key = $ENV{AWS_SECRET_KEY};

# SQSオブジェクトを作成します。                                                                                                           
my $sqs = new Amazon::SQS::Simple( $access_key, $secret_key );

# キューオブジェクトを取得します。                                                                                                        
my $q = $sqs->CreateQueue('sample_flect_queue');

# キューからメッセージを取得します。                                                                                                      
my $msg = $q->ReceiveMessage();

# メッセージの内容を出力してみます。                                                                                                      
print $msg->MessageId() . "\n";
print $msg->MessageBody() . "\n";

# キューからメッセージを削除します。ReceiptHandleというのを使います。                                                                     
$q->DeleteMessage( $msg->ReceiptHandle() );

exit 0;


【すぐに使えて高い信頼性があることについて】

メッセージキューは機能は非常にシンプルですが、同じようなキューを
自前で構築して、Amazon SQS並みの信頼性を保とうと思うとけっこう大変です。

たとえば、Q4MのようにMySQLを使うタイプのメッセージキューを自前で
構築した場合、1台くらいサーバが落ちてもメッセージをロストすることなく、
なおかつ、クライアントからのメッセージ送受信のリクエストをさばきつづける、
となると、必要な構築コストはかなり大きいです。

複数台のサーバが必要で、MySQLのレプリケーションをしたり、あるいは
DRBDで複数台のデータを同期させたり・・・、とかとか。ちょっと手間がかかりますね。

その点、Amazon SQSはAmazonが複数のサーバやデータセンターで冗長化していて大量のリクエストが来ても、ちゃんと止まらずにさばいてくれます。

そういったメッセージキューシステムを自前で作らなくても
すぐに本番システムレベルの信頼性で使える、というのは場合によっては
大幅なコスト削減になるんではないかと思います。

もちろん、パフォーマンス面など適合しないケースもあるかと思いますが、
クラウドな環境ではひとつの選択肢になるのではないかと考えています。

【制限や注意事項もあります】

基本的な注意事項は「メッセージ保存期間と視認性について」のところで
書いたとおりのこと、それと、メッセージが8192バイトが最大なので、
大きいデータの受け渡しが必要なときはS3などにデータをおき、その
ポインタ情報(URL)をやりとりするように、ということがあります。

その他に重要なポイントとしては

 (1) 同一のメッセージが複数回受信できてしまうことがある。
 (2) メッセージはキューに入れた順番どおりには受信できない。

ということです。

これはAmazon SQSが複数のサーバや複数のデータセンターを使って
運営されているためのようですが、注意が必要です。

(1)については場合によっては、Amazon SQS以外のデータストア
(Amazon SimpleDBなど)にどこまでのメッセージ処理ができたか、
などの情報を持っておく必要があります。
その辺はシステムの要求などによりケースバイケースだと思いますが、注意が必要です。

【まとめ&今後取り組むこと】

初期調査、入門だけなのに、記事が少しながくなってしまったので、今日は
これくらいにしておきます。

現在、私が行っているAmazon SQSの調査の最終ゴールは当社が現在力を入れている
Saleforceのシステムと連携させてみることです。

ちゃんと連携できたらまた記事にしますので、待っていてください。

なお、当社はAmazon Web Servicesに力を入れると同時に、Salesforce事業も
展開中です。現在、こういったいろいろなクラウドプラットフォームを使って
お客様によいソリューションを提供したい、というエンジニアの方を
大募集中です。もし、興味のある方は以下からご連絡いただけると幸いです。

http://www.flect.co.jp/recruit/index.html

2010年9月24日 (金)

Net::Amazon::EC2でEC2 API Toolsより高速にEBSのスナップショットを取得

こんにちは。フレクト 大橋です。

前回、EBS上に置いたMySQLのバックアップを取得する方法を紹介しましたが、
EC2 API Toolsを使ったEBSのスナップショット取得に5秒くらいかかってしまう
欠点がありました。
(※ 5秒かかるのは私たちが使っているベターホームレシピ(http:bhmb.jp)でのことで
 他の環境ではどうかは分かりませんが、それなりにかかると思います)
前回紹介した方法ではスナップショット取得中はファイルシステムへの書き込みを
ブロックしているので、運用中のサービスによっては5秒程度ブロックされるが嫌だったり
することもあると思います。
 
ところが以下を見てみると、スナップショット取得にEC2 API Toolsの
「ec2-create-snapshot」コマンドを使うより、PerlでNet::Amazon::EC2モジュールを
使った方が高速にスナップショット取得ができそうとのことなので
やってみました。
 
 
■ Net::Amazon::EC2を使ったEBSスナップショットの取得
 
cpanからNet::Amazon::EC2モジュールをインストールしてください。
cpanコマンドを使えば簡単にできると思います。Mooseが入っていないと
Mooseのインストールも必要になるため、若干時間がかかるかもしれません。
 
インストールしたあと、以下のようなスクリプトでEBSのスナップショット取得ができます。
Volume IDは各自の環境のものをご利用ください。またAmazon Web Serviceのアクセスキー、秘密鍵なども各自の環境のものをご利用ください。
 
#!/usr/bin/env perl
# ebs_snapshot.pl

use strict;
use warnings;

use Net::Amazon::EC2;

my $aws_access_key = $ENV{EC2_ACCESS_KEY};
my $aws_secret_key = $ENV{EC2_SECRET_KEY};
my $volume_id      = 'vol-xxxxxxx';

my $ec2 = Net::Amazon::EC2->new(
    AWSAccessKeyId  => $aws_access_key,
    SecretAccessKey => $aws_secret_key,
    region          => 'us-west-1',
);

my $snapshot = $ec2->create_snapshot(
    VolumeId    => $volume_id,
    Description => 'snapshot by Net::Amazon::EC2',
);

exit 0;
 
■ EC2 API Toolsとの比較
 
EC2 API Toolsを使うと以下のようなコマンドでスナップショットが取れます。
Volume IDに各自の環境のものをいれます。
 
> ec2-create-snapshot -d 'スナップショットの説明'  Volume-ID
 
EC2 API Toolsで私ども環境でEBSのスナップショット(40GB)を取得してみると、
timeコマンドでの計測ではだいたい4秒から5秒くらいかかっています。
環境はus-west-1のEC2上のインスタンスを使いました。(一部出力を省略しています)
 
【1回目】
# time ec2-create-snapshot -d command-line-test-01 vol-xxxxx
real     0m5.020s
user     0m4.408s
sys     0m0.205s
 
【2回目】
# time ec2-create-snapshot -d command-line-test-02 vol-xxxx
real     0m4.696s
user     0m4.603s
sys     0m0.151s
 
【3回目】
# time ec2-create-snapshot -d command-line-test-03 vol-xxxx
real     0m4.479s
user     0m4.590s
sys     0m0.165s
 
次にNet::Amazon::EC2を使ったスクリプトで計測してみました。
スクリプトは先ほど説明したPerlのスクリプトで、ebs_snapshot.plとしています。
EC2 API Toolsで計測した環境と同じ環境で試してみました。
 
【1回目】
# time perl ebs_snapshot.pl
real     0m1.256s
user     0m0.747s
sys     0m0.050s
 
【2回目】
# time perl ebs_snapshot.pl
real     0m1.468s
user     0m0.848s
sys     0m0.041s
 
【3回目】
# time perl ebs_snapshot.pl
real     0m1.331s
user     0m0.792s
sys     0m0.021s
 
だいたいこっちは1.2秒〜1.4秒くらいのスピードでできました。
EC2 API Toolsより3倍〜4倍くらいのスピード。計測方法が若干いい加減ですが、
速くなるのは間違いなさそうです。
こっちを使えば、バックアップ時に書き込みロックの時間を少し軽減できそうです。
また、コマンドライン操作でもストレスが減りますね。
 
■ なぜ速いのか&まとめ
 
詳細を調査したわけではないですが、単純にEC2 API ToolsはJavaでできていて
コマンドラインで実行すると起動すると実処理に入るまでが時間がかかることが
大きいです。あとはNet::Amazon::EC2はQuery APIを使っていて、EC2 API Toolsが
SOAPを使っているのも遅くなる要因にはあると思いますが、実時間がどれくらい
差があるのかは分かりません。
 
Amazon Web Servicesを操作するコマンドで、よく使うものは
Perl, Rubyなど起動の軽いスクリプトでQuery APIを使って運用ツールを作った方
が長期的には何かとストレスが小さいかな、と思います。
 
フレクトではAmazon Web Servicesを使ったプロダクトやソリューション事業を積極的に
実施しています。興味のある方はいつでも以下からご連絡ください。
 

Net::Amazon::EC2でEC2 API Toolsより高速にEBSのスナップショットを取得

こんにちは。フレクト 大橋です。

前回、EBS上に置いたMySQLのバックアップを取得する方法を紹介しましたが、
EC2 API Toolsを使ったEBSのスナップショット取得に5秒くらいかかってしまう
欠点がありました。
(※ 5秒かかるのは私たちが使っているベターホームレシピ(http:bhmb.jp)でのことで
 他の環境ではどうかは分かりませんが、それなりにかかると思います)
前回紹介した方法ではスナップショット取得中はファイルシステムへの書き込みを
ブロックしているので、運用中のサービスによっては5秒程度ブロックされるが嫌だったり
することもあると思います。
 
ところが以下を見てみると、スナップショット取得にEC2 API Toolsの
「ec2-create-snapshot」コマンドを使うより、PerlでNet::Amazon::EC2モジュールを
使った方が高速にスナップショット取得ができそうとのことなので
やってみました。
 
 
■ Net::Amazon::EC2を使ったEBSスナップショットの取得
 
cpanからNet::Amazon::EC2モジュールをインストールしてください。
cpanコマンドを使えば簡単にできると思います。Mooseが入っていないと
Mooseのインストールも必要になるため、若干時間がかかるかもしれません。
 
インストールしたあと、以下のようなスクリプトでEBSのスナップショット取得ができます。
Volume IDは各自の環境のものをご利用ください。またAmazon Web Serviceのアクセスキー、秘密鍵なども各自の環境のものをご利用ください。
 
#!/usr/bin/env perl
# ebs_snapshot.pl

use strict;
use warnings;

use Net::Amazon::EC2;

my $aws_access_key = $ENV{EC2_ACCESS_KEY};
my $aws_secret_key = $ENV{EC2_SECRET_KEY};
my $volume_id      = 'vol-xxxxxxx';

my $ec2 = Net::Amazon::EC2->new(
    AWSAccessKeyId  => $aws_access_key,
    SecretAccessKey => $aws_secret_key,
    region          => 'us-west-1',
);

my $snapshot = $ec2->create_snapshot(
    VolumeId    => $volume_id,
    Description => 'snapshot by Net::Amazon::EC2',
);

exit 0;
 
■ EC2 API Toolsとの比較
 
EC2 API Toolsを使うと以下のようなコマンドでスナップショットが取れます。
Volume IDに各自の環境のものをいれます。
 
> ec2-create-snapshot -d 'スナップショットの説明'  Volume-ID
 
EC2 API Toolsで私ども環境でEBSのスナップショット(40GB)を取得してみると、
timeコマンドでの計測ではだいたい4秒から5秒くらいかかっています。
環境はus-west-1のEC2上のインスタンスを使いました。(一部出力を省略しています)
 
【1回目】
# time ec2-create-snapshot -d command-line-test-01 vol-xxxxx
real     0m5.020s
user     0m4.408s
sys     0m0.205s
 
【2回目】
# time ec2-create-snapshot -d command-line-test-02 vol-xxxx
real     0m4.696s
user     0m4.603s
sys     0m0.151s
 
【3回目】
# time ec2-create-snapshot -d command-line-test-03 vol-xxxx
real     0m4.479s
user     0m4.590s
sys     0m0.165s
 
次にNet::Amazon::EC2を使ったスクリプトで計測してみました。
スクリプトは先ほど説明したPerlのスクリプトで、ebs_snapshot.plとしています。
EC2 API Toolsで計測した環境と同じ環境で試してみました。
 
【1回目】
# time perl ebs_snapshot.pl
real     0m1.256s
user     0m0.747s
sys     0m0.050s
 
【2回目】
# time perl ebs_snapshot.pl
real     0m1.468s
user     0m0.848s
sys     0m0.041s
 
【3回目】
# time perl ebs_snapshot.pl
real     0m1.331s
user     0m0.792s
sys     0m0.021s
 
だいたいこっちは1.2秒〜1.4秒くらいのスピードでできました。
EC2 API Toolsより3倍〜4倍くらいのスピード。計測方法が若干いい加減ですが、
速くなるのは間違いなさそうです。
こっちを使えば、バックアップ時に書き込みロックの時間を少し軽減できそうです。
また、コマンドライン操作でもストレスが減りますね。
 
■ なぜ速いのか&まとめ
 
詳細を調査したわけではないですが、単純にEC2 API ToolsはJavaでできていて
コマンドラインで実行すると起動すると実処理に入るまでが時間がかかることが
大きいです。あとはNet::Amazon::EC2はQuery APIを使っていて、EC2 API Toolsが
SOAPを使っているのも遅くなる要因にはあると思いますが、実時間がどれくらい
差があるのかは分かりません。
 
Amazon Web Servicesを操作するコマンドで、よく使うものは
Perl, Rubyなど起動の軽いスクリプトでQuery APIを使って運用ツールを作った方
が長期的には何かとストレスが小さいかな、と思います。
 
フレクトではAmazon Web Servicesを使ったプロダクトやソリューション事業を積極的に
実施しています。興味のある方はいつでも以下からご連絡ください。
 

2010年9月22日 (水)

EC2でEBS上のMySQLのデータをバックアップ

こんにちは。フレクトの大橋です。

ベターホームレシピ(http://bhmb.jp)では、MySQLを会員やレシピデータ用の
インスタンスと、Cicindela用のインスタンスを同一のサーバにそれぞれ
データをEBSに置いて運用しています。

レプリケーションなど信頼性向上のための施策をしているのですが、
運用上大事なのはバックアップです。

そこで、今日はEBS上のMySQLのデータのスナップショットを
整合性を失わずにバックアップする方法についてベターホームレシピでの
実運用の事例をもとに紹介します。

■ 本題の前に・・・、Amazon RDSについて

そもそも直接MySQLをEC2上にインストールしなくても、日々機能が強化されている
Amazon RDSを使えばよいのではないか、という考えもあります。はい、その通りです。
特に最近はMulti-AZ機能なども提供され、安心感があります。

ただ、ベターホームレシピを検討していたときには、RDSは冗長化機能が弱い、
バックアップでIOフリーズがあったりする、など現在より課題も多かったので
EC2上で自前運用としました。

また、運用にかけられる予算が少なかったので、EC2とは別に複数のインスタンスでの
RDSの費用が発生するのが嫌だったというのもあります。

RDSを選ぶかは、みなさまの環境によると思います。

■ EBS上にMySQLデータを置いて動かす

では、EC2上で自前でMySQLを運用する場合について進めます。
普通にインストールすると、EC2のローカルストレージにデータを置くことになりますが、
EC2のインスタンスが落ちた場合、データ消えてしまうので怖いです。

したがって、MySQLのプログラム自体はEC2のローカルストレージでも
いいのですが、データディレクトリはEBS上に置くことにします。

肝心の方法ですが、以下に書いてある通りですんなりできます。   

http://d.hatena.ne.jp/shibataism/20080822/1219422913
http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1663&categoryID=100

■ ファイルシステムは xfs

ポイントはファイルシステムをxfsで作ることできます。

xfsはファイルシステムのフリーズフリーズ解除(freeze/thaw)機能があり、
EBSスナップショット取得中に書き込みをロックすることができ、
一貫性を持ったファイルシステムのスナップショット取得ができます。

freezeのコマンドはシェルからできるので、運用上、自動化することもでき、
今回の用途にはよいです。なので、以下に続く例もxfsにします。

■ 手動でフリーズ、スナップショット取得を実行してみる

前提としてmysqlのデータファイルは
  /vol/****/mysql/data
にあるものとします。(****は当社の場合はプロジェクト名です)

手順は以下の順番です。

 (1) MySQLのデータをFLUSHし、READロックをかけます。つまり、書き込みできないようにします。これでDBへの書き込みはできなくなります。
 (2) xfs_freezeコマンドでファイルシステムを凍結。ファイルシステムに書き込みをできなくすると同時に、ファイルシステム上のキャッシュやメタデータなどをディスクに書き込んでしまいます。
  (3) EBSのスナップショットを取得する。
 (4) xfsの凍結を解除します。ec2-create-snapshotでできます。
 (5) MySQLのロックを解除します。

DBやファイルシステムの状態が不整合を起こさないようにする工夫は(1)、(2)です。
(1)でMySQLのキャッシュのデータをFLUSHし、全部ディスクに退避させ、その上でREADロックです。
これでMySQLに追加書き込みはできません。その上で(2)を実施して、ファイルシステムに書き込みできなくします。
ディスクに追加書き込みできなくしてからEBSのスナップショット取得、そしてロックを順次解除していきます。具体的には以下のようにmysqlのコンソールに入ってコマンドを実行していくとできます。

----------------------------

 # mysql -u root --password=xxxx --port=xxxx --host=xxx.xxx.xxx.xxx     # mysqlのコンソールへ。

mysql >FLUSH TABLES WITH READ LOCK;                  # (1)MySQLをロック
mysql >SYSTEM xfs_freeze -f /vol                    # (2)ファイルシステムをロック
mysql >SYSTEM ec2-create-snapshot -d xxxxx vol-xxxxxx                  # (3)EBSのスナップショット
mysql >SYSTEM xfs_freeze -u /vol                    # (4)ファイルシステムのロック解除
mysql >UNLOCK TABLES;                      # (5)MySQLのアンロック

----------------------------
 

■ バックアップのプロセスを自動化する

上記のプロセスをスクリプトで自動化しておくと、定期的なスナップショット
取得ができて便利です。以下に簡単なPerlでのスクリプト例も書いておきます。
なお、xfsを使わない場合も想定して、xfs_freezeの前にsyncを入れていますが、
それ以外は上記のプロセスの自動化となっています。

#!/usr/bin/env perl

use strict;
use warnings;

use DBI;

my $use_xfs         = 1;
my $xfs_mount_point = '/vol';

my $use_mysql      = 1;
my $mysql_username = 'xxxx';
my $mysql_password = 'xxxx';
my $mysql_host     = 'xxx.xxx.xxx.xxx';
my $mysql_port     = 3306;
my $mysql_dsn      = [
    "DBI:mysql:;host=$mysql_host;$mysql_port", $mysql_username,
    $mysql_password
];

my $dbh = undef;

# connect and lock mysql
if ($use_mysql) {
    $dbh = connect_db($mysql_dsn);
    flush_tables_with_read_lock($dbh);
}

# commit buffer to disk
run_command( ['sync'] );

# freeze file system
if ($use_xfs) {
    run_command( [ 'xfs_freeze', '-f', $xfs_mount_point ] );
}

# snapshot ebs
run_command( [ 'ec2-create-snapshot', '-d', 'xxxxxx', 'vol-xxxxx' ] );


# thaw file system
if ($use_xfs) {
    run_command( [ 'xfs_freeze', '-u', $xfs_mount_point ] );
}

# unlock and disconnect
if ($use_mysql) {
    unlock_tables($dbh);
    disconnect_db($dbh);
}

exit 0;

sub run_command {
    my ($command) = @_;
    eval { system(@$command) and die "failed($?)\n"; };
    warn "ERROR: @$command: $@" if $@;
}

sub connect_db {
    my $dsn = shift;
    my $dbh = DBI->connect(@$dsn)
      or die "cannot connect database " . $!;
    return $dbh;
}

sub disconnect_db {
    my $dbh = shift;
    $dbh->disconnect();
}

sub flush_tables_with_read_lock {
    my $dbh = shift;
    $dbh->do('FLUSH TABLES WITH READ LOCK;') or die $dbh->errstr;
}

sub unlock_tables {
    my $dbh = shift;
    $dbh->do('UNLOCK TABLES; ') or die $dbh->errstr;
}

■ 注意点、制限事項など

ベターホームレシピで運用しているときはだいたい1回5秒くらいかかります。
特にEBSスナップショットに時間がかかります。その間、書き込みがブロックされるので
注意が必要です。書き込みに待ちが発生してもよい環境(スレーブ環境)などで取得するか、
マスタ環境で取得する場合は、書き込みブロックが許容できる環境で実施するのが
よいと思います。

なお、EBSスナップショットの取得はec2-create-snapshotコマンドではなく、APIを直接
たたけばもう少し高速になるはずです。それはまた今度実施してみます。

あと今回はxfsにしましたが、ext3,ext4など他のファイルシステムでもxfs_freeze的なことが
できるのかは、ちょっと調べましたが、見当たりませんでした。できるのかもしれませんが、
他のファイルシステムでもこういったバックアップ運用ができるのか、今後調べてみたいです。

■ 参考資料

今回の記事は以下の記事をもとに作りました。

・EBSでMySQLのスナップショットを取るための手順等の資料等
http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1663&categoryID=100
http://alestic.com/2009/09/ec2-consistent-snapshot

■ まとめ

このような手順を踏めば、定期的に整合性の取れた状態でスナップショットを
作っておけて便利です。今度はリストアの方法なども記載したいです。

フレクトではEC2を使ったインフラ運用に興味のあるエンジニアを
募集しています。興味のある方は以下からご連絡ください。

 

http://www.flect.co.jp/recruit/index.html

 

EC2でEBS上のMySQLのデータをバックアップ

こんにちは。フレクトの大橋です。

ベターホームレシピ(http://bhmb.jp)では、MySQLを会員やレシピデータ用の
インスタンスと、Cicindela用のインスタンスを同一のサーバにそれぞれ
データをEBSに置いて運用しています。

レプリケーションなど信頼性向上のための施策をしているのですが、
運用上大事なのはバックアップです。

そこで、今日はEBS上のMySQLのデータのスナップショットを
整合性を失わずにバックアップする方法についてベターホームレシピでの
実運用の事例をもとに紹介します。

■ 本題の前に・・・、Amazon RDSについて

そもそも直接MySQLをEC2上にインストールしなくても、日々機能が強化されている
Amazon RDSを使えばよいのではないか、という考えもあります。はい、その通りです。
特に最近はMulti-AZ機能なども提供され、安心感があります。

ただ、ベターホームレシピを検討していたときには、RDSは冗長化機能が弱い、
バックアップでIOフリーズがあったりする、など現在より課題も多かったので
EC2上で自前運用としました。

また、運用にかけられる予算が少なかったので、EC2とは別に複数のインスタンスでの
RDSの費用が発生するのが嫌だったというのもあります。

RDSを選ぶかは、みなさまの環境によると思います。

■ EBS上にMySQLデータを置いて動かす

では、EC2上で自前でMySQLを運用する場合について進めます。
普通にインストールすると、EC2のローカルストレージにデータを置くことになりますが、
EC2のインスタンスが落ちた場合、データ消えてしまうので怖いです。

したがって、MySQLのプログラム自体はEC2のローカルストレージでも
いいのですが、データディレクトリはEBS上に置くことにします。

肝心の方法ですが、以下に書いてある通りですんなりできます。   

http://d.hatena.ne.jp/shibataism/20080822/1219422913
http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1663&categoryID=100

■ ファイルシステムは xfs

ポイントはファイルシステムをxfsで作ることできます。

xfsはファイルシステムのフリーズフリーズ解除(freeze/thaw)機能があり、
EBSスナップショット取得中に書き込みをロックすることができ、
一貫性を持ったファイルシステムのスナップショット取得ができます。

freezeのコマンドはシェルからできるので、運用上、自動化することもでき、
今回の用途にはよいです。なので、以下に続く例もxfsにします。

■ 手動でフリーズ、スナップショット取得を実行してみる

前提としてmysqlのデータファイルは
  /vol/****/mysql/data
にあるものとします。(****は当社の場合はプロジェクト名です)

手順は以下の順番です。

 (1) MySQLのデータをFLUSHし、READロックをかけます。つまり、書き込みできないようにします。これでDBへの書き込みはできなくなります。
 (2) xfs_freezeコマンドでファイルシステムを凍結。ファイルシステムに書き込みをできなくすると同時に、ファイルシステム上のキャッシュやメタデータなどをディスクに書き込んでしまいます。
  (3) EBSのスナップショットを取得する。
 (4) xfsの凍結を解除します。ec2-create-snapshotでできます。
 (5) MySQLのロックを解除します。

DBやファイルシステムの状態が不整合を起こさないようにする工夫は(1)、(2)です。
(1)でMySQLのキャッシュのデータをFLUSHし、全部ディスクに退避させ、その上でREADロックです。
これでMySQLに追加書き込みはできません。その上で(2)を実施して、ファイルシステムに書き込みできなくします。
ディスクに追加書き込みできなくしてからEBSのスナップショット取得、そしてロックを順次解除していきます。具体的には以下のようにmysqlのコンソールに入ってコマンドを実行していくとできます。

----------------------------

 # mysql -u root --password=xxxx --port=xxxx --host=xxx.xxx.xxx.xxx     # mysqlのコンソールへ。

mysql >FLUSH TABLES WITH READ LOCK;                  # (1)MySQLをロック
mysql >SYSTEM xfs_freeze -f /vol                    # (2)ファイルシステムをロック
mysql >SYSTEM ec2-create-snapshot -d xxxxx vol-xxxxxx                  # (3)EBSのスナップショット
mysql >SYSTEM xfs_freeze -u /vol                    # (4)ファイルシステムのロック解除
mysql >UNLOCK TABLES;                      # (5)MySQLのアンロック

----------------------------
 

■ バックアップのプロセスを自動化する

上記のプロセスをスクリプトで自動化しておくと、定期的なスナップショット
取得ができて便利です。以下に簡単なPerlでのスクリプト例も書いておきます。
なお、xfsを使わない場合も想定して、xfs_freezeの前にsyncを入れていますが、
それ以外は上記のプロセスの自動化となっています。

#!/usr/bin/env perl

use strict;
use warnings;

use DBI;

my $use_xfs         = 1;
my $xfs_mount_point = '/vol';

my $use_mysql      = 1;
my $mysql_username = 'xxxx';
my $mysql_password = 'xxxx';
my $mysql_host     = 'xxx.xxx.xxx.xxx';
my $mysql_port     = 3306;
my $mysql_dsn      = [
    "DBI:mysql:;host=$mysql_host;$mysql_port", $mysql_username,
    $mysql_password
];

my $dbh = undef;

# connect and lock mysql
if ($use_mysql) {
    $dbh = connect_db($mysql_dsn);
    flush_tables_with_read_lock($dbh);
}

# commit buffer to disk
run_command( ['sync'] );

# freeze file system
if ($use_xfs) {
    run_command( [ 'xfs_freeze', '-f', $xfs_mount_point ] );
}

# snapshot ebs
run_command( [ 'ec2-create-snapshot', '-d', 'xxxxxx', 'vol-xxxxx' ] );


# thaw file system
if ($use_xfs) {
    run_command( [ 'xfs_freeze', '-u', $xfs_mount_point ] );
}

# unlock and disconnect
if ($use_mysql) {
    unlock_tables($dbh);
    disconnect_db($dbh);
}

exit 0;

sub run_command {
    my ($command) = @_;
    eval { system(@$command) and die "failed($?)\n"; };
    warn "ERROR: @$command: $@" if $@;
}

sub connect_db {
    my $dsn = shift;
    my $dbh = DBI->connect(@$dsn)
      or die "cannot connect database " . $!;
    return $dbh;
}

sub disconnect_db {
    my $dbh = shift;
    $dbh->disconnect();
}

sub flush_tables_with_read_lock {
    my $dbh = shift;
    $dbh->do('FLUSH TABLES WITH READ LOCK;') or die $dbh->errstr;
}

sub unlock_tables {
    my $dbh = shift;
    $dbh->do('UNLOCK TABLES; ') or die $dbh->errstr;
}

■ 注意点、制限事項など

ベターホームレシピで運用しているときはだいたい1回5秒くらいかかります。
特にEBSスナップショットに時間がかかります。その間、書き込みがブロックされるので
注意が必要です。書き込みに待ちが発生してもよい環境(スレーブ環境)などで取得するか、
マスタ環境で取得する場合は、書き込みブロックが許容できる環境で実施するのが
よいと思います。

なお、EBSスナップショットの取得はec2-create-snapshotコマンドではなく、APIを直接
たたけばもう少し高速になるはずです。それはまた今度実施してみます。

あと今回はxfsにしましたが、ext3,ext4など他のファイルシステムでもxfs_freeze的なことが
できるのかは、ちょっと調べましたが、見当たりませんでした。できるのかもしれませんが、
他のファイルシステムでもこういったバックアップ運用ができるのか、今後調べてみたいです。

■ 参考資料

今回の記事は以下の記事をもとに作りました。

・EBSでMySQLのスナップショットを取るための手順等の資料等
http://developer.amazonwebservices.com/connect/entry.jspa?externalID=1663&categoryID=100
http://alestic.com/2009/09/ec2-consistent-snapshot

■ まとめ

このような手順を踏めば、定期的に整合性の取れた状態でスナップショットを
作っておけて便利です。今度はリストアの方法なども記載したいです。

フレクトではEC2を使ったインフラ運用に興味のあるエンジニアを
募集しています。興味のある方は以下からご連絡ください。

 

http://www.flect.co.jp/recruit/index.html

 

2010年9月11日 (土)

CloudFrontのエッジサーバ上にキャッシュされているオブジェクトを更新する

こんにちは。フレクトの大橋です。

私たちが運営しているベターホームレシピ(http://bhmb.jp)では、画像などの静的コンテンツ
の配信にCloudFrontを使っています。

CloudFrontはAmazonが用意しているS3上のオブジェクトを高速に配信する仕組みです。
CloudFrontを使うと、S3のオブジェクトがエンドユーザに対して近くに配置されている
サーバ(エッジサーバ)から配信されるようになり、高速のコンテンツの配信ができます。アメリカ西海岸にあるS3の画像が日本国内のエッジサーバにキャッシュされて、高速に配信できたりします。CDN(Contents Delivery Network)の一種です。

CloudFrontのエッジサーバはオブジェクトへのアクセスがあったときに、もしエッジサーバ上に
オブジェクトがあれば、それを配信し、なければ、S3にアクセスしにいき、
配信します。S3から取得したオブジェクトはエッジサーバ上にキャッシュされます。

キャッシュされる時間はS3のメタデータ(HTTPヘッダなど)にTTLを設定すれば制御できます。
以前は24時間が最短でしたが、現在は1時間を最短にできます。
Expireヘッダに1時間後の時間を設定するなどすれば、1時間ごとにエッジサーバのオブジェクトは
更新されるようになるはずです。詳しくは以下を参考にしてください。

http://aws.typepad.com/aws/2010/04/amazon-cloudfront-object-ttl-slashed.html

■ キャッシュが1時間単位だとけっこう面倒

さて、前置きが長くなりましたが、ベターホームレシピではデザイナが
直接S3にアップして静的コンテンツを確認したりします。(もちろん、開発用環境からやりますが)
しかし、以下のような問題によくぶつかっていました。

 ・静的コンテンツ(画像、CSS)などを更新しても、HTML内はCloudFrontのURLを
  指しているので、1時間以上待たないと更新が確認できない。
 ・デザイナがExpireヘッダなどいちいち意識するのはとても面倒

うちのデザイナは技術力もあるため、S3を直接触るような運用になっている事情もあるのですが、
何かとこのキャッシュのタイミングは面倒な作業が発生していました。

そのため、

「CloudFront上のコンテンツをゴリゴリ編集できるようにしたい、もうキャッシュ切れを待つのは面倒」

という不満がチーム内(デザイナだけですが)にただよっていました。

■ CloudFrontのInvalidation機能

そうしたら、最近以下のような記事を見つけました。
英語の苦手な私は早速スルーしようと思いましたが、ちょっとだけ読んでみると、
どうやら、CloudFront上のエッジサーバのキャッシュを無効にできる機能が
CloudFront API上に実装されたようです。

http://aws.typepad.com/aws/2010/08/new-cloudfront-feature-invalidation.html

用途としては

 ・まれに実施するCSSやJavaScriptの更新
    → ただし、1時間とか1日待つのは面倒ですよね
 ・間違ってエンコードしたビデオファイルをキャッシュから削除

などなどがあがっています。

■ CloudBuddy PersonalでInvalidation機能の使う

「APIが用意されているので、そちらでどうぞ。」

http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=213

と言いたいところですが、現実的にはうちのデザイナはそこまでは
やってくれませんし、そんなことを要求したら喧嘩になりそうなのでやめておきます。
以下の2つのツールが現状は対応しているようです。

   ・CloudBuddy Personal
   ・CloudBerry Explorer

前者で実施してみました。

まずは CloudBuddy Personalをインストールします。

  http://m1.mycloudbuddy.com/downloads.html

メールアドレスなど入力が必要ですが、画面に出てくる指示のままに
進めます。

ダウンロード、インストール後、S3のアクセスキー、秘密キーなどを
入力して、CloudBuddy Personalのエクスプローラ画面を開いてください。

CloudFrontに対応したバケットを選択し、右クリックを押して
以下のように「Object Invalidate」を押してください。

Cf_inv_01

次の画面で、「Distribution」のURLとInvalidateしたいオブジェクトを選択し、
「Create New Invalidation」を押します。

Cf_inv_02

そうすると、たぶん、5分から10分くらいでキャッシュが無効になっているはずです。
リアルタイムじゃないのでご注意ください。
Invalidationする前に、該当のオブジェクトを更新するなりしておくと
ちゃんと確認できます。

CloudBuddy Personalのエクスプローラの右上のCloudFrontボタンから
たどれるCloudFront Consoleでも、Invalidation Listで無効にしたキャッシュオブジェクトの
リストが以下のように確認できます。

Cf_inv_03

はい、このエントリは若干長いですが、CloudFront上のキャッシュオブジェクトの更新は
けっこう簡単です。そして、実際に使うときも技術的なことはほとんど考えなくてよいです。

まだ開発者の私しか試していないので、来週、うちのデザイナに試してもらおうと
思います。きっとこれまでの不満を解消できることでしょう。

フレクトではCloudFrontやS3を使ってデザイナと一緒にコンテンツ運用の
「よりよい仕組み」を作っていけるエンジニアを募集しています。
興味のある方は以下からどうぞ。

 

http://www.flect.co.jp/recruit/index.html

 

CloudFrontのエッジサーバ上にキャッシュされているオブジェクトを更新する

こんにちは。フレクトの大橋です。

私たちが運営しているベターホームレシピ(http://bhmb.jp)では、画像などの静的コンテンツ
の配信にCloudFrontを使っています。

CloudFrontはAmazonが用意しているS3上のオブジェクトを高速に配信する仕組みです。
CloudFrontを使うと、S3のオブジェクトがエンドユーザに対して近くに配置されている
サーバ(エッジサーバ)から配信されるようになり、高速のコンテンツの配信ができます。アメリカ西海岸にあるS3の画像が日本国内のエッジサーバにキャッシュされて、高速に配信できたりします。CDN(Contents Delivery Network)の一種です。

CloudFrontのエッジサーバはオブジェクトへのアクセスがあったときに、もしエッジサーバ上に
オブジェクトがあれば、それを配信し、なければ、S3にアクセスしにいき、
配信します。S3から取得したオブジェクトはエッジサーバ上にキャッシュされます。

キャッシュされる時間はS3のメタデータ(HTTPヘッダなど)にTTLを設定すれば制御できます。
以前は24時間が最短でしたが、現在は1時間を最短にできます。
Expireヘッダに1時間後の時間を設定するなどすれば、1時間ごとにエッジサーバのオブジェクトは
更新されるようになるはずです。詳しくは以下を参考にしてください。

http://aws.typepad.com/aws/2010/04/amazon-cloudfront-object-ttl-slashed.html

■ キャッシュが1時間単位だとけっこう面倒

さて、前置きが長くなりましたが、ベターホームレシピではデザイナが
直接S3にアップして静的コンテンツを確認したりします。(もちろん、開発用環境からやりますが)
しかし、以下のような問題によくぶつかっていました。

 ・静的コンテンツ(画像、CSS)などを更新しても、HTML内はCloudFrontのURLを
  指しているので、1時間以上待たないと更新が確認できない。
 ・デザイナがExpireヘッダなどいちいち意識するのはとても面倒

うちのデザイナは技術力もあるため、S3を直接触るような運用になっている事情もあるのですが、
何かとこのキャッシュのタイミングは面倒な作業が発生していました。

そのため、

「CloudFront上のコンテンツをゴリゴリ編集できるようにしたい、もうキャッシュ切れを待つのは面倒」

という不満がチーム内(デザイナだけですが)にただよっていました。

■ CloudFrontのInvalidation機能

そうしたら、最近以下のような記事を見つけました。
英語の苦手な私は早速スルーしようと思いましたが、ちょっとだけ読んでみると、
どうやら、CloudFront上のエッジサーバのキャッシュを無効にできる機能が
CloudFront API上に実装されたようです。

http://aws.typepad.com/aws/2010/08/new-cloudfront-feature-invalidation.html

用途としては

 ・まれに実施するCSSやJavaScriptの更新
    → ただし、1時間とか1日待つのは面倒ですよね
 ・間違ってエンコードしたビデオファイルをキャッシュから削除

などなどがあがっています。

■ CloudBuddy PersonalでInvalidation機能の使う

「APIが用意されているので、そちらでどうぞ。」

http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=213

と言いたいところですが、現実的にはうちのデザイナはそこまでは
やってくれませんし、そんなことを要求したら喧嘩になりそうなのでやめておきます。
以下の2つのツールが現状は対応しているようです。

   ・CloudBuddy Personal
   ・CloudBerry Explorer

前者で実施してみました。

まずは CloudBuddy Personalをインストールします。

  http://m1.mycloudbuddy.com/downloads.html

メールアドレスなど入力が必要ですが、画面に出てくる指示のままに
進めます。

ダウンロード、インストール後、S3のアクセスキー、秘密キーなどを
入力して、CloudBuddy Personalのエクスプローラ画面を開いてください。

CloudFrontに対応したバケットを選択し、右クリックを押して
以下のように「Object Invalidate」を押してください。

Cf_inv_01

次の画面で、「Distribution」のURLとInvalidateしたいオブジェクトを選択し、
「Create New Invalidation」を押します。

Cf_inv_02

そうすると、たぶん、5分から10分くらいでキャッシュが無効になっているはずです。
リアルタイムじゃないのでご注意ください。
Invalidationする前に、該当のオブジェクトを更新するなりしておくと
ちゃんと確認できます。

CloudBuddy Personalのエクスプローラの右上のCloudFrontボタンから
たどれるCloudFront Consoleでも、Invalidation Listで無効にしたキャッシュオブジェクトの
リストが以下のように確認できます。

Cf_inv_03

はい、このエントリは若干長いですが、CloudFront上のキャッシュオブジェクトの更新は
けっこう簡単です。そして、実際に使うときも技術的なことはほとんど考えなくてよいです。

まだ開発者の私しか試していないので、来週、うちのデザイナに試してもらおうと
思います。きっとこれまでの不満を解消できることでしょう。

フレクトではCloudFrontやS3を使ってデザイナと一緒にコンテンツ運用の
「よりよい仕組み」を作っていけるエンジニアを募集しています。
興味のある方は以下からどうぞ。

 

http://www.flect.co.jp/recruit/index.html

 

採用情報

株式会社フレクトでは、事業拡大のため、
・Salesforce/Force.comのアプリケーション開発
・HerokuやAWSなどのクラウドプラットフォーム上での
Webアプリケーション開発
をする、エンジニアを募集中です。

未経験でも、これからクラウドをやってみたい方、
是非ご応募下さい。

フレクト採用ページへ

プロフィール

執筆者:大橋 正興
株式会社フレクト 取締役

【得意分野/業務分野】

B2Cのサイト開発を主な業務領域とするシステムエンジニアです。あと、Salesforce.com認定デベロッパーです。AW、Salesforce、システム基盤構築・運用、サーバ/インフラ構築・運用が今の注力分野です。

【簡単な経歴】

埼玉県所沢市出身。1979年生まれ。大学からSFC。修士(政策・メディア)。ソニーエリクソンで携帯電話のアプリ・ミドル の先行開発に従事したあと、フレクトに参加。2009年6月より取締役。ベターホームレシピの開発ディレクション等、B2Cサイト構築においてアプリ開発やインフラ構築などに従事中。

会社紹介

株式会社フレクトは、
認定コンサルタント
認定上級デベロッパー
認定デベロッパー
が在籍している、セールスフォースパートナーです。
セールスフォースパートナー
また、heroku partnersにも登録されています。
herokuパートナー
株式会社フレクトのSalesforce/Force.com
導入支援サービス
弊社の認定プロフェッショナルが支援致します。
・Visualforce/Apexによるアプリ開発
・Salesforceと連携するWebアプリ開発
も承っております。
セールスフォースご検討の際は、
お気軽にお問合せください。

Twitter

頻繁ではないですが、ときどきツイートしています。 お気軽にフォローしてください。

2021年9月

      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
ブログ powered by TypePad