レベル: 中級 Teodor Zlatanov, Programmer, Gold Software Systems
2009年 03月 31日 この 5 回からなる連載では、Amazon の S3 (Simple Storage Service) と SimpleDB を利用した単純な写真共有 Web サイトを、Perl と Apache を使用して構築します。この第 1 回目では、S3 と SimpleDB のアーキテクチャーについて調べ、写真共有サイトの設計を行うことで、S3 と SimpleDB の長所と短所を説明します。
さて、皆さんは Amazon の Web サービスの中の、Amazon S3 (Simple Storage Service) と Amazon SimpleDB を学ぼうとしています。そのためには実践演習が一番です。ここでは簡単な写真共有サイトを作成します。
この連載の目標は、適切に設計されたサイトを構築することではありません。そうした演習は既に何度も行われています。その上、Web サイトを構築する作業は難しく、難しい部分のうち技術的な面は一部でしかありません。ですから、「まったく、あんたの記事は最悪だ」などという不満のメールを私に送らないでください。この記事を元に sharethewindbeneathmydonkey.com のようなサイトを作っても最初の週から 100 万ドルも儲けられるわけではないからです。(もし儲けられたとしたら、その元を作ったのは私であることを思い出してください。)
 |
この連載を最大限に活用するために
この連載を読むためには、HTTP と HTML に関する初心者レベルの知識と、JavaScript と Perl (Apache の mod_perl プロセスの内部で使われます) に関する中級レベルの知識が必要です。リレーショナル・データベースやディスク・ストレージ、ネットワークなどの知識があると役に立ちます。この連載は回を追うごとに技術的なレベルが高くなるため、そうしたトピックの知識が必要な場合には「参考文献」セクションを参照してください。
|
|
この連載ではドメイン名として share.lifelogs.com を使います。では Amazon S3 について調べてみましょう。
Amazon S3 の概要
私は UNIX® 管理者になってしばらく経ちますが、私の経験上バックアップ・サービスやファイル保管サービスは決して単純なサービスではありません。SAN、NAS、LUN、LVM、RAID、JBOD、IDE、SCSI などの頭字語を見ても何も感じない人は、おそらく幸せな人です。これらの文字を見て何かを感じる人であれば、ナプキンでそっと涙を拭きながら昼食を食べた経験がきっとあるはずで、例えば、破損した 4 年分の DLT バックアップを回復させる作業を始めて 3 ヶ月過ぎた頃に、もっと適切なデータ管理方法がないのかと思ったりもしたはずです。ただし私が実際にそうした経験をしたわけではありません。
 |
IBM と Amazon Web サービス (AWS)
クラウド・コンピューティングを利用することで、コンピューティング容量、帯域幅、ストレージ、セキュリティー、信頼性などが問題とならない仮想環境でアプリケーションを開発することができます。仮想環境ではユーザー自身のシステムにソフトウェアをインストールする必要がありません。仮想的なコンピューティング環境でアプリケーションの開発、デプロイ、管理を行う場合、この環境を利用した時間と容量に対してのみ支払いをすればよく、ニーズやビジネス要件の変化に応じてスケール・アップやスケール・ダウンをすることができます。
IBM は Amazon Web サービスと提携しており、Amazon の EC2 (Elastic Compute Cloud) 仮想環境で IBM のソフトウェア製品を利用することができます。IBM が EC2 で提供しているソフトウェアは以下のとおりです。
- DB2® Express-C 9.5
- Informix® Dynamic Server Developer Edition 11.5
- WebSphere® Portal Server と Lotus® Web Content Management Standard Edition
- WebSphere sMash
これらは製品レベルのコードであり、すべての機能とオプションが使用可能です。これらの製品の詳細について、またこれらの製品の Amazon Machine Images のダウンロードに関しては IBM developerWorks の Cloud Computing Resource Center を参照してください。
クラウド・コンピューティングに関する他のリソースについては、developerWorks にある開発者向け Cloud Computing スペースを参照してください。
|
|
Amazon の S3 (Simple Storage Service) は分散ストレージ・システムです。Amazon を信頼してデータの保管に S3 を利用するなら、はるかに楽をすることができます。もちろん、念のために必ず皆さん自身でもバックアップを行う必要があります。(またセキュリティーも問題になるかもしれません。S3 にデータを置くということは S3 のアクセス制御システムを使用する必要があるというということであり、それは皆さんの求める認証や許可の要件に合わないかもしれません。詳細については「参考文献」に挙げた S3 のドキュメントを参照してください。)
では S3 によって何が得られるのでしょう。S3 では、ファイルの保存と取得を行う際に、ユーザー・キー (ランダムに見える長いストリング) とユーザー・パスワード (ランダムに見えるもうひとつのストリング) を使っています。課金は Amazon の Web サイトに記載されている S3 の課金体系に従って行われます。コストはそれほど高くはありません。自ら NAS や SAN、あるいはローカル・ディスクを用意して管理するコストに比べれば、S3 のコストは極めて妥当です。
2009年初頭時点での S3 のサービスでは、S3 のデータは Amazon の持つ 2 ヵ所のデータ・センター (米国とヨーロッパにあるセンター) でホストされ、十分なネットワーク接続性が確保されています。米国とヨーロッパ以外の場所で大量の利用者にデータを提供したい場合には、全世界でのパフォーマンスを判断するために設計されている Gomez や Keynote などのサービスを使ってパフォーマンス・テストを実行する必要があります。米国とヨーロッパ内であっても、迅速かつ確実にデータを提供する必要があるビジネスの場合には、そうしたサービスを利用して毎日パフォーマンス・テストを実行するように設定する必要があります。
分散ストレージ・システムの大きな問題は更新遅延です。更新遅延というのは、コンテンツ所有者がアクションを実行してからそのアクションが伝播するまで時間がかかることです。しかしアクションを実行してからそれが伝播するまでの時間だけが潜在的な懸念事項というわけではありません。伝播が均一に行われない場合には、顧客がコンテンツを見るタイミングによってその内容が異なってしまう可能性もあります。Amazon はサーバーでの一貫性を保証しています。つまり顧客に対して破損データが表示されることはありませんが、S3 を検討する場合にはこの点を念頭に置く必要があります。画像のアップロードや変更、削除を行う場合には、そうした変更が即座に反映されると思ってはいけません。
CPAN には S3 にアクセスするための Perl ライブラリーが用意されており (「参考文献」を参照)、なかでも Net::Amazon::S3 は優れた選択肢のひとつです。Amazon S3 のリソース・ページには他にも数多くのライブラリーが挙げられていますが、この記事ではこれらのライブラリーを使用しません。ここで行う S3 の統合ではコンテンツをアップロードする際に Perl コードを使わずに S3 の機能を使用します (また、JungleDisk アドオンや Firefox S3Fox アドオンなど、S3 にアクセスするための便利なツールも数多くあり、これらのツールは Perl を使わずにデータを容易に管理するには、うってつけのツールです。)
Amazon S3 の例
さて、S3 で何が得られるかの説明を続けましょう。ファイル (S3 では「オブジェクト」と呼ばれます) は「バケット」に保存されます。各バケットの中で、ファイル名 (ファイルの「キー」) は一意でなければなりません。ファイルの属性には「color」や「language」などの名前を付けることができますが、属性はファイル名の一部とは見なされません。
例えば、米国の国旗の画像を「images/flag.png」として「us.images.share.lifelogs.com」というバケットに保存し、ドイツの国旗の画像を「images/flag.png」として「de.images.share.lifelogs.com」に保存するとします (ファイルは名前が同じですが異なるバケットの中にあります)。すると、ユーザーが http://us.images.share.lifelogs.com.s3.amazonaws.com/images/flag.png を要求すると米国の国旗が得られ、http://de.images.share.lifelogs.com.s3.amazonaws.com/images/flag.png を要求するとドイツの国旗が得られます。さらに、DNS の中で de.images.share.lifelogs.com に de.images.share.lifelogs.com.s3.amazonaws.com というエイリアスを付け、us.images.share.lifelogs.com にも同様のエイリアスを付けると、ユーザーは http://us.images.share.lifelogs.com/images/flag.png または http://de.images.share.lifelogs.com/images/flag.png を要求するだけで目的の国旗を得ることができます。
Amazon S3 のすべてのアカウントの中でバケットの名前が一意でなければならないことに注意してください。そのため、「test」や「default」といった名前は不適切です。可能であれば、フル・ドメイン名でバケット名を修飾します。そうすれば DNS の中でのバケットの識別や使い方が容易になります。また、バケット名には制限があり、小説になるほどの長い名前をバケットに付けてはいけません。またバケットの名前に使用する文字は、ドメイン名に使用できる文字と同じ種類のものにとどめる必要があります。
S3 は複雑なサービスなので、先に進む前に S3 のホームページをよく見ることをお勧めします。
Amazon SimpleDB の概要
プロの講演者や大学教授が、前の列で居眠りをしている、午前 3 時までテキーラを飲んでいた人を起こそうとして、「データベースは重要です」と声を高める部分がここです。
皆さんは眠くなっていませんか?
私達が日々目にしている生データの洪水は、ソートされ、フィルタリングされ、集約され、平均化され、分析されて、管理不可能なほどの情報の流れとなります。こうしたデータベースをホストするためには IT の専門家がフルタイムで働く必要があります。データベースのホスティングには、スペースや電力、バックアップ、その他多数のリソースが必要になります。SimpleDB のようなホスト・データベースはビジネス上の金銭的な判断をする上で検討の価値がありますが、ここでは技術的な側面のみを説明します。
簡単なデータベースの一例として、冷蔵庫に貼り付けてある ToDo リストがあります。このリストでは各行に 1 つずつ項目が記載されていて、一部の項目の隣にはチェック・マークが付けられ、また一部の項目にはバツ印が付けられているかもしれません。このリストを従来のリレーショナル・データベースでモデリングすると、2 つの列を持つ 2 つのテーブルになります (表 1)。
表 1. todo_foreign テーブル
| 項目 | ステータス・コード (status.statuscode に対する外部キー、 デフォルトは 0) |
|---|
| 母に電話する | 0 | | 税務署に電話する | 2 | | 牛乳を買う | 1 |
表 2. ステータス・テーブル
| ステータス・コード | ステータス |
|---|
| 0 | アクティブ | | 1 | 完了 | | 2 | 削除済み |
「ちょっと待ってください」と皆さんは言うかもしれません。項目が完了した日付や削除された日付、変更した人に関してはどうするのでしょう。またデータ型は何なのでしょう。結局のところ、こうしたことのために賢くて能力のある DBA (データベース管理者) を育てているのであり、彼らは正規形や外部キー、SQL などのすべてを知っています。今すぐに、ぜひとも DBA に設計を見てもらう必要があるのではないでしょうか。
確かにそうしたコメントは的確ですが、とりあえず、この簡単な例を進めましょう。後でゆっくり、『超初心者のための SQL と RDBMS』のような本を読んでください。
Amazon SimpleDB は、広範に分散された、キーと属性によるデータベースです。このデータベースは決してすべてのビジネスに適すものではなく、またパフォーマンスとスケーラビリティーに関して厳しい制約があります。各属性は 1KB に制限されているため、この ToDo リストの項目は 1 キロバイトよりも長い名前を持つことができません。
またセキュリティーも問題です。SimpleDB のアクセス制御システムは S3 のアクセス制御システムと似ています。この連載で作成するような簡単なソーシャル・サイトでは、データベースのバックエンドとして SimpleDB を大いに活用することができます。とは言え、SimpleDB がビジネス上の要件や予算、データ・ストレージに関する要求事項をすべて満たせるかどうかを十分に検討する必要があります。
先ほど触れた、S3 の更新遅延の問題は SimpleDB にも影響します。更新を行っても、その更新がすべての場所で即座に反映されるわけではありません。
この記事での簡単なデータベースの例を使うと、SimpleDB の構造は次のようになります。
表 3. SimpleDB による ToDo リストの構造
| 項目 | ステータス |
|---|
| 母に電話する | アクティブ | | 税務署に電話する | 削除済み | | 牛乳を買う | 完了 |
ここまでは問題ありません。この方が最初の例よりも簡単ではないでしょうか。しかしここで、別の項目を追加したらどうなるでしょう。
ステータスが重複していることがわかるでしょうか。項目を追加したことによって、「アクティブ」がデータベースの中に 2 つ保存されています。こうなると、大規模なテーブルの場合にはストレージとパフォーマンスの点でコストが高くなります。その一方、SimpleDB の各行は自己完結的に設計されており、行を取得すれば、その行に関係する情報をすべて取得することができるため、わざわざステータスを参照しに行ったりする必要がありません。SimpleDB の更新遅延を考えると、ステータスを参照する必要がないことは重要です。
SimpleDB による別の ToDo リスト
ここで一例として waituntiltomorrow という新しいステータス・コードを追加し、このコードを todo_foreign テーブル (外部キーを持つ表 1) の 1 つの項目に適用するとします。すると、2 つの更新を行うことになります (status テーブルに対する更新と todo_foreign に対する更新)。もし status テーブル (表 2) の更新が todo_foreign を更新した後に行われると、データの一貫性が失われることになります。SimpleDB ではユーザーが更新した順序どおりに即座に更新することを保証しているわけではないことを忘れないでください。そのため、(項目の参照とステータスの参照という) 2 度の参照を行うことでパフォーマンスが低下する上に、データの一貫性が失われる可能性もあります。
SimpleDB で重要なことは、列の存在を忘れることです。SimpleDB には列がなく、各行に対して属性があるのです。これらの属性は静的なものではないため、属性の追加と削除は自由にすることができます。ToDo の項目に対して作成日と削除日を追加したい場合には、単にそうした属性を項目に追加します。todo_foreign の場合には、作成日と削除日を追加するためには 2 つの列が必要です (まだ項目がアクティブの場合には削除日はヌルになるかもしれません)。ここで例えば、項目の完了日のための列として、さらに 1 列追加したらどうなるでしょう。あるいはステータス・コードのみにし、削除日を完了日として使うためにはどうすればよいのでしょう。
SimpleDB では、必要なことだけを行えばよいのです。作成日が必要であれば、created_date 属性を追加します。削除日が必要であれば、削除された項目のみにその属性を割り当てます。属性があることで、その属性をその項目に適用する、ということがわかるのです。
列で考えてはいけません。SimpleDB の行は Perl のハッシュによく似ています。つまりすべてのキーはストリングです。そしてすべての値はストリングまたはストリングの配列です。では、先ほどの設計を再度試してみましょう。
リスト 1. todo_freeform
{ item: "call Mom" }
{ item: "call IRS", deleted_date: "2009-03-01" }
{ item: "get milk", done_date: "2009-03-02" }
|
SimpleDB には ItemName という暗黙キー (この場合はストリングとしての ToDo 項目) があることに注意してください。そのため、ToDo リストは次のようになります。
リスト 2. SimpleDB による ToDo リスト
"call Mom" { }
"call IRS" { deleted_date: "2009-03-01" }
"get milk" { done_date: "2009-03-02" }
|
SimpleDB ではオブジェクトは必ず属性を持たなければならないため、すべてのオブジェクトに created_date 属性を追加します。すると次のようになります。
リスト 3. SimpleDB による ToDo リストに created_date を追加する
"call Mom" { created_date: "2009-02-01" }
"call IRS" { created_date: "2009-02-01", deleted_date: "2009-03-01" }
"get milk" { created_date: "2009-02-01", done_date: "2009-03-02" }
|
「しかしちょっと待ってください」と皆さんは叫び、こう続けるかもしれません。「本当にすべてがストリングで、データは厳格に型付けされていないのですか?」
そのとおりなのです。すべてストリングです。これは素晴らしいことではないでしょうか。
さらに、このテーブルの中の削除された任意の項目に deletereason 属性を追加することができ、その 3 ヶ月後にその項目を復活させることもできるのです。それによって何かが影響を受けることはなく、その変更に対応した新しいコードでそれを使用すればよいだけです。
ここで一息入れ、DBA がアスピリンを飲んで元気になるのを待つことにしましょう。DBA がアスピリンを飲もうとすると、Perl プログラマーは親切なので DBA に水を持ってきてくれます。
サンプル・データベースの話を続けましょう。重要なことは、アクティブな項目、削除された項目、完了した項目を取得するためのクエリーを考えることです。これは実は非常に簡単です。SimpleDB のドキュメントを見ればすべてのクエリーの作成方法が説明されています。ここでは SELECT 言語を使います。QUERY 言語もありますが SELECT の方が SQL に近いため、大部分の読者には SELECT の方が理解しやすいはずです。
リスト 4. todo_freeform クエリー
-- get active
select * from todo_freeform where done_date is null and deleted_date is null
-- get deleted
select * from todo_freeform where deleted_date is not null
-- get done
select * from todo_freeform where done_date is not null
|
これだけです。では SimpleDB と S3 とを組みあわせてみましょう。
サービスを統合し、写真を共有する
では SimpleDB と S3 とをどう接続するのでしょう。(SimpleDB と S3 とは同じアクセス制御モデルを使用しますが、SimpleDB と S3 とが初めから接続されているわけではありません。) 接続方法は簡単です。単純にバケットと S3 オブジェクトの名前を SimpleDB の中に保存すればよいだけです。ToDo リストはもう十分なので、今度は写真共有サイトの設計を始めることにしましょう。
このサイトは写真を S3 に保存し、ユーザー・コメントを SimpleDB に保存する必要があります。ではユーザー・アカウントはどうするのでしょう。ここでは SimpleDB が分散型であることを我慢しなければなりません。つまり場合によると、無効なユーザーがいるということです (例えばユーザーは削除されていなくても、そのユーザーを参照する行は削除されている、など)。ただしこのアプリケーションでは、ユーザーを SimpleDB の中に保持することにします。ここでは任意の場所に素早くサイトをセットアップできることが目標なので、外部データベースに対する依存関係はまったくありません。そこで、mod_perl の下で実行される Perl のグルー・コードを少しばかり使用し、実際のアクションを S3 と SimpleDB の中で実行します。
まず、写真のテーブルが必要です。レコードは次のようなものです。
リスト 5. 写真のテーブルのレコード、share_photos
"http://developer.amazonwebservices.com/connect/images/amazon/logo_aws.gif"
{ user: "ted", name: "Amazon Logo"}
"http://images.share.lifelogs.com/funny.jpg"
{ user: "bob", name: "Funny Picture", s3bucket: "images.share.lifelogs.com" }
|
次に、ユーザーのテーブルが必要です。
リスト 6. ユーザーのテーブル、share_users
"ted" { given: "Ted", family: "Zlatanov" }
"bob" { given: "Bob", family: "Leech" }
|
そしてコメントが必要です。
リスト 7. コメント、share_comments
"random-string"
{
url: "http://images.share.lifelogs.com/funny.jpg",
comment: "Ha ha",
posted_when: "2009-03-01T19:00:00+05"
}
"random-string2"
{
user: "ted",
url: "http://developer.amazonwebservices.com/connect/images/amazon/logo_aws.gif",
comment: "No it doesn't",
posted_when: "2009-03-01T20:00:01+05"
}
"random-string3"
{
url: "http://developer.amazonwebservices.com/connect/images/amazon/logo_aws.gif",
comment: "No it doesn't",
reply_to: "random-string2",
posted_when: "2009-03-01T20:00:01+05"
}
|
 |
注意事項
Google も Amazon と同等なサービスをいくつか提供していますが、この連載は決して Google のサービスと Amazon のサービスとを比較するためのものではありません。そうした比較はオンラインでたくさん行われています。またこの連載では Amazon による EC2 (Elastic Compute Cloud) などの他のサービスについても触れませんが、これらのサービスも興味深く便利なものであり、Web サイトを構築する際には確かに役立ちます。そして、SimpleDB に匹敵する CouchDB のような、キーと値による分散型データベースが他にもあるので、それらについても詳しく調べてみることをお勧めします。
|
|
reply_to キーを調べることでコメントをスレッド化します。すべての投稿には一意のキーとしてランダムなストリングが付加されます。
ここで以下のような規則を作成したことに注目してください。
user 属性がない場合には、コメントは匿名の人からのものであることを意味します。
- 写真の URL によってすべてのコメントが結び付けられるため、写真の URL を変更してはいけません。
- S3 オブジェクトにも URL があります (URL には S3 オブジェクトとして識別するためのバケット名を使います)。
- URL はオブジェクトのキーなので、写真の URL を重複させてはいけません。
これはテーブルの設計の最終版ではありません (SimpleDB が非常に柔軟なことを忘れないでください)。それでも最初の手掛かりとしては十分です。
まとめ
この記事では S3 と SimpleDB の長所と短所を少し詳しく説明しました。この説明は決して完全ではありませんが、Amazon の S3 と SimpleDB が皆さんのプロジェクトにとって適切かどうかを判断するためには役立つはずです。
この記事では SimpleDB による簡単な ToDo リストの例を取り上げ、ユーザー、写真、コメントそれぞれのテーブルのデータ・レイアウトの設計をどのように始めればよいかを説明しました。第 2 回では S3 と SimpleDB を利用する Web サイト (mod_perl を使用した Apache) とライブラリーのセットアップ方法について説明します。
参考文献 学ぶために
製品や技術を入手するために
議論するために
著者について  | 
|  | Teodor Zlatanov は 1999年にボストン大学 (Boston University) でコンピューター工学の修士号を取得しています。彼は 1992年からプログラマーとして働いており、Perl、Java、C、C++ を使ってきています。彼が関心を持っている領域は、オープンソースによるテキスト構文解析、データベース・アーキテクチャー、ユーザー・インターフェース、UNIX システム管理などです。 |
記事の評価
|