2010年11月27日土曜日

アプリケーションアーキテクチャとデータベース

引き続き右のクラウドアプリケーションアーキテクチャについて考えています。

JJUG CCC 2010 Fallでは、CQRSアーキテクチャパターンの動きを下の図を用いて説明しました。
これを実現する場合、Commandによる更新系とQueryによる問合せ系で、物理的なデータベースを分けるのがよいわけですが、さらにデータベースのシステムも性質に合わせたものを適材適所で選択するとより良い結果が得られるはずです。

問合せ系のデータベースとしては、ここまでの議論からカラム指向データベース/HBaseが候補となっています。

Commandとして投入されたEventはコミットログ的な実現方式で、データベースに格納します。このデータをここではEventログと呼ぶことにします。Eventログを格納するデータベースは、通常オペレーションではappend-onlyなので、分散ISAM的なシンプルなデータベースが向いています。shared nothingなのでshardingでスケーラビリティを確保するのも容易です。このあたりの性質を軸にデータベースを選択することになります。append-only&shardingに強い、更新が高速で信頼性の高い分散KVSが候補となりますが、まだ見つけていないので保留。現時点ではRDBMSを(ISAM的に)使うのがよいかもしれません。

問題は、Eventログの内容をカラム指向データベースに反映するところです。
カラム指向データベースは、問合せに強い反面、更新に弱い性質があります。このため、カラム指向データベースを通常のトランザクション向けデータベースとして使うのは、あまり得策ではありません。

本アーキテクチャでは、このギャップをドメインサービスにおいて、トランザクションデータの格納にインメモリデータベースを使うことで埋めることが眼目の一つになっています。インメモリデータベースはVoltDBが候補になっています。
アプリケーション実行中のトランザクションは、インメモリデータベースに格納・管理されます。カラム指向データベースはあくまでもインメモリデータベースのバックアップなので、更新に多少の時間がかかっても問題ありません。
また、データの永続性はEventログのデータベースによって担保されるため、バックアップデータベースであるカラム指向データベースへのデータ更新は、インメモリデータベースへの更新とは非同期に、バックグラウンドでゆっくり行っても大丈夫というわけです。

以上のように、分散KVS(またはRDBMS)、インメモリデータベース、カラム指向データベースを適材適所で組合わせてアプリケーションを構築すると面白い結果が得られそうです。
まだまだ机上の議論ですが、この方向で考察を深めていきたいと考えています。

2010年11月26日金曜日

データベースの選択

カラム指向データベースにHBaseを使うと、Hadoopとの連携がスムーズになるので、バランスがよさそうというお話をしました。

こうなると、インメモリデータベースも具体的に考えてみたくなります。

当初は、SQLiteのインメモリデータベースモードを使って、自分でメモリクラスタを組むようなことを考えていたのですが、色々調べてみるとどうもVoltDBがよさそうに思えてきました。

VoltDBはRDBMSなので、SQLの豊富なデータ操作機能を用いることができます。
いわゆるKVSを使うと、アプリケーション側で相当の作り込みが必要なので、この点でRDBMSは安心感があります。

VoltDBは、自動的にメモリクラスタを組んでくれるみたいなので、この点でもアプリケーションは何もしなくて済みそうです。
メモリクラスタによってスケーラビリティを高めるとともに、信頼性を向上させることができます。

VoltDBではJavaを使ったストアドプロシジャとしてプログラムを書く必要があるので、この点がちょっとクセのあるところです。
たとえば、本アーキテクチャの場合、ドメインサービスだけでなく、アプリケーションサービスもストアドプロシジャとして実現するような実現方式も検討が必要になります。
この点に問題がなければ、かなり有力な選択肢ではないかと思います。

インメモリデータベースの弱点は、メモリクラスタが完全にダウンした場合の永続性の確保と、大規模データがメモリに載り切らないリスクです。
本アーキテクチャでは、Eventログを用いて永続性は確保できているので、メモリにデータが載り切る場合には、Eventログの分散KVS(または普通のRDBMS)とVoltDBだけでシステムが組むこともできそうです。(AWSの場合、メモリモデルとして7.5GB, 15GB, 34.2GB, 68.4GBが用意されており、一般的なアプリケーションではメモリのみで運用することが可能です。すでにそういう時代に入っています。)
ただし、メモリクラスタ再起動時にEventログから最新の状態を復元するのに時間がかかりそうなので、何らかのチェックポイントをどこかに保存して置く必要があります。
そうなると、結局のところバックアップデータベースとしてHBaseを併用するのがバランスがよさそうです。

図の左側にあるマスターデータはローディングが早ければ何でもよいので、HBaseに相乗りで十分でしょう。

以上の考察から、今の所:

  • Eventログ用DB:append-only&shardingで高速書き込みできる分散KVSの何か
  • ドメインサービスのインメモリデータベース:VoltDB
  • バックアップデータベース&Hadoop:HBase
  • マスターデータベース:HBase(に相乗り)
というのが面白そうと考えています。

2010年11月25日木曜日

Hadoopの置き場所

土曜日に書いたアーキテクチャは、Hadoop座談会で得られたインスピレーションによるものでしたが、肝心のHadoopの置き場所を考えるのを忘れていました。
そこで、考えてみたのが以下の図です。


アーキテクチャ的には、MapReduceやその実装としてのHadoopだけでなく、より汎用的な概念の導入が有効ではないかということでBackground Computingとしています。
さらに細かく考えていくと、Background ComputingもBatchとRealtime(Streaming)に分けることができそうですが、これはいずれ。

ボクは、クラウドアプリケーションとは、非同期に発生するイベントを連続して受け取りながら、イベント受信をうけて内部状態を刻一刻と遷移させていくオブジェクトと考えています。右の図はこのあたりをJJUG CCC 2010 Fallでお話した時に使ったものです。
この中で、インデクサとしているものが、上の図のBackground Computingに相当します。
クラウドアプリケーション自身はイベント駆動で動作しますが、その応答性能や結果精度を向上させるために、必要な情報をバックグラウンドで常に作り続けているのも、クラウドアプリケーションのもうひとつの側面になります。
この部分の実現機構として、MapReduce/Hadoopが重要な選択肢というわけですね。

Hadoopを組み合わせるということで具体的に考えてみると、HBaseはカラム指向データベースということに思い至りました。アーキテクチャ素案では、ドメインサービスのメインデータベースはインメモリデータベースで、このバックアップとしてカラム指向データベースを併用しています。このバックアップデータベースをHBaseとすることで、Hadoopとの連携をシームレスに行う事ができるようになります。

Background Computingの結果は、バックアップデータベースに直接戻すケースと、イベントとして通常のデータ更新ルートに載せるケースの両方が必要でしょう。
そのあたりを図に追加しています。

2010年11月20日土曜日

クラウドアプリケーションのアーキテクチャ素案

きのうはHadoop座談会(第3回)。佐藤先生と萩原さんのお話を聞くことができました。
並行・並列・分散技術。RDBMS JoinからDryad。旬のテーマで参考になる点が多々ありました。
これに加えて、懇親会で萩原さんからお聞きしたカラム指向データベースのお話が刺激的。クラウドアプリケーション・アーキテクチャのインスピレーションが浮かんだので、図にまとめてみました。


CQRS、Event Sourceのアーキテクチャの上で:

  • 各種データベースの選択とアーキテクチャ責務分割
  • プレゼンテーション、アプリケーション、ドメインの各サービスのアーキテクチャ責務分割
  • 可用性の担保
  • スケーラビリティの担保
といったものを織り込んでいます。
Domain Serviceのクラスタを構築してin memory databaseでワークデータの管理をするのが面白いかなと思っているのですが、Domain Service初期化時にすべてのデータをメモリにローディングするのは現実的ではないので、バックエンドのデータベースが必要となります。ここにカラム指向データベースがぴったりはまるのではないか、というのがインスピレーション。RDBMSでもよいところですが、スケーラビリティを高めるにはカラム指向データベースという選択が有効と考えられます。
エージェント,というとやや大げさですが、ストアドプロシジャとかクロージャとか、そういった技術でデータの近くで処理を行って結果を返す機能が必要になるのは明らかなので、そのあたりもアーキテクチャに取り込みたいところ。ここは、Domain Service界隈で実現できるのではないかと考えています。
他にも色々と話題があるので、この図をもとにブログで実現方式を整理していこうと思っています。