レベル: 中級 Jack Herrington (jherr@pobox.com), Editor-in-Chief, Code Generation Network
2007年 1月 23日 Amazon の S3 (Simple Storage Service) リモート・ストレージ・サービスを利用してメディア・ファイルをホストし、ディスク・スペースと帯域幅を節約すると同時にサイトの信頼性を向上させましょう。また S3 は、Web 2.0 の世界では非常に一般的な、拡大する一方のマルチメディア・ファイルを扱えることから、サイトの信頼性を改善することもできます。
Web 2.0 と共に、Web ではマルチメディアが一般的になりました。Flikr は、開設後数週間で何百万もの画像を扱うようになりました。Web 1.0 の時代の切手サイズほどのビデオは、Google Video や YouTube によるブラウザー画面一杯のムービーにとって代わられました。では、小さな PHP アプリケーション開発者はどうすべきなのでしょう。膨大な数の画像や巨大なビデオ・ファイルをホストしたいとしたら、どんなことが起こるでしょう。9 ドルのホスティング・アカウントだけで、それだけのスペースと帯域幅に対応できるのでしょうか。また、ホスティング会社のインターネット接続は、そうしたトラフィックに追いつけるのでしょうか。おそらく無理でしょう。
幸い Amazon が、まったく新しいタイプのコンシューマー・レベルの Web サービス、リモート・ストレージを持って救いに登場しました。わずか数セントで、何ギガバイトもの、どんな種類のデータでも Amazon に保存し、ホストさせることができます。皆さんのサイトでこのスペースを画像の保管に使うこともでき、あるいはバックアップ・ホストとして Amazon を使うこともできるのです。
この記事では、一連の PHP ページを使いながら、Amazon S3 を使ってマルチメディア・ファイルをホストする方法について説明します。多少わかりにくいところはありますが、Amazon はコンテンツのアップロードや取得のための方法をいくつか用意しているため、利用プロセスは簡単です。
Amazon S3 について
Amazon S3 ストレージ・サービスの使い方は簡単です。AWS (Amazon Web Services) ストアーから自分が希望するストレージ・サービスを選択し、Subscribe をクリックします。そこで支払い方法 (通常はクレジット・カード) を設定します。本や DVD を買うために日頃使っているカードで構いません。Amazon は、ユーザーがアップロード、あるいはダウンロードするギガバイトごとにクレジット・カードに課金します。ストレージの設定が終わると、リンクを含んだ e メールが送られてきます。そのリンクから自分のアカウント ID と秘密鍵にアクセスすることができます。
そこから先に進むために、バケット (bucket) とオブジェクトという 2 つの重要な概念を理解する必要があります。バケットはハードディスクのディレクトリーのようなものです。オブジェクトはバケット内の名前付きのデータ・ブロックです。その中には何でも好きなものを入れることができます。Amazon が、ファイルではなくオブジェクトという用語を使っているのはこのためです。例えばこの記事の場合、私は Amazon S3 に画像ファイルをアップロードするので、各オブジェクトは 1 つのファイルに対応します。
 |
バケットの名前の付け方
バケットには任意の名前を付けられますが、注意すべきことがあります。バケットの名前のための空間は、このサービスを利用する全員で共有されています。そのため、バケットにはユニークな名前を付けることです。バケット内のオブジェクトには任意の名前を付けることができます。
|
|
Amazon S3 は、バケットとバケット内オブジェクトの作成、編集、削除のための方法として、複数の方法をサポートしています。ユーザーの好みで SOAP を使うこともできます。あるいはこの記事の場合のように、REST (Representational State Transfer) プロトコルと curl コマンドライン・ユーティリティーを使って、Amazon S3 サーバーに HTTP 上で GET、PUT、DELETE コマンドを発行することもできます。PUT コマンドはバケットまたはオブジェクトを作成し、DELETE はバケットまたはオブジェクトを削除し、GET はバケットに関する情報や、オブジェクトからデータを取得します。
オブジェクトは、いくつかのレベルのアクセス・コントロールを持つことができます。この記事に関係するレベルとしては、バケットの所有者のみがバケットの内容を読める private と、誰でも内容を読めるものの変更はできない public-read という 2 つがあります。ここでは、Amazon S3 を使って私の画像を公開できるように、public-read オプションを使います。これらの画像の URL の形式は、http://[bucketname].s3.amazonaws.com/[object] あるいは http://s3.amazonaws.com/[bucketname]/[object] のいずれかです。私の画像アップロード・アプリケーションでは、アップロードされた画像の URL は、http://jherr_photos.s3.amazonaws.com/IMG_2912.jpg のような形式です。これは非常にすっきりした形式だと思います。
サンプル・アプリケーション
これから作成するアプリケーションは非常に単純です。1 つのページがあり、このページにはファイルを受け付けるフォームがあります。このページは次にアップロード・ページにポストされ、アップロード・ページが新しいオブジェクトを、画像コンテンツと共に私の Amazon S3 バケットに追加します。この概念を図 1 に示します。
図 1. Amazon S3 に画像をアップロードする
実際には、スクリプトは私が何をアップロードしようと気にしません。単純にコンテンツ・ファイルと、そのアップロード・ファイルに関連付けられた MIME タイプを Amazon S3 に送信するだけです。ですから、ムービーでも何でも好きなものをアップロードすることができます。
何らかの画像が Amazon S3 にある場合には、もう 1 つのページがバケットの内容を表示します。この概念を図 2 に示します。
図 2. 画像ページに対するデータの流れ
重要な点として、HTML ページのデータは私のサーバーから来ますが、画像データは Amazon S3 から来ることに注意してください。そうです。つまり私は帯域幅のコストを Amazon に払うのです。しかしそれは同時に、Amazon の巨大なデータ・パイプ、データ・センターの冗長性、そのための全インフラを利用できるという意味でもあります。これはとても PHP のホスト・アカウントで実現できるようなものではありません。つまり巨大なデータ・ファイル (例えばムービーなどの画像) に対しては、そうしたデータをホストするサーバーの信頼性と、そのインターネット・パイプのサイズが非常に重要なのです。
アップロード・ページ
私が提案したアプリケーションを作成するための最初のステップは、Amazon S3 のアカウントを設定することです。それが終われば、あとは Amazon S3 サービスに接続するための、ちょっとした PHP コードを入手することだけです。残念ながら、Amazon も PEAR も、現在は PHP 用の Amazon S3 クラスを持っていません。そこで私はあちこちを探し回り、基本的なことをすべて処理できる、Geoff Gaudreault の Amazon S3 クラスを見つけました。このソースコードは長すぎてここには収まりませんが、「ダウンロード」のセクションに置いてあります。
Gaudreault の Amazon S3 クラスを利用するには、PEAR から Crypt_HMAC モジュールをインストールする必要があります。そこでステップ 3 として、このモジュールを次のコマンドを使ってインストールします。
% pear install Crypt_HMAC
|
インストールが終わったら、Gaudreault の s3.class.php ファイルを編集し、AWS キーと秘密鍵を含めます。秘密鍵は、ユーザーによって書かれたコードが Amazon にリクエストを送信しているのだと Amazon が確認できるように、リクエストの一部を暗号化するために使われます。これは有料サービスなので、この秘密鍵を他の人に渡してはいけません。
実装を始めるには、ファイルのアップロードができるフォームを持つページが必要です。
リスト 1. Index.php
<html>
<body>
<form enctype="multipart/form-data" action="upload.php" method="post">
<input type="hidden" name="MAX_FILE_SIZE" value="2000000" />
<input type="file" name="file" />
<input type="submit" value="Upload" />
</form>
</body>
</html>
|
アップロード・ページをブラウザーに表示します。
図 3. アップロード・ページ
次の index.php スクリプトが、このファイルをアップロード・ページに送信します。
リスト 2. Upload.php
<?php
require( "s3.class.php" );
$srvc = new S3();
$srvc->putBucket( 'jherr_photos' );
$tmpfile = 'tmpfile';
move_uploaded_file( $_FILES['file']['tmp_name'], $tmpfile );
chmod( $tmpfile, 0777 );
$fh = fopen( $tmpfile, 'rb' );
$contents = fread( $fh, filesize( $tmpfile ) );
fclose( $fh );
$srvc->putObject( $_FILES['file']['name'], $contents,
'jherr_photos', 'public-read',
$_FILES['file']['type'] );
unlink( $tmpfile );
?>
|
最初に、Amazon S3 PHP ライブラリーをインクルードします。次に Amazon S3 オブジェクトを作成し、そのオブジェクトを入れるバケットを作成します。Amazon S3 は親切なので、既にバケットがある場合には、もう 1 つバケットを作成しようとするリクエストを単純に無視します。つまりこのコードを一度実行した後は、バケット作成リクエストは無視されます。
バケットを作成したら、アップロードされたファイルを読める場所に移動し、ファイルの中身を読めるようにパーミッションを変更します。次にファイル全体を $contents 変数の中に読み込みます。そうしたら、S3 オブジェクトを使ってこのファイルをバケットに追加します。もし同じ名前を持つファイルが既に存在している場合は、中身がが単純に置き換えられます。スクリプトの最後で、アップロード用の一時ファイルを削除します。
画像を取得する
次のステップでは、アップロードされた画像を Web ページ上で実際に見てみます。そのためには、list.php という別の PHP スクリプトを作成する必要があります。
リスト 3. List.php
<?php
require( "s3.class.php" );
$srvc = new S3();
$resp = $srvc->getBucket( 'jherr_photos' );
preg_match_all( "/\<Key\>(.*?)\<\/Key\>/", $resp, $found );
?>
<html><body><table>
<?php foreach( $found[1] as $key ) { ?>
<tr><td>
<img
src="http://jherr_photos.s3.amazonaws.com/<?php echo($key) ?>" />
</td></tr><?php } ?>
</table></body></html>
|
このスクリプトは、まずライブラリーをインクルードし、S3 オブジェクトを作成します。次に、getBucket() メソッドを使ってバケットの現在の内容を取得します。この情報は、XML コードを含むストリングとして返されます。この XML コードには中身が一杯ですが、最も重要なのは <Key> タグの中に保存されている一群のファイル名です。XML パーサーを使えば <Key> タグを読み出すことができますが、この場合は正規表現を使った方が簡単です。
見つかった <Key> タグの配列が得られたら、表を作成します。この表の各行は 1 つの画像タグを持ち、画像タグにはソース中のファイル名が使われています。私はこのプロセスをテストするために、私と私の家族のクリスマス写真を何枚かアップロードし、それから list.php ページに行きました。その結果が下記です。
図 4. Amazon S3の写真のリスト・ページ
私はこれを、Amazon S3 サンプルの HelloWorld 版だと思っています。これ以上ないほど単純です。コマンドライン・スクリプトを使うこともできますが、ブラウザーで見た方がずっと楽しいものです。Amazon S3 の使い方がいかに簡単か、この例から理解できると思います。
落とし穴
この例は、複雑なものの大部分が S3 クラスの中に含まれているため、実際以上に単純になっています。大部分の Web リクエストは比較的単純ですが、リクエストの署名部分で問題が起こります。Amazon は、ユーザーだけが知っている秘密鍵を使って各リクエストが署名されていることを要求します。そしてこの署名プロセスが、面倒な上にデバッグが難しいのです。ありがたいことに、S3 クラスがこの複雑さを隠してくれます。
S3 クラスを手にすれば、署名プロセスの問題には悩まずに済みます。しかし実際に問題が起きると、1 時間か 2 時間、入念にドキュメンテーションを調べ、また Amazon の署名ツール・ヘルプを使って問題に対応する羽目になります。それが終われば、Amazon S3 サービスとその兄弟分、Amazon SQS (Simple Queue Service) を簡単に使うことができます。
Amazon S3 とその世界
Amazon S3 は、全体的なサービスの一部にすぎません。Amazon S3 に特に関係する他の 2 つのサービスとして、Amazon SQS と、そして驚くべき名前の付いた Amazon EC2 (Elastic Compute Cloud) があります。
Amazon SQS では、アプリケーション同士が名前付きキューを使って通信し合うことができます。名前付きキューの中に、1 つのアプリケーションがさまざまなイベント (例えば「ユーザーを追加した」「レポートを要求する」など) に基づくメッセージを挿入し、別のアプリケーションがメッセージを読んで処理し、そしてそれらをキューから削除します。この機能は TIBCO が提供するサービスと似ており、この機能を利用してエンタープライズ・アプリケーション同士を疎結合することができます。
Amazon EC2 サービスは、この記事の執筆時点でまだベータでしたが、このサービスによって Amazon のサーバー・プールの計算パワーをオンデマンド風に活用することができます。アプリケーションの Amazon Machine Image を作成し、そのイメージを Amazon S3 にアップロードします。こうしてから Amazon EC2 サービスをリクエストすると、アプリケーションのプロセスを開始、停止でき、またプロセスをモニターすることもできます。この機能によって膨大な処理能力がオンデマンドで提供されますが、ただしそれを利用するためのアプリケーションを作成する必要があります。
これら 3 つのサービスを 1 つのパッケージとして見ると、つまり Amazon S3 をディスクとして、Amazon SQS をメッセージング・バックプレーンとして、そして Amazon EC2 をプロセス管理システムとして利用することを考えると、Amazon が何を提供しようとしているのか明確になってきます。Amazon は、小規模から中規模のビジネスを対象に、オンデマンドで処理能力を提供するベンダーになろうとしているのです。そうした意味からは、Amazon EC2 システムの Amazon S3 をいくら使っても無料ということです。
まとめ
Amazon S3 は、皆さんのサイトの帯域幅の負担を一部軽減する他にも、たくさんの便利な使い方ができます。そのためのアイデアをいくつか下にあげました。
-
バックアップ
- Amazon S3 を使ってデータベースの夜間バックアップを行うことができます。そのためには、Amazon の S3Curl コマンド・ライン・スクリプトが非常に便利です。
-
共有ストレージ
- USB ドライブを使う代わりに Amazon S3 フォルダーを作成し、次に Jungle Disk (Amazon S3 をハードディスクのようにマウントします) のようなツールを使ってファイル用の共有リポジトリーを作成します。このリポジトリーを自分用の何台かのコンピューター間でのリポジトリーに、あるいはチームのメンバーとの間でのリポジトリーに使うことができます。さらには、リモート Web サーバーとの間でのリポジトリーにも使うこともできます。
-
小さな Web サイト
- HTML や画像を Amazon S3 にアップロードすることによって、小さな静的 Web サイトを、ほんの数セントで Amazon S3 でホストすることができます。
-
ポッドキャストやビデオ・ブログ、あるいはフォト・ブログ
- Amazon S3 を使うことによって、ポッドキャスト用のメディア・ファイルや RSS V2.0 XML をアップロードでき、また Amazon S3 から直接ポッドキャストを実行することができます。
私は使えば使うほど Amazon S3 を好きになります。インターフェースは単純であり、システムは信頼できます。さらに嬉しいことに、値段が手頃です。皆さんも Amazon S3 を試し、皆さん自身の Web アプリケーションに活用できないか、検討してみてください。
ダウンロード | 内容 | ファイル名 | サイズ | ダウンロード形式 |
|---|
| Source code | os-php-amzmm.s3class.zip | 4KB | HTTP |
|---|
参考文献 学ぶために
製品や技術を入手するために
議論するために
- developerWorks の PHP Developer Forum は PHP 開発者の議論の場として、さまざまな話題を提供しています。PHP のスクリプトや関数、構文、変数、PHP のデバッグなどに関する質問、その他 PHP 開発者に関係するあらゆる話題に関して投稿することができます。
-
developerWorks blogs から developerWorks コミュニティーに加わってください。
著者について  | |  | Jack D. Herringtonは、20年以上の経験を持つシニア・ソフトウェア・エンジニアです。著者には、「Code Generation in Action」、「Podcasting Hacks」、そして近々刊行予定の「PHP Hacks」の3冊があります。彼は30本以上の技術記事も執筆しています。 |
記事の評価
|