月曜日, 7月 02, 2012

KVS上でアプリを動作させるために必要なたった2つのこと このエントリーを含むはてなブックマーク

先の記事で、ReflexWorksにおけるデータ操作の方法について触れ、ツリー構造の仮想フォルダ管理とREST APIによるデータアクセスについて説明した。ここでは、もう少し掘り下げて、KVS上でアプリを動かすための条件とは何なのかについて考えてみたい。(たった2つのことといいながら長文失礼します)

SQL vs NoSQL: Battle of the Backends

タイムリーにも、Google IO でSQL vs NoSQL: Battle of the Backendsというセッションがあったようだ。ここでは、SQL(MySQL)とNoSQK(Datastore)を、Queries、Transactions、Consistency、Scalability、Management、Schemaの6つの項目について比較していて、前半の3つについてはSQLが、後半の3つについてはNoSQLが優れているという結果になっている。最後は両者同数でどっちもどっちだね、みたいな話になっているが、セリングトークも含まれるのでこれは真に受けて欲しくないとにかく、これまで主張してきた通り、トランザクションが増えるとRDBがボトルネックになり、オンライン処理ではそのうち限界になってくるはずだ。
 また肝心のパフォーマンスについては、「基幹系システムでCloud SQLは使えるか試してみた」を見てもわかるように、Datastoreとはまだ相当の差があるようだ。

とはいえ、丸山先生もおっしゃっているように、GAEでもMySQLが使えるようになったことは、まあ、それはそれで結構なことだとは思う。(ということでお茶を濁す)

アプリにKVSを意識させないことが大事

さて、今WebアプリといえばHTML5などのリッチコンテンツが主流である。クライアント上のネイティブアプリのように小気味好く動作することが求められている。またスマートデバイスではオフラインや非同期更新などもある。もはや、JSPやJSF、あるいはPHPでHTMLを動的に作るといった古いアーキテクチャーは通用しない。エンジニアは利用者に最大限のエクスペリエンスを与えようと頑張っており、UI/UXに多くの時間と労力をかけている。可能なかぎり画面だけに集中したいと思っているはずだ。なので、JavaScriptを中心としたフレームワークのムーブメントが今起きていると思う。

このような要求にもReflexWorksであれば対応できる。ReflexWorksは、疎結合を基本としているためクライアント開発者がUI/UXに専念できるように、なるべくサーバ開発を意識させないようにしている。クライアントシンプルなREST APIでサービスを呼び出すことだけ考えればよく、結果もJSON/XMLで取得できる。

KVSで業務アプリを動かす条件とは

冒頭で、GAEではDatastoreはよいがCloudSQLはビミョーであるといった。
一方、AWSのRDSやSQL Azureはまずまずのようだが、実は、Amazon DynamoDBや、Azure Storage Service(KVSの方)にもビミョーなところがある。

一つ目はトランザクション。
GAEではEG(エンティティグループ)のトランザクションが扱える。Azure Storage Serviceでも、同一テーブル、Partitionkeyのデータはトランザクション処理可能である。しかし、DynamoDBではトランザクションを扱えない。(ドキュメントによるとatomic counter程度はできそうだが・・)



http://www.slideshare.net/kentamagawa/amazon-dynamodb-11808513
クラウドのエンタープライズ利用を考えた場合、数msで返せるとか、数万qpsとかいっても単体のスループットであれば実はそれほど重要ではない。ブラウザ表示で数msと数百msの違いは感じられないので、単純にKVSパフォーマンス比較してもあまり意味はない。逆にどんなに高速でもトランザクション非サポートは痛い。トランザクション機能がないと結局は参照系など用途は限定されることになるため、単体性能は悪くてもノードを増やすことでリニアに性能向上できることの方がはるかに重要だ。たとえ数百msのレスポンスで数十tpsになったとしてもトランザクション機能とスケーラビリティは必須である

2つ目はセカンダリインデックス。
実はKVSであっても単純なkeyとvalueだけでなく高度な検索ができるようなものもある。例えば、GAEのDatastoreには、データがソートされて格納されている。そしてRANGE検索ができるため前方一致で検索できる。これはRDB(2次元)とKVS(1次元)の間の1.5次元の性質をもつというのだそうだ。(このあたりについては、kazunoriさんの記事:BigTableと分散KVS がとても参考になる)
キー検索以外にもプロパティ検索も欲しくなる。DynamoDBやAzure Storage Serviceでは、プロパティ検索は可能だが、GAEのproperty indexのような、Built-in indexが存在しないためプロパティ検索は全スキャンになってしまうようだ。これでは大量のデータ検索には使えない。




ReflexWorksにおける基本設計と検索について

元へ。クライアント開発では単なるJSON呼び出しなので、それほど苦労しないことは理解いただけたと思うが、サーバ側ではそれなりのサービスを準備するのが結構大変だと思われるかもしれない。だが、実はそんなことはない。以下に示すように、ReflexWorksはドキュメント指向でありORMは不要であり設計も単純明快だ。



ReflexWorksにおける設計の基本となるのはエンティティである。エンティティとは、簡単にいえば、一単位として扱われるデータのまとまりのこと。難しくいえば、貧血症をおこしたオブジェクトのこと(笑)。POJOでもJSONの連想配列でも何でもいい。とにかく、クラスやプロトタイプに複数の項目がプロパティとして付いているものをエンティティと呼んでいる。ただし、CSVのようにデータを列挙したものではなく、項目と値がペアになっておりまた親子関係も表現できる。

ReflexWorksでは、このエンティティにユニークなアドレス(URL)をつけることで、データ全体を階層管理している。そして、そのアドレスに対してREST APIで操作する。



BDBはセカンダリインデックスが使えるという(1.5次元の)KVSである。このセカンダリインデックスにより、様々なプロパティ検索やソートなどを高速に実行できる。

例) GET /d/{selfid}?{name}{=|.eq.|.lt.|.le.|.gt.|.ge.|.ne.}{value}&{name}{=|.eq.|.lt.|.le.|.gt.|.ge.|.ne.}{value}&...&l={n}


重要なことは、どんなに分散しても全体の階層管理は崩れず一貫した操作が可能になっているということ。RDBであればデータ量が増えるとテーブル分割などで頭を悩ませることになるが、ReflexWorksであればアプリはBDBのことを気にせず単にREST APIを実行すればよく、裏にあるノードの数なども気にする必要はない。

ReflexWorksにおけるトランザクション処理

トランザクションに関して説明する。
reflexworksでは、最小単位のentryにaliasという別名フォルダを複数付けることができ、またatomicな更新ができる仕組みを提供している。別名フォルダとは、/foo/doc1.xmlを/bar/doc1.xmlでもアクセス可能にする仕組みで、UNIXファイルシステムのシンボリックリンクだとおもっていただければ結構だ。


atomicity(原子性)、isolation(分離性)、consistency(一貫性)
  • (ATOMの)entryはトランザクションの最小単位であり原子性をもつ
    • つまり、RDBの1レコードに相当
  • alias(別名)の追加削除はentry内であるためatomicでありisolationが保たれる
    • 例えば、entryがフォルダ移動しても2重に見えたりはしない
  • 複数のentryはfeedで括られる
  • feedのPOST/PUTは1トランザクションで実行されるため、どれか一つでも失敗するとロールバックする(一貫性は保たれる)

例えば、本を買う例でいえば、本はカートに入れられるか、入れるに失敗するかでなければならない。あるいは、買うか買わないかである。




これは、フォルダをカートとみなせば、注文データ(Document)がフォルダ移動する問題に置き換えることができる。以下のように、異なるフォルダで同時に見えてはいけないし、どちらにもないという状態があってはいけない。




これを、reflexworksで実装すると以下のようになる。selfはこのドキュメントの実体があるフォルダを示す。(固定)一方のalternate(別名)のフォルダがfolder1からfolder2に更新されることで上記のフォルダ移動を実現する。entryの更新はatomicなので一貫性は保たれる。


最後に

KVS上でアプリを動作させるために必要なこととは、トランザクション処理とセカンダリインデックスの2つということを説明してきたが、あくまでこれはオンライン業務のアプリに関してであり、一貫性を必要としないような検索系のアプリなどは他のKVSを使ってさらに高速化できるだろう。あるいは、BDB以外でトランザクション処理とセカンダリインデックスをサポートするKVSがあるかもしれない。実はReflexWorksはBDBに特化したものではなく、他のKVS上でも動作するように、TaggingServiceとDatastoreはレイヤーを別けて作ってある。実際にGAE上でも動作するし、本当は、DynamoDBやAzure上でも動かしたいと思っている。 繰り返しになるが、ReflexWorksであれば、単純なRESTサービスのAPI実行になるため、下位のレイヤーがどのようなものになろうと開発者は意識する必要がない。また、こうすることでベンダーロックインを防ぐことにもなる。
 ちなみに、先日からFacebook上で開発案件を募集しはじめたので、あわせて紹介しておきたい。 


 ReflexWorksで分業開発をしよう! 
「HTML5や画面デザインなどをお得意とされている方は画面開発だけに集中し、サービスのことは考えなくて構いません。サービスの実装部分はJavaなので、サービス開発担当、もしくは弊社メンバーがお手伝いできます。お互いに得意なところを役割分担しながら分業開発できればいいなと考えています。」


0 件のコメント:

 
© 2006-2015 Virtual Technology
当サイトではGoogle Analyticsを使ってウェブサイトのトラフィック情報を収集しています。詳しくは、プライバシーポリシーを参照してください。