Java 開発 2.0: Amazon RDS で Play フレームワークを使用する

サービスとしてのリレーショナル・データ管理?それもありです

Amazon の RDS (Relational Database Service) は、データベースの保守作業を Amazon Web Services に任せることで、アプリケーションのデータ・ストレージを極めて簡単に増設、交換できるようにしています。今月は、著者の Andrew Glover が以前に作成した位置情報ベースのクラウド用モバイル・アプリケーションを再び取り上げ、当初使用していた NoSQL データストアを従来の RDBMS に交換します。Play フレームワークと AWS コンソールを使えば、ごく簡単に交換することができます。

Andrew Glover, Author and developer, Beacon50

Andrew GloverAndrew Glover は、ビヘイビア駆動開発、継続的インテグレーション、アジャイル・ソフトウェア開発に情熱を持つ開発者であるとともに、著者、講演者、起業家でもあります。また、easyb BDD (Behavior-Driven Development) フレームワークの創始者、そして『継続的インテグレーション入門 開発プロセスを自動化する47の作法』、『Groovy in Action』、『Java Testing Patterns』の 3 冊の本の共著者でもあります。詳細は彼のブログにアクセスするか、Twitter で彼をフォローしてください。



2011年 8月 26日

この連載について

Java 技術が初めて登場してから現在に至るまでに、Java 開発の様相は劇的に変化しました。成熟したオープンソースのフレームワーク、そしてサービスとして提供される信頼性の高いデプロイメント・インフラストラクチャーを利用できる (借りられる) おかげで、今では Java アプリケーションを短時間かつ低コストでアセンブルし、テスト、実行、保守することが可能になっています。この連載では Andrew Glover が、この新たな Java 開発パラダイムを可能にする多種多様な技術とツールを詳しく探ります。

この連載では数ヶ月前に、Amazon が Java アプリケーション開発用に提供している Elastic Beanstalk という PaaS (Platform-as-a-Service) を実際に使用しながら紹介しました。その記事で示したように、極めて柔軟な Beanstalk は、処理を行う上でほとんどあらゆるツールを組み合わせて使用することができます。そのため、Play を使用して迅速な開発を行うとともに、MongoHQ という別の PaaS で MongoDB インスタンスを管理することができました。この 2 つの PaaS インフラストラクチャーを組み合わせると、アプリケーションの保守のほとんどを行なってくれるため、素晴らしいクラウド用モバイル・アプリケーションの構築に専念できるというわけです。

MongoHQ PaaS は前述のプロジェクトでは極めて有効に機能しましたが、データを従来の RDBMS に保管するとしたら、どうでしょうか。結局のところ、ほとんどの Java 開発者はリレーショナル・データベースのコードを作成するほうが楽に感じるものです。また、多くの NoSQL データストアでは必然的に ACID を諦めることになりますが、すべてのプロジェクトにその余裕があるわけではありません。

DB2 pureScale

オンデマンドによるリレーショナル・データベースのスケーリングは、今に始まったことではありません。IBM の DB2 pureScale はさまざまな点で RDS と似ており、DB2 の分散したインスタンスを自動的にスケーリングできるとともに、信頼性の高いデータを受信することができます。pureScale は、無制限の容量、安定した可用性、そしてアプリケーションの透過性 (アプリケーションを変更する必要がないこと) により、データの急増に対処します。pureScale の詳細を学ぶには、「参考文献」を参照してださい。

今月は、Amazon Web Services ファミリーに加わった素晴らしい多用途のサービス、Amazon Relational Database Service (RDS) の導入方法を説明します。Amazon RDS を使用するのは、MongoHQ でホストされた MongoDB インスタンスを実行するのと同じくらいに簡単です。そのリレーショナル性を管理するのはまったく難しいことではありませんが、スケーリングに関してはいくつかの興味深い問題が出てくるはずです。けれども、前もってスキーマを定義しておけば、後は順調に進みます。

Amazon RDS

Amazon RDS (Relational Database Service) は、オンデマンドでスケーリング可能なクラウド・ベースの MySQL インスタンスを提供するアプリケーション開発用の PaaS です。RDS が単にクラウド内で稼動する MySQL のインスタンスでしかないのであれば、私はこの記事を書いてはいません。2009年に、MySQL を実行する Amazon EC2 イメージを利用する方法についての記事をすでに書いているからです (「参考文献」を参照)。

リレーショナルのスケーリング

NoSQL への移行が勢いを得た主な理由の 1 つは、NoSQL にはスケーラビリティーがあることです。そもそも NoSQL が台頭することになった 1 つの原因として、従来のリレーショナル・システムでは、シャーディングなどの技術を使用した取り組みが行われているとは言え、ノードをまたがる水平スケーリングを行うのは簡単ではないことが挙げられます。リレーショナル・システムではノードにデータを分散することができないわけではありませんが、ノードにデータを分散すると、複雑さもコストも増してくるということです。RDS はリレーショナル・データベース・システムであるため、RDS におけるスケーリングでは、データベースのセクションをコピーするのではなく、データベース全体をノード間でコピーしなければなりません。そのため、データの重複が問題になる可能性があります (NoSQL データストアおよび RDBMS シャーディングについての詳細は、「参考文献」を参照してください)。

RDS に一見の価値を与えているのは、これが Amazon によって管理、運用されている PaaS であり、Elastic Beanstalk とほとんど同じサービスおよび柔軟性を提供するという点です。バックアップ、複製、さらにはパッチまでもが Amazon によって提供されます。しかも、RDS は完全にスケーラブルです。ほんの数回クリックするだけで、アプリケーションのストレージ容量を増やすことができます。Amazon では、アベイラビリティー・ゾーン間で RDS を複製するオプションも提供しています。つまり、アベイラビリティー・ゾーンが機能停止した場合や、ある時間帯にゾーンで保守作業が予定されている場合でも、引き続きデータを提供することができるということです。さらに、データベースの読み取り専用インスタンスをプロビジョニングして、大容量のアプリケーションまたはピーク期間の読み取り速度を向上させることもできます。

MySQL と連動するように作られているアプリケーションは、そのまますぐに RDS を利用できるので、データベースがクラウド内にある限り、アプリケーションを変更する必要はありません。また RDS では、AWS の他のサービスと同じように従量課金制モデルを採用しているため、RDS を利用すれば、ハードウェアやライセンスに先行投資することなく、使用した容量、ストレージ、そして帯域幅の分だけ料金を支払えばよいのです。


RDS のセットアップと構成

AWS では、コマンドラインまたは AWS 管理コンソールを使って各種のサービスをプロビジョニングできるようになっています。AWS 管理コンソールは、RDS のさまざまな側面について選択可能なオプションを示してくれることから、私はどちらかというと、コマンドラインよりもコンソールを使用しています。そこで、この手順では AWS 管理コンソールのコンソールで「RDS」タブを選択し、「Launch Instance (インスタンスの起動)」ボタンをクリックするところから作業を開始します。

RDS を使用するにはサインアップしてください

Amazon Web Services でのあらゆるサービスの常に漏れず、Amazon RDS を使用するには、アカウントを作成する必要があります。アカウントを取得すれば、Amazon RDS にサインアップすることができます。ただし、Amazon のサービスはいずれも従量課金制であることをお忘れなく!

画面には、MySQL データベース・インスタンスの詳細を設定するためのダイアログが表示されます。このダイアログで、例えばマシンのサイズ、MySQL のバージョン、データベースのインスタンスに割り当てるストレージの量などを指定することができます。注目する点として、AWS にはデータベースを複数のアベイラビリティー・ゾーンにデプロイするというオプションがあります。その場合には必然的にクラスターが作成されるため、ある特定のアベイラビリティー・ゾーンが機能停止したとしても、他のゾーンがそのゾーンを確実にカバーします。

図 1 に示されているように、インスタンスを設定するには、データベースのスキーマ名、管理ユーザー名、パスワードを指定する必要があります。

図 1. RDS インスタンスのセットアップ
MySQL データベース・インスタンスの構成

Continue (続ける)」をクリックすると、データベースの概要を構成する別のダイアログが表示されます。このダイアログでは、データベースの JDBC URL の一部として使用される名前を構成するだけでなく、MySQL がリッスンするポートを変更して、データベースを置くアベイラビリティー・ゾーンを選択することもできます (図 2 を参照)。

図 2. RDS インスタンスの構成
データベースのアベイラビリティー・ゾーンを選択する画面

次に表示されるのは、AWS にデータをバックアップさせるための設定と、保守のスケジュールに関する設定ついての管理オプションです (図 3 を参照)。

図 3. RDS の管理オプション
AWS コンソールによるデータベース管理の起動および構成

Continue (続ける)」をクリックして構成内容を確認した後、RDS インスタンスを起動します。インスタンスが起動するまでには数分かかることもあるので、今のうちに、コーヒーでひと息つくか、Twitter で最新の情報をチェックしてください。RDS がいったん起動すれば、後は素早く事が運びます。

RDS セキュリティー

インスタンスが起動された後、お好みの SQL 管理ツールでインスタンスにアクセスする前に、もう 1 つ行わなければならない作業があります。AWS を操作した経験があるとしたら意外なことではないはずですが、デフォルトではある程度ロックが掛かっているため、明示的にインスタンスへのアクセスを許可しなければなりません。

RDS のセキュリティー制約はかなり強力であり、RDS と通信するための IP、または IP の範囲を指定できるようになっています。しかし、この記事では簡単のため、どの IP でも私のインスタンスと通信できるようにしたいと思います。そのためには、RDS の「DB Security Group (DB セキュリティー・グループ)」ペインで、CIDR/IP 制約を編集して 0.0.0.0/0 にしてください。これは基本的に、すべての IP が許可されることを意味します。このステップを図 4 に示します。

図 4. RDS セキュリティーの設定
AWS RDS の「DB Security Group (DB セキュリティー・グループ)」のスクリーン・ショット

このステップを完了したら、RDS のインスタンスをリブートします (AWS Management Console のダッシュボードでインスタンスを右クリックすると、リブートするためのオプションが表示されます)。

実行中の RDS インスタンスを選択すると、「Description (説明)」ペイン (図 5 を参照) にいくつかの重要な詳細情報が表示されます。そのなかでも、今ここで最も関係してくる情報は、エンドポイントです。この URL を使用して、MySQL インスタンスに接続することになります。

図 5. RDS ダッシュボード
AWS Management Console の RDS ダッシュボードのスクリーン・ショット

これで、お好みのデータベース管理ツール (または、お望みであればコマンドライン) を使用して、RDS インスタンスにアクセスできるようになりました。私がこれから使用するのは、ほとんどの GUI 指向のツールと同じくテーブルとデータを表示するための巧みなインターフェースを備え、さらにクエリー・コンソールを提供している Sequel Pro です。データベース・インスタンスに接続するためには、データベースのユーザー名、パスワード、そしてエンドポイント URL を知っている必要があります。


RDBMS 方式の Magnus

Amazon の Elastic Beanstalk を紹介した私の記事 (「参考文献」を参照) を読んでいれば、その記事のために私が作成した Magnus というモバイル用クラウド・アプリケーションについてはご存知のことでしょう。Magnus 用のコレクションとして、私は MongoDB に AccountLocation の 2 つを作成しました。Account という名前の1 つのコレクションを作成して、そこに、それぞれに Location 文書を埋め込んだ文書を含めることもできましたが、2 つのコレクションを使用することによって、このアプリケーションのシナリオで世界中のモバイル機器から送られてくるはずのアカウントの位置情報を永続化することができました。

Amazon RDS のデモンストレーション用にも同じ関係をモデル化しますが、今回は、昔ながらの方法でモデル化します。Magnus は、世界中にまたがる位置情報が頻繁に更新されるアプリケーションです。このようなアプリケーションの場合、特に RDS が多数のアベイラビリティー・ゾーンでクラスタリングできることを考えると、RDS に切り替えることにメリットがあるはずです。また、RDBMS の領域には、例えばデータを論理パーティションに分割するシャーディングなどの手法もあります。したがって、地理的位置を基準にアカウントおよび位置情報をシャーディングすることもできます。ただし、クラスタリング、複製、シャーディングにはいずれも利点と欠点があるので、個々のストラテジーに着手する前に、それぞれの利点および欠点を十分に考慮しておかなければなりません。

Magnus で SQL を使えるようにするには、まず初めに 2 つのリレーショナル・テーブルを定義する必要があります。これらのテーブルには、(ご想像のとおり) それぞれ accountlocation という名前を付けます。リスト 1 に、account テーブルの定義を示します。

リスト 1. account テーブル
CREATE TABLE `account` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(30) DEFAULT NULL,
  PRIMARY KEY (`id`)
)

リスト 2 に記載する location テーブルには、account テーブルへの外部キーを指定します。このようにすることで、account テーブルとその各種 location テーブルとの間に 1 対多の関係をセットアップします。

リスト 2. location テーブル
CREATE TABLE `location` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `account_id` int(11) DEFAULT NULL,
  `latitude` double DEFAULT NULL,
  `longitude` double DEFAULT NULL,
  `date_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
  `name` varchar(50) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `account_id` (`account_id`),
  FOREIGN KEY (`account_id`) REFERENCES `account` (`id`)
)

テーブルを定義した後は、これらのテーブルを RDS インスタンス内に作成します。RDS インスタンス内にテーブルを作成する方法は、ローカル・マシンで実行中の MySQL インスタンスにテーブルを作成する場合と同じです。単純に、ターミナル・ウィンドウを開くか、お好みの GUI で RDS エンドポイントを指定するかして、テーブルを作成してください。これは極めて簡単な作業です。


Play の構成

Play Web アプリケーション・フレームワーク (「参考文献」を参照) は、Amazon RDS でも、Elastic Beanstalk での場合と同じように機能するため、今回もこのフレームワークを使用してアプリケーションを開発します。Play では各種のデータストアをごく簡単に切り替えることができます。しかも、このフレームワークには最初から JPA サポートが組み込まれています。MongoHQ 実装から Amazon RDS を使用する実装に切り替えるには、モデルに多少の変更を加えるだけの話です。まず、Play には JPA サポートが組み込まれているため、Magnus の application.conf ファイルを変更して、代わりに RDS インスタンスを参照させるようにします (リスト 3 を参照)。

リスト 3. location テーブル
db.url=jdbc:mysql://magnus.cp3pl5vineyp.us-east-1.rds.amazonaws.com/magnus_locations
db.driver=com.mysql.jdbc.Driver
db.user=admin
db.pass=g3tf0kl

上記のリストに何も特別な処理はありません。リスト 3 は 100 パーセント JDBC です!

関係をモデル化する

あらゆる RDBMS ORM ライブラリーと同様に、これから最上位レベルの Java オブジェクトを使って、テーブルを 1 対 1 の関係でモデル化します。このアプリケーションで最上位レベルの Java オブジェクトに該当するのは、1 つの Account 型と 1 つの Location 型です。LocationAccount に関係づけられることになります。

Play の Model 型を継承すると、いくつかのおまけが付いてきます。その 1 つは、ファインダー風のメソッドと、save および delete という標準的な CRUD メソッドを手に入れられることです。

Account クラスは 2 つの JPA アノテーションを使用します。そのうちの 1 つ、Table アノテーション (リスト 4 を参照) には、名前を (小文字に) 変更した account テーブルを指定する必要があります。

リスト 4. Account 型
package models;

import play.db.jpa.Model;
import javax.persistence.Entity;
import javax.persistence.Table;

@Entity
@Table(name = "account") //required otherwise table is Account
public class Account extends Model {
 public String name;
}

リスト 5 に示す Location POJO は、多少複雑です。このオブジェクトにはさらに 2 つのアノテーションを追加して、LocationAccount との間に多対 1 の関係を作成しなければなりません。

リスト 5. JPA で定義された Location クラス
package models;

import play.db.jpa.Model;
import javax.persistence.*;
import java.math.BigDecimal;
import java.sql.Timestamp;

@Entity
@Table(name = "location")
public class Location extends Model {

 public BigDecimal latitude;
 public BigDecimal longitude;
 public String name;
 @Column(name = "date_time")
 public Timestamp timestamp;

 @ManyToOne
 @JoinColumn(name="account_id", nullable = false)
 public Account account;

}

最後に、リスト 6 に示すように Application コントローラーの saveLocation メソッドを更新します (前の Magnus 実装では、/location/ に対するすべての HTTP PUT をこのメソッドにルーティングしたことを思い出してください)。saveLocation は単に、新しい Location オブジェクトを作成し (したがって、それに対応するレコードも作成します)、この Location インスタンスを既存の Account に関連付けるだけに過ぎません。この関連付けをするには、先ほど Play の Model オブジェクトを継承したので、重宝な findById メソッドを使用することもできます。

リスト 6. RDS での位置を基準とした更新
public static void saveLocation(String id, JsonObject body) throws Exception {
 String eventname = body.getAsJsonPrimitive("name").getAsString();
 double latitude = body.getAsJsonPrimitive("latitude").getAsDouble();
 double longitude = body.getAsJsonPrimitive("longitude").getAsDouble();

 Location loc = new Location();
 loc.longitude = new BigDecimal(longitude);
 loc.latitude = new BigDecimal(latitude);
 loc.name = eventname;
 loc.account = Account.findById(new Long(id));

 loc.save();

 renderJSON(getSuccessMessage());
}

RESTClient を使ったテスト

更新後の位置情報サービスが機能するかどうかをテストするには、RESTClient を使用することができます。このテストでは、以前 Magnus で行ったように、いくつかの JSON 文書を作成して送信します。

図 6. RESTClient を使ったテスト
RESTClient インターフェースのスクリーン・ショット

メソッドが新しい Location レコードを正常に永続化すると、成功を意味する JSON レスポンスが送り返されてきます。私が使っている便利で素晴らしい GUI では RDBMS 内のデータを表示できるので、location テーブルを確認してみます。すると、どうなっているかわかりますか? RDS によって新しい Magnus レコードがクラウドに保管されています!

図 7. これがクラウドに保管された Magnus レコードです!
AWS Management Console に表示されたクラウド内の Magnus

まとめ

PaaS は、Web アプリケーションの迅速な開発およびデプロイを目指すソフトウェア開発チームの良き友です。この記事では、リレーショナル・データベース (この記事では MySQL を使いましたが、RDS は Oracle Database もサポートします) をクラウドに配置する PaaS ソリューション、Amazon RDS を紹介しました。Amazon RDS はプロビジョニングするのが極めて簡単で、おそらく皆さんがこれまで長年にわたって構築してきた各種の RDBMS システムとまったく同じように機能します。重要な違いは、Amazon が保守を引き受けてくれることです。

参考文献

学ぶために

  • 連載「Java 開発 2.0」: この dW の連載では Java 開発の様相を塗り替える技術を詳しく探っています。これまで、Amazon Elastic Beanstalk (2011年2月)、MongoDB (2010年9月)、Amazon EC2 (2009年10月)、NoSQL (2010年5月)、Hibernate Shards (2010年8月) などの話題を取り上げてきました。
  • ナレッジ・パス「Using NoSQL and analyzing big data」(developerWorks、2011年5月): NoSQL、ビッグ・データ、そしてデータ・マイニングについて学ぶための dW リソースが揃っています。
  • ナレッジ・パス「Cloud computing: Fundamentals」(2011年3月): クラウド・コンピューティングの概念、および IaaS、PaaS、SaaS という 3 つのサービス・モデルについて解説しています。
  • Java Technology bookstore で、この記事で取り上げた技術やその他の技術に関する本を探してください。
  • developerWorks Java technology ゾーン: Java プログラミングのあらゆる側面を網羅した記事が豊富に用意されています。

製品や技術を入手するために

  • Amazon Relational Database Service: Amazon Web Services ファミリーに含まれるこの Java Web サービスは、リレーショナル・データベースをクラウドでスケーリングします。
  • Play フレームワーク: Web 開発者によって構築された Java フレームワークを自称する Play は、開発者の生産性に重点を置き、RESTful なアーキテクチャーをターゲットとしています。
  • IBM 製品の評価版をダウンロードするか、あるいは IBM SOA Sandbox のオンライン試用版で、DB2、Lotus、Rational、Tivoli、および WebSphere などが提供するアプリケーション開発ツールやミドルウェア製品を試してみてください。

議論するために

  • developerWorks コミュニティーに参加してください。ここでは他の developerWorks ユーザーとのつながりを持てる他、開発者が主導するブログ、フォーラム、グループ、ウィキを調べることができます。

コメント

developerWorks: サイン・イン

必須フィールドは(*)で示されます。


IBM ID が必要ですか?
IBM IDをお忘れですか?


パスワードをお忘れですか?
パスワードの変更

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


お客様が developerWorks に初めてサインインすると、お客様のプロフィールが作成されます。会社名を非表示とする選択を行わない限り、プロフィール内の情報(名前、国/地域や会社名)は公開され、投稿するコンテンツと一緒に表示されますが、いつでもこれらの情報を更新できます。

送信されたすべての情報は安全です。

ディスプレイ・ネームを選択してください



developerWorks に初めてサインインするとプロフィールが作成されますので、その際にディスプレイ・ネームを選択する必要があります。ディスプレイ・ネームは、お客様が developerWorks に投稿するコンテンツと一緒に表示されます。

ディスプレイ・ネームは、3文字から31文字の範囲で指定し、かつ developerWorks コミュニティーでユニークである必要があります。また、プライバシー上の理由でお客様の電子メール・アドレスは使用しないでください。

必須フィールドは(*)で示されます。

3文字から31文字の範囲で指定し

「送信する」をクリックすることにより、お客様は developerWorks のご使用条件に同意したことになります。 ご使用条件を読む

 


送信されたすべての情報は安全です。


static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=60
Zone=Java technology, Cloud computing
ArticleID=753193
ArticleTitle=Java 開発 2.0: Amazon RDS で Play フレームワークを使用する
publish-date=08262011