Amazon Web Services

2010年11月18日 (木)

Amazon SimpleDBをコマンドラインから使う方法

こんにちは、大橋です。

前回、Amazon SimpleDBに関して記事を書きましたが、
今回は実際にSimpleDBに触ってみる方法を書きます。

■ まずはツールの選択

GUIベースのツールでは以下のようなツールがあります。

・AWS Toolkit for Eclipse
     http://aws.amazon.com/eclipse/
・SDB Explorer(有料、試用期間あり)
     http://www.sdbexplorer.com/

最初のものはAmazon純製ですね。
また、CUIでは以下のようなものがあります。

・Amazon SimpleDB command line interface(amazon-simpledb-cli)
 http://code.google.com/p/amazon-simpledb-cli/

他にもツールはいろいろあると思いますが、サーバ管理者としては
CUIベースでできるものがほしいので、まずはamazon-simpledb-cli
を使ってAmazon SimpleDBを操作できるようになりたいと思います。

■ amazon-simpledb-cliのインストール

【モジュールのインストール】

amazon-simpledb-cliはPerlでできています。
最初に必要な以下のモジュールをインストールします。

  • Getopt::Long
  • Pod::Usage
  • Digest::SHA1
  • Digest::HMAC
  • XML::Simple

cpanmでインストールすると簡単です。以下のようにcpanmコマンドを実行すると
インストールできます。簡単ですね。

 > cpanm XML::Simple

cpanmの使い方インストール方法は以下が分かりやすいので参考にしてみてください。
http://www.omakase.org/perl/cpanm.html

 【Amazon SimpleDB用のPerlモジュールのインストール】

次にAmazon SimpleDB用のモジュールのインストールをします。
モジュールをダウンロードして、以下のようにコマンドを打ってインストールします。

> curl -Lo amazon-simpledb-perl-library.zip http://amazon-simpledb-perl-library.notlong.com
> unzip amazon-simpledb-perl-library.zip
> sitelib=$(perl -MConfig -le 'print $Config{sitelib}')
> sudo cp -r AmazonSimpleDB-*-perl-library/src/Amazon $sitelib/

これでモジュールセットアップは完了です。

 【simpledbコマンドのインストール】

> sudo curl -Lo /usr/local/bin/simpledb http://simpledb-cli.notlong.com
> sudo chmod +x /usr/local/bin/simpledb

なお、simpledbコマンドの1行目は 「#!/usr/bin/perl」 となっています。
必要に応じて「#!/usr/bin/env perl」などと書き換えてください。

【環境変数のセットアップ】

コマンドとして実行したり、.bashrcに記載するなどして以下のようにAmazon SimpleDBのアクセスキーと秘密キーをセットアップしておいてください。

export AWS_ACCESS_KEY_ID='xxxxxxxxxxxxxxxxx'
export AWS_SECRET_ACCESS_KEY='xxxxxxxxxxxxxxxxxxxx'

【インストールできているか確認する】

PATHが/usr/local/binに通っている場合は以下のようにコマンドを打つと
ちゃんと実行され、ヘルプがでます。/usr/local/bin/simpledb とコマンドを
打ってもOKです。

> simpledb
Usage:
     simpledb [opts] create-domain DOMAIN
     simpledb [opts] delete-domain DOMAIN
     simpledb [opts] list-domains

     simpledb [opts] put         DOMAIN ITEM [NAME=VALUE]...
     simpledb [opts] put-replace DOMAIN ITEM [NAME=VALUE]...
     simpledb [opts] get         DOMAIN ITEM [NAME]...
     simpledb [opts] delete      DOMAIN ITEM [NAME[=VALUE]]...

     simpledb [opts] select SELECTEXPRESSION

Options:
     --help         Print help and exit.

     --aws-access-key-id KEY
                    AWS access key id
                    [Defaults to $AWS_ACCESS_KEY_ID environment variable]

     --aws-secret-access-key SECRETKEY
                    AWS secret access key
                    [Defaults to $AWS_SECRET_ACCESS_KEY environment variable]

     --max COUNT
                    Maximum number of domains/items to retrieve and list.
                    [Defaults to all]

     --separator STRING
                    Separator between attribute name and value.
                    [Defaults to equals (=)]

Arguments:
     DOMAIN            Domain name
     ITEM              Item name
     NAME              Attribute name
     VALUE             Attribute value
     SELECTEXPRESSION  SimpleDB select expression

■ amazon-simpledb-cliを使ってみる】

【コマンド書式】

基本的な書式は以下です。

> simpledb コマンド名 ドメイン名 値

【ドメイン作成】

書籍(book)ドメインを作ってみましょう。以下のようにすればドメインが作成できます。

> simpledb create-domain book

【値を何かputしてみる】

putコマンドで書籍(book)ドメインに書籍アイテムを一つ入れてみましょう。Itemの主キーとなる部分にはITEM名には
ISBN(4873110963の部分)を登録します。その他は書籍名(name)、値段(price)、著者名(author)をいれます。

> simpledb put book 4873110963 name='Programming Perl' price=5565 author='Larry Wall'

【アイテムの属性(Attribute)に2個目の値を入れてみる】

SimpleDBで1つの属性に複数の値を入れることができます。以下のようにすれば、2つ目の値が入ります。
主キーとなる部分にはISBNを指定し、追加する属性のところだけ値をいれます。

> simpledb put book 4873110963 author='Tom Christiansen'

【アイテムを更新する】

アイテムの属性に値を追加するのではなくて、アイテムそのものを入れ替える場合は以下のようにput-replacekコマンドを使います。

> simpledb put-replace book 4873110963 name='Programming Perl' price=5565 author='Larry Wall'

【Select文でアイテムを取得する】

以下のようにSelect文でアイテムの情報が取得でき、出力が得られます。
アイテムごとの最初の行がITEMのキー(この場合はISBN)です。

> simpledb select 'select name, price, author from book'
4873110963   # ISBN(主キーの部分)
author=Larry Wall
author=Tom Christiansen
price=5565
name=Programming Perl

以下のようにLike文などSQLっぽいクエリを投げることができます。

> simpledb select 'select name, price, author from book where author like "Larry%" '

likeや=, >, <, OR, ANDなどいろいろな演算子が使えます。詳しくは以下あたりから
情報をたどるといろいろなクエリが分かります。

http://docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/index.html?UsingSelect.html

機会があれば、もう少し丁寧にクエリを解説したいですが、今回はスキップします。

【アイテムをgetする】

以下のようにITEMのキーを指定して、アイテムを1つ取得することができます。

> simpledb get book 4873110963 
author=Larry Wall
author=Tom Christiansen
price=5565
name=Programming Perl

【アイテムを削除する】

以下のようにITEMのキーを指定して、アイテムを1つ削除できます。

> simpledb delete book 4873110963

【ドメインを削除する】

最後にドメインの削除です。以下のようにdelete-domainコマンドで削除できます。

> simpledb delete-domain book

【まとめ】
以上がAmazon SimpleDBをコマンドラインから使う方法の紹介です。

一通りこれだけのコマンドが分かっていれば、デバッグするなど簡単な
オペレーションはだいぶ便利になると思います。

次回はJavaでAmazon SimpleDBを操作してみたいと思います。また、Consistent ReadやConditional Put/Deleteについても近いうちに書いてみるつもりです。

2010年11月16日 (火)

Amazon SimpleDBについて調べたことをまとめました

こんにちは。大橋です。

最近、セールスフォース関連の仕事でAmazon SimpleDBの話題がでることがあったのですが、
EC2やS3に比べると情報が少ないなぁ、というのを実感しました。

そこで、SimpleDBについていろいろ勉強してみました。ただ、量が多いので分割して
記事にしたいと思います。今回の記事ではSimpleDBとは何かということ、RDBと比較しながら
データモデルの説明、そしてどのような操作(API)があるのか、制約、メリットなど、
調べたことをまとめたいと思います。

【SimpleDBとは?】

SimpleDBはHTTPベースのAPI(REST/SOAP)で操作できる構造化されたデータストアです。
Amazonのページによると以下のように説明があります。

Amazon SimpleDB は可用性、拡張性、柔軟性の高い、非リレーショナル型データストアで、
データベース管理の負荷を軽減します。開発者は簡単なwebインターフェイスを使ってデータの保存や参照を行うだけで、
後はAmazon SimpleDB が残りの部分を担当します。

RDBではないのですが、ある程度構造化されたデータをHTTPベースのAPIで
簡単に扱うことができるデータベースというところです。

では、中身を追っていきます。

【データモデル】

Amazon SimpleDBのデータモデルをRDBと比較しながら説明します。

例として以下のような書籍データベースを考えてみます。
RDB的には以下の表そのものがテーブルに該当します。フィールドは書籍名(Name)、価格(Price)、商品のURL(URL)、著者名(Author)で、主キーにあたるところがISBN(Item Name)にあたると考えてください。

Simpledb_2


SimpleDBでは、上記の表のようなデータについて以下のように考えます。

(やや乱暴な言い方ですが、)RDBのテーブルに該当するのが「ドメイン」です。上記の表の1レコード1レコードは1つのアイテムです。
アイテムにはアイテムを一意に決めるユニークなキーがあります。それがItemのNameです。
ここはユニークでないといけません。この書籍のデータではISBNを入れています。

アイテムは複数の属性(Attribute)を持ちます。これが書籍名(Name)、価格(Price)、商品のURL(URL)などのフィールド(カラム)に該当します。各属性には名前と値があり、Price(名前)=3780(値)というように指定します。また、値はすべて文字列で、インデクシングされます。RDBならば各属性には1つの値しか入れることはできませんが、SimpleDBでは1つの属性に複数の値を入れることができます。上記の表では著者名(Author)が該当します。

なんとなく分かりましたでしょうか。乱暴な言い方をすれば、以下のように考えればよいかと。

  • テーブルがドメイン
  • RDBのレコードにあたるものがアイテム(Item)
  • 主キーにあたるところがItem Nameでドメイン内ではユニークでないといけない
  • 各フィールド(カラム)のことは属性(Attribute)という。
  • 1つのアイテムのある属性の値は複数持つことができる
  • 属性の値は文字列だけ。すべての値はインデクシングされる。


【SimpleDBの機能】

次に、SimpleDBがアプリ開発者に提供している機能を紹介します。ドメイン操作に関することと、アイテムなどデータを操作に関することの大きく2つの機能群があるのでそれぞれ説明します。

ドメイン操作

ドメイン操作には以下の4種類の機能がAPIとして提供されています。

  • CreateDomain

        ドメインを作成します

  • DeleteDomain

        ドメインを削除します

  • ListDomains

        アクセスキー、秘密キーでアクセスできるドメインのリストをできます。

  • DomainMetaData

        ドメイン名、ドメイン内のアイテム数や属性値の数など、ドメインに関するメタ情報を取得できます。

データ(Item)操作

データ操作には以下の操作がAPIとして提供されています。

  • PutAttributes

        アイテムと属性を登録するか、アイテム名を指定して属性を登録/更新します。

  • GetAttributes

        アイテムのNameを指定して、アイテム情報を1件取得できます。

  • BatchPutAttributes

        複数のアイテムをまとめて登録/更新できます。(1回の操作で25件)

  • Select

        SimpleDB用のselect文でアイテムを取得できます。

  • DeleteAttributes

        アイテムから属性を削除します。また、アイテムそのものを削除します。

  • BatchDeleteAttributes

        複数のアイテムについて属性削除からアイテムそのものを削除します。

【ドメイン/アイテムに関する制約事項、気をつけるポイント】

ここまで、「どんなことができるか」を簡単に説明してきましたが、それなりに制約もあります。

以下に気をつけたほうがいい制約事項を列挙します。

  • APIのリクエストサイズは1MBを超えることはできません。(BatchPutAttributesあたりで関係します)
  • 1つのアイテムにつき、属性は最大256個までです。
  • 1つのドメインに10億アイテムまで格納できます。つまり、それを超えた場合はドメイン名を変更するなど対処が必要です。
  • ドメインごとに最大10GBのユーザデータを持つことができます。
  • 1つのアカウントにつき100件のドメインを作成できます。ただし、AWSのサポートに連絡すれば追加ドメイン作成もお願いできるようです。※ http://aws.amazon.com/contact-us/simpledb-limit-request/ でお願いできるみたいです。
  • 1つのクエリ(select)で取得できるアイテム数は最大2500です。
  • RDBではないので、joinはできません。工夫してデータモデルの設計を行いましょう。
  • RDBのようにスキーマを事前に定義するわけではありません。いわゆるスキーマレスなデータベースになります。

それと、Wikipediaに以下のように記載がある通り、CAP定理に置ける一貫性は成立していないです。この辺がクラウド的(?)です。

CAP定理において、一貫性が成立していなく、それゆえ、書き込みをしても、一貫性読み込みを指定しない限り、読めるようになるまで1秒程度以下の時間がかかる。


【うれしいポイント】

制約も説明したので、個人的にうれしいと思っているポイントも列挙しておきます。

  • 管理が簡単

        インストールとかセットアップとかほとんど不要です。

        バッファとか一所懸命調整しなくても十分なパフォーマンスが出ます(出るらしいです)。

  • 高い可用性

        Amazon S3やSQSと同じように高い可用性があります。

        データは地理的に分散された環境の保存されるのでMySQLで

        一所懸命レプリケーション設定する、みたいなことはしなくてよいです。

  • EC2と使うのであれば高速

        同一リージョンであればLAN内アクセスと同程度の遅延でアクセスできます。

  • HTTPベースなのでEC2以外からも容易にアクセスできる

        オンプレミスの環境やセールスフォースなど他のクラウド環境からも

        REST/SOAPのAPIを通じて簡単にアクセスできます。

        SimpleDBを介したデータ連携なども容易にできます。
        (注意しないとセキュリティ上危険なことにもなりそうですが)

  • すごく安い

        あとで説明しますが、すごく安いです。

        Amazonのデータベースサービスでは他にAmazon RDSが
        ありますが、それと比べてもずっとずっと安いです。

【課金体系】

詳細は以下を見てください。安いです。

http://aws.amazon.com/jp/simpledb/#pricing

US価格だとデータ転送は送信に限り、0.15ドル/GB(US価格)、データ保存は1ヶ月に0.25ドル/GBです。それぞれ最初の1GBは無料です。それと、PUT/GET/Selectなどのクエリを実行するのに使ったSimpleDBのマシン稼働時間も課金対象です。毎月、最初の25時間は無料で、そのあとは1時間あたり0.140ドルです。

【まとめ】

今回はSimpleDBについてその概要的なことを説明しました。
joinができない、スキーマレス、一貫性、あたりにとまどいが出てしまう面はありますが、
簡単に使えて、Amazonクォリティの可用性があるデータベースということで、けっこう魅力があると思っています。特に、EC2だけでなく多様な環境が入り交じったときなどにHTTPベースのAPIで操作できることは大きなメリットがあるのではないかと考えています。

次回からはコマンドラインでの使い方やプログラムからの使い方など
より実戦で使いそうな内容を書いていきたいと思います。

2010年10月28日 (木)

AWS SDK for JavaでAmazon SQSを使う

前回、Amazon SQSの記事で、Perlから使う方法を紹介しましたが、今日はJavaから
使う方法を紹介したいと思います。

というのはフレクトでは、Web系のアプリケーション構築はJavaで作ることが多いからです。
Perlはサーバの運用・管理のツールとして使うケースが多いです。

なお、Amazon SQSの本ブログでの紹介は以下のページを参照してください。

http://blog.flect.co.jp/cto/2010/09/amazon-sqs-4938.html

■ AWS SDK for Java

JavaからAmazon Web Servicesを操作するには、Amazon純正のSDKである
「AWS SDK for Java」を使います。以下からダウンロードできます。

http://aws.amazon.com/sdkforjava/

他にもPHP、Ruby、.NETなどの純正SDKがあります。

■ 使うための準備

AWS SDK for Javaの現在のバージョンは1.0.14です。aws-java-sdk-1.0.14.jarというファイルが
ダウンロードできると思います。これをクラスパスに通しましょう。

また、CommonsのHTTPクライアントライブラリやCODECライブラリが必要になるので
それぞれ以下からダウンロードしてクラスパスに通しましょう。

http://hc.apache.org/httpclient-3.x/
http://commons.apache.org/codec/

これで、コードを書き始められます。

■ 最初にアクセスキー、秘密キーのセットアップ

最初にアクセスキーと秘密キーを指定して、AWSCredentialという認証情報を持つインタフェースを実装しているBasicAWSCredentialsクラスのインスタンスを作成します。
そして、認証情報を引数にしてAmazonSQSClientというSQSのクライアントクラスの
インスタンスを作成します。

ちなみに、この手順はAmazonS3Clientなどでも同じような手順になります。
AWSCredentialを実装しているクラスにはPropertiesCredentialというプロパティファイルに
キー情報を保持して、それを読み取る実装クラスもあります。

String accessKey = "xxxxx"; // アクセスキーの設定
String secretKey = "xxxxx"; // 秘密キーの設定
// SQSのクライアントを作成。
AmazonSQS sqs = new AmazonSQSClient(new BasicAWSCredentials(accessKey,secretKey));

■ エンドポイントURLでRegionの指定

アメリカ東海岸、西海岸、シンガポールなど、どこのSQSサーバを使うか指定します。

// アメリカ西海岸を指定する。
sqs.setEndpoint("sqs.us-west-1.amazonaws.com");

ちなみに各Regionの指定は以下のURLです。

・アメリカ東海岸(US-East):sqs.us-east-1.amazonaws.com
・アメリカ西海岸(US-West):sqs.us-west-1.amazonaws.com
・シンガポール(Asia Pacific):sqs.ap-southeast-1.amazonaws.com
・ヨーロッパ(EU):sqs.eu-west-1.amazonaws.com

■ キューを作成する

エンドポイントを作成したら、いよいよキューを作成しましょう。以下のようにさくせいする。
視認性の秒数は、あるクライアントがキューのメッセージをReceiveしたときに、ここで指定した
秒数分は他のクライアントからReceiveできない(見えなくなる)、というものです。デフォルトは
30秒です。キューのURLはこのあと、メッセージの受け渡しをするときに使います。

// キュー作成のリクエスト作成。第2引数は視認性の秒数。
CreateQueueRequest createQueueRequest = new CreateQueueRequest("FlectQueue", 30); // キューを作成する。 CreateQueueResult createQueueResult = sqs.createQueue(createQueueRequest); // キューのURLを取得。この後のリクエストで使います。 String queueUrl = createQueueResult.getQueueUrl();

■ メッセージをキューに送信する

以下のように、SendMessageRequestクラスでリクエスト用のインスタンスを設定し、先ほど作成したキューのURLを指定します。そして、メッセージ内容を setMessageBody で指定して、最初に作成した
AmazonSQSClientのインスタンス(sqs)からメッセージをキューに送信します。

SendMessageRequest sendMessageRequest = new SendMessageRequest();
// 作成したキューURLを指定する。
sendMessageRequest.setQueueUrl(queueUrl);
// メッセージ内容をリクエストにセットする。
sendMessageRequest.setMessageBody("Hello, World");
// キューにメッセージを入れる。メッセージ結果を取得するとメッセージIDを取得できます。

SendMessageResult sendMessageResult = sqs.sendMessage(sendMessageRequest);

System.out.println(sendMessageResult.getMessageId());

■ キューからメッセージを受信し、処理が終わったら削除する

キューに入っているメッセージは他のワーカープロセス等で処理するのが一般的だと思います。
メッセージを取得する側を書いてみます。途中まではメッセージ送信と同じですね。
受信側特有なのは receiveMessageRequest.setMaxNumberOfMessages の部分で、メッセージ取得数をセットできる部分です。リクエスト送信後はforループにあるように、最大で指定した数分のメッセージを取得し、その結果をハンドリングできます。

取得したメッセージからは MessageクラスのgetReceiptHandle()メソッドを使うことで
メッセージのReceiptHandleを取得できます。メッセージに対応する処理が終わったら、
このReceiptHandleを指定して、キューからメッセージを削除します。
メッセージを削除しないと、キュー作成時に指定した視認性の秒数を経過したら、他のクライアントから同じメッセージを取得できてしまうので、きちんと削除したほうがよいです。
(ただ、同じメッセージを取得してもシステムとして挙動がおかしくならないようにはしないといけません)

// リクエストクラスのインスタンスを作成。
ReceiveMessageRequest receiveMessageRequest = new ReceiveMessageRequest();
// キューのURLをセット。
receiveMessageRequest.setQueueUrl(queueUrl);
// 1回のリクエストで取得できるメッセージの最大数を指定。
receiveMessageRequest.setMaxNumberOfMessages(10);
// メッセージ取得。
ReceiveMessageResult receiveMessageResult = sqs.receiveMessage(receiveMessageRequest);

// getMessagesで複数のメッセージのリストが返ってきます。
for (Message message : receiveMessageResult.getMessages()) {
    // ReceiptHandleはメッセージの削除を行うために必要になるハンドルです。 
    System.out.println("ReceiptHandle : " + message.getReceiptHandle()); 
    System.out.println("MessageId : " + message.getMessageId());
    System.out.println("MessageBody : " + message.getBody());

    // ここで何かしらのメッセージに対する(重めの)処理をします。
    doSomething();

    // 処理が終わったらキューからメッセージを消します。
    DeleteMessageRequest deleteMessageRequest = new DeleteMessageRequest();
    // QueueのURLを設定します。
    deleteMessageRequest.setQueueUrl(queueUrl);
    // ReceiptHandleを設定します。
    deleteMessageRequest.setReceiptHandle(message.getReceiptHandle());
    // そして、メッセージの削除をします。
    sqs.deleteMessage(deleteMessageRequest);
}

■ with***メソッドを使ってコンパクトにキュー操作処理を呼び出す

ここまでの例はキュー作成、メッセージ送信、メッセージ受信、いずれもだいたい以下の流れで処理をしてました。

 (1) リクエストクラスのインスタンス作成(****Requestクラスをnewする)
 (2)  リクエストインスタンスにキューURLなどパラメータをセット(set***メソッド)
 (3) AmazonSQSClientインスタンスのcreateQueue, sendMessageなどのメソッドでリクエストインスタンスを指定し、実行

この流れを、リクエストクラスのwith****メソッドを使うことでコンパクトにできます。
以下にメッセージ送信を例に紹介します。

SendMessageResult sendMessageResult = sqs.sendMessage(
    new SendMessageRequest()
    .withQueueUrl(queueUrl)
    .withMessageBody("Hello World")
    );

少しコンパクトになった感じがしますね。

■ まとめ

AWS for Javaを使ってAmazon SQSを操作する方法を書きました。Amazon純正のSDKだけあってS3など他のサービスについても使い方に統一感があり、何かと使いやすいです。

このブログでPerl関連でサンプルを書いていたのですが、社員がJava好きが多いので、
S3、EBS、IAMなど他のサービスについても調査をしてなるべくJavaで使い方など
ブログに書いていきたいと思います。

■ 参考リンク

http://aws.amazon.com/articles/3586
http://docs.amazonwebservices.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/

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

採用情報

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

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

フレクト採用ページへ

会社紹介

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

2019年4月

  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