BT

最新技術を追い求めるデベロッパのための情報コミュニティ

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース JBoss Cacheによる分散キャッシュ:Manik Surtani氏へのQ&A

JBoss Cacheによる分散キャッシュ:Manik Surtani氏へのQ&A

JBoss Cacheは(source)Javaベースのアプリケーションに対するエンタープライズ級のクラスタリングソリューションで、頻繁にアクセスされるJavaオブジェクトをキャッシュすることで高可用性をもたらし、劇的にパフォーマンスを向上させることを目指しています。この記事ではプロジェクトを率いるManik Surtani氏とのインタビューを要約する。

Manikさん、まず始めにあなたの顧客がJBoss Cacheを利用してキャッシュの恩恵を受けている一般的なやり方、とりわけ高可用性について話していただけますか。

データを永続化装置、とりわけデータベースから取得することはとても高負荷なことです。そしてデータベースはフロントエンドのスケールアウトやクライアントの追加に対応することになると拡張性がよくない(または安くできない)ということは周知の事実です。一方でCPUコアやメモリはどんどん安くなり、それによってより可用性の高いシステムを求めやすくなっています。"ただいまメンテナンス中です"というのは過去のものとなっています。

JBoss Cacheのような分散キャッシュはデータベースとフロントエンドの中間層となることができ、永続化状態への高速なインメモリアクセスを提供します。インメモリ状態の一貫性の保証、更新、そしてJVMのヒープ領域を抑えるためにJBoss Cacheでは多くのことをしています。

JBoss CacheとHibernateやJBoss Seamのような他の有名なオープンソースプロジェクトとの調和についてはどうでしょう。

いくつかのオープンソースプロジェクトでJBoss Cacheが利用されています。Hibernate(その結果としてJBossアプリケーションサーバのEJB3実装も)バックエンドのデータベースから取得したエンティティを保管するのにJBoss Cacheを利用しています。それによってエンティティを取得する度にデータベースを検索するコストを抑えています。これはほんのさわりにすぎません。Hibernateにおける分散キャシュの利用についてはこれだけじゃなくもっと細かい点がたくさんあります。

SeamもJSFのページフラグメントをキャッシュするのに分散キャシュを利用しています。ここでもフラグメントやページの生成に時間が掛かりそうな部分でのスケーラビリティを向上させています。

他にも、Lucne、Hibernate Search、GridGain、そしてJBossアプリケーションサーバのHTTPセッションクラスタリングとクラスタ化されたシングルサインオンのコードもJBoss Cacheを利用しています。

JBoss Cacheには2つの異なる特徴があります。コアキャッシュとPOJOキャッシュです。この2つの主な違いの要点を教えて下さい。

コアキャッシュはもらったものを単に木構造に似た構造で保管するだけです。キーと値のペアがノードに保持されレプリケーションや永続化のためにシリアライズされています。

一方POJOキャッシュではクラスにバイトコードを織り込んで監視するためにもっと精巧なメカニズムを使用しています。フィールドが変更されたことをキャッシュに通知するためにフィールドにリスナを追加しています。例えば、大きく複雑なオブジェクトをPOJOキャッシュに保管すると、POJOキャッシュはオブジェクトのバイトコードを監視し、そのオブジェクトのプリミティブ部分だけを木構造に保管します。そしてひとたびフィールドが変更されるとその変更されたフィールドだけがレプリケートされます。これによって非常に効果的なきめ細かいレプリケーションを達成できます。

ほんとはもっと多くの違いがありますが、主な違いは上述の通りです。

きめ細かいレプリケーションという点ははPOJOキャッシュとコアキャッシュのパフォーマンスの違いに大きな影響を与えるでしょう。この点に対する見積もりやベンチマーク結果はありますか。

こういったベンチマークはかなりシステムに依存します。従って一般的なベンチマークではあまり意味がありません。大きく複雑なオブジェクトがキャッシュされているとき、きめ細かいレプリケーションはとても役立ちます。しかし、Stringを保管するだけならあまり意味はありません。同様に単純なオブジェクト、例えば2つのString型フィールドしか持たないPersonクラスに対してはPOJOキャッシュは効果どころか(フィールドのインターセプションなどの)オーバーヘッドをもたらします。

このようなことがあるのでこの種の比較にはユースケースに合わせたベンチマークを作ることを常々勧めています。私達はキャッシュ方法や設定の違いをベンチマークするためのフレームワークを開発しました(source)。主にJBoss Cacheの異なるバージョン間でのベンチマークのために内部で利用しているものです。しかしダウンロードできますし、独自のオブジェクトやアクセスパターンに対する独自のテストを記述するための拡張性も十分あります。

特にPOJOキャッシュについて、どのように参照整合性を管理していますか。

オブジェクト参照のことを言っているのであれば、まさにここでバイトコードの織り込みが登場します。POJOにインターセプタを入れてキャッシュにからの参照フィールドを追加しています。

HashMapのようなローカルキャッシュを選択することはありませんか。

多くの人がMapはキャッシュの入り口だといいます(事実、この論点がJSR-107 JCACHEの専門家達に採用されMapを拡張したjavax.cache.Cacheが作られました)。しかし、Mapは単純なキーと値のペアを保管するのには優れていますが、キャッシュに必要なその他の特質の多くについて不十分です。例えば、メモリ管理(メモリからの削除)、非活性化と永続化、そしてより細かいロック制御(例えばHashMapは全くスレッドセーフではありません。そしてConcurrentHashMapはロックしているオブジェクト以外からの読込みやまして同時読込みにすら対応していません)などです。そして適切なキャッシュには"エンタープライズ"の特質があります。JTA互換性やリスナが追加可能であることなどになります。

従って、Mapはいい入り口ですがもし上記の特質のいずれか一つでも実装したり管理したくなったらMapではなくてキャッシュを利用するべきでしょう。

どのようなロック機構を利用していますか。従来からデータベースで利用されているものと同じでしょうか。

JBoss Cacheは従来から木構造のノード一つずつに対するロックと並行して悲観的ロックの手法を採用しています(source)。これらのロックには分離性 ― データベースの対応する機能に類似しています ― が適用されこれによって同時読取りが可能になったりしています。

楽観的ロックの手法も提供しています。これは管理用のデータを持ち各トランザクションではコピーを扱い、トランザクションがコミットされる時に本体の木構造とコピーを検証することになります。書込みによって読取りが待たされるということがまったくないような頻繁な読取りが発生するシステムに対して非常に高い同時実行性を提供します。そして悲観的ロックで発生しがちなデッドロックに対応する可能性ともなります。

JBoss Cache 3.0.0と同時に複数バージョンによる同時実行制御(MVCC)機能のリリースへ向けて(source)、現在鋭意開発中です。これは多くの一般的なデータベースシステムで利用されている手法で楽観的ロックや悲観的ロックを凌ぐものになるでしょう。そしてこの実装は読取りに対してはロックフリーになるでしょう。これによって今までのロッキングの仕組みよりかなり速くなると思います。これが安定すればMVCCをJBoss Cacheのデフォルトのロック機構にしたいと思っています。

JGroups(source)との統合について少しお聞かせ下さい。

JBoss Cacheでは他のグループを探し出しクラスタを構成するためのグループ間通信のライブラリとしてJGroupsを利用しています。またグループ内の他のキャッシュと通信するために私達が実装したRPC機構のチャンネルとしても利用しています。JBoss CacheはJGroupsのネットワークプロトコルやチューニングにおける高度な柔軟性や拡張性の高さの恩恵を受けています。これによりキャシュは組み込み機能としてLAN上のクラスタで稼働したり、ファイヤウォール越しのWAN上でクラスタを構成することもできるのです。

JBossアプリケーションサーバ抜きでキャッシュ(機能)だけを使うことはできますか。

勿論です!JBoss Cacheを使うのにJBossアプリケーションサーバが必要だと広く誤解されています。これは間違いです。スタンドアロンのJavaプログラムでも利用されています。GUIにも利用されています。他のアプリケーションサーバでも利用されています。たまたまJBossアプリケーションサーバと一緒に出荷されているだけです。

一つより多くのノードへのレプリケーションというのはフェールオーバには必須の要素でありその実装方法には多くの方策があります。JBoss Cacheではどのようなレプリケーションモデルをサポートしていますか。

現在、2つの方法をサポートしています。全ノード間でのレプリケーション(TR: total replication)と特定ノード間でのレプリケーション(BR: buddy replication)です。TRはグループ内の全てのメンバに状態をコピーします。この方法は状態を共有しどのメンバに対してもフェールオーバできることを保証するという意味ではとても素晴らしい方法ですが、可用性を阻害します。一方でBRは特定のメンバをバックアップ対象として選んでそのバックアップメンバに対してのみ状態をレプリケートします。このことはバックアップノードへフェールオーバした時が最も効果があることを意味します。ただ、リクエストを辿って状態が移されるので他のメンバにフェールオーバしたとしても問題なく動きます。session affinityと一緒に利用するにはBRが一番の組み合わせになります。というのもセッション状態の移動は高負荷であるためにその発生はフェールオーバの際にのみ限定する必要があるからです。

ノード間のレプリケーションにピア・ツー・ピアモデルを利用すると特定のアーキテクチャで可用性の問題が発生するようです。JBoss Cacheでもこのような問題がありますか。

ありません。ブロードキャスト通信のためにLANとIPマルチキャストを利用する場合、ピア・ツー・ピアネットワークとグループ通信はとても効果的です。最近のほとんどのネットワーク機器は既にIPマルチキャストに対応しています。しかし、ピア・ツー・ピアによるデータレプリケーション ― 全てのメンバがシステムの全ての状態を保持している ― には可用性の問題があるかもしれません。先ほどのトータルレプリケーションに関するコメントを見て下さい。このような理由で私達はsession affinityを利用する局面ではbuddy replicationを勧めるのです。

私達はパーティショニングについても取り組んでいます(source)。これによってグループ全体に渡って適切な可用性の手段で適切に状態を分散管理することができます。そしてこの時にsession affinityは不要なのです。この技術によってbuddy replicationとtotal replicationの両方が無用になることを願っています。

近い将来キャッシングとクラスタリングにおいてどんなトレンドが現れることを期待していますか。そしてJBoss Cacheはどのように進化してこれらのニーズを満たしていくつもりですか。

ハードウェアが安くなり、CPUメーカーが1つのチップにより多くのコアを積むようになればなるほど分散キャッシュは重要になってくるでしょう。このことは必然的により多くの"仮想"マシンを生み出しそのような高い同時実行性を管理するためにデータベースを最大限に働かせることにさえつながるでしょう。そして分散キャッシュは大きなボトルネックに対する解決策として最も重要なものの一つとなるでしょう。加えてデータグリッドとクラウドコンピューティングの流行りです。というのもクラウドやグリッド内の各ノードは共有データにアクセスする必要があるからです。

パーティンショニングとMVCCは今後のクラスタサイズに対する膨大な要望にJBoss Cacheが対応するために必要なものだと思います。

原文はこちらです:http://www.infoq.com/news/2008/06/jboss-cache-interview

この記事に星をつける

おすすめ度
スタイル

BT