Bigtableをお手軽に使える凄さ
(この記事は、日経BP社「ITpro」向けに書いたものを再掲しています)
GAE/Jのもうひとつの革新的な点は、「Googleインフラの圧倒的なスケーラビリティ・高信頼性をお手軽に利用できる」という点です。例えばGAE/Jでは、データを保存・検索する手段として一般的なRDBは利用できない代わりに、Google独自のデータストア「Bigtable」を利用します。
Bigtableについての詳細はここでは省略しますが、従来型のRDBとは異なる「key-value型」の巨大分散データストアであり、Googleの検索サービスの桁外れのスケーラビリティと可用性を実現している中核技術のひとつです。リレーショナルモデルではないため、例えばテーブル間の結合や全文検索といった(RDB感覚では)ごくあたりまえの機能も対応できないなど、いろいろと制限やクセがあり、あらゆる用途に適用可能なわけではありません。しかしそれと引き替えに、Google検索と同等のほぼ無限のスケーラビリティと高い可用性を手に入れることができます。実際、Googleの社員が個人で始めたSNSサービス「orkut」がブラジルを中心に全世界で急成長した際にも、同サービスがBigTable上に構築されていたため、当初のアーキテクチャをそのまま使い続けることができたと言われています。
Bigtableについては、以下の書籍に詳しいです。
GAE/Jでは、Java EE標準のJDO(Java Data Objects)APIに基づいてコードを記述することで、このBigtableに簡単にアクセスできます。例として、ご都合.comにおける「カレンダーの新規作成」のコード例を紹介しましょう。ユーザーが作成した個々のカレンダー情報は、GtgCalendarクラスというEntityクラスに保持されています。
@PersistenceCapable(identityType = IdentityType.APPLICATION) public class GtgCalendar { @PrimaryKey @Persistent(valueStrategy = IdGeneratorStrategy.IDENTITY) @Extension(vendorName="datanucleus", key="gae.encoded-pk", value="true") private String key; @Persistent private String uid; @Persistent private String title; @Persistent private String comment; ...<以下、そのほかのフィールドやgetter/setterは省略>
このように、POJOクラスに「@Persistent」や「@PrimaryKey」といったアノテーションを記述することで、同クラスの内容をBigTableに保存可能になります。なお、BigTableでは事前にDBスキーマを定義しておく必要はなく、スキーマの変更も随時可能です。
このGtgCalendarに納められたカレンダー情報を保存するコードは、以下のように記述します(いずれもご都合.comで実際に動作しているコードです)。
// GtgCalendar「gc」を保存 PersistenceManager pm = pmf.getPersistenceManager(); try { pm.makePersistent(gc); } finally { pm.close(); }
このように、GtgCalenderをPersistenceManagerのmakePersistenceメソッドの引数として渡すだけで、その内容がBigtableに格納されます。ちょうどHibernateやRuby on RailsにおいてオブジェクトをDB保存する場合と同じ感覚で、ものの数行で記述できます。
一方、BigTableに保存されたデータを検索して取得するには、JDOで規定されたクエリ言語「JDOQL」を用いて、SQLライクなクエリを記述します。
// クエリを作成 PersistenceManager pm = pmf.getPersistenceManager(); Query query = pm.newQuery(GtgCalendar.class); query.setFilter("token == tokenParam"); query.declareParameters("String tokenParam"); // クエリを実行 Listresults; GtgCalendar gc = null; try { results = (List )query.execute(token); } finally { query.closeAll(); pm.close(); }
ここでは、GtgCalendarのtokenフィールドをキーにして、同オブジェクトを検索しています。これもきわめて容易に記述できます。このように、JDOによるBigtableプログラミングはたいへん容易で、JDOとBigTableのいずれも初体験の筆者でも1日程度でやりたいことをひととおり実装できました。
もちろん、Bigtableの「クセ」はときにたいへんやっかいな問題となり、用途によってはまったく使えないケースも少なくないはずです。しかしBigtableで対応できる用途ならば、サービスの規模拡大にともなうスケーラビリティや可用性の心配はほぼなくなります。例えば、万が一に「ご都合.com」のようなプチWebサイトが全世界的な人気を獲得し、数1000万件のカレンダーを抱える巨大サイトに成長したとしても、現在のコードをあまり変更せずにサービス品質を維持できるはずです(負荷テストで検証したわけではありませんが……)。つまり、大規模Webサイトへの成長過程でこれまで避けられなかった「データベースのスケールアップ/スケールアウト」、「クラスタ構築による負荷分散と高可用性の実現」のための巨額の追加投資が一切不要となります。これは既存のデータベースベンダーやサーバベンダー、大手SIerにとってはもっとも“うまみ”の大きなエリアであり、彼らにとっては地殻変動レベルの脅威ではないでしょうか。