BT

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

寄稿

Topics

地域を選ぶ

InfoQ ホームページ ニュース JGroupsのmemcached実装 - フェイルオーバやJMXもサポート

JGroupsのmemcached実装 - フェイルオーバやJMXもサポート

memcached(リンク)は分散メモリオブジェクトキャッシュのシステムで、動的なウェブアプリケーションでデータベースの負荷を軽減するのに利用される。memcachedはメモリにデータやオブジェクトをキャッシュしてデータベースの読み込み回数を減らすことでデータベースを多用するウェブサイトのスピードを向上させる。memcachedのベースとなるのはキーとそれに対応する値の組を格納したハッシュマップだ。memcachedのサービスデーモンはCで書かれているが、クライアントの言語はmemcachedプロトコル(リンク)でデーモンと通信できれば何でもいい。memcachedは冗長性を提供する(たとえばハッシュマップのコピーを保存するなど)ものではなく、サーバマシンSが停止したりクラッシュしたりすると、Sにあったキーおよび値は失われてしまう。

JBoss(リンク)のJGroups(リンク)・ClusteringチームのリードであるBela Ben氏は、近頃JGroupsをベースにしてmemcachedを実装した(リンク)。これはJavaのクライアントでmemcachedに直接アクセスできる。この実装は全てJavaで書かれ、memcachedフレームワークよりいくつかの利点をもっている。

  • Java クライアントとPartitioonedHashMap(org.jgroups.blocks.PartitionedHashMap)は同じアドレス空間で動作し、そのためmemcachedプロトコルを使って通信する必要がない。このことでサーブレットはシリアライズ化のオーバヘッドなしでキャッシュに直接アクセスすることができる。
  • 全てのPartitionedHashMapプロセスはお互いを認識し、クラスタの構成が変化する時にどうすればいいかを決めることができる。たとえば、サーバが停止しようとする時、そのサーバが管理している全てのキーを隣のサーバへ移すことができる。memcachedだとサーバSがダウンするとサーバSにあったデータは消えてしまう。
  • クラスタの構成が変化する(新しいサーバS が起動するなど)時、全てのサーバは自分たちのもつデータをSにおくべきかをチェックする。そして必要があればそれらのサーバはサーバSに全てのデータを移す。このことにより(たとえば)SはデータをDBか読み込む必要がなく、(memcachedの場合と同じように)書き込みもDBでなくキャッシュに対しておこなうことができる。またmemcachedと違いキャッシュは自動的にリバランスがおこなわれる。
  • PartitionedHashMap はL1(Level 1)キャッシュをもっている。ここでは必要になりそうなデータをキャッシングする。たとえば、A、B、C、D、Eというサーバがあり、クライアントが(アクセスの多い)ニュース記事をCに置いた時、memcachedだとその記事に対する全てのリクエストをCへリダイレクトすることになる。そのためDにアクセスするクライアントがその記事を得ようとするとDからCへのGETリクエストもすることになる。JGroupsの場合は最初のアクセスでこの記事をD のL1キャッシュに格納するので、Dからこの記事にアクセスしたいクライアントはDにキャッシュされた記事を得ることができ、Cへのラウンドトリップを回避できる。ただし、全てのキャッシュデータには有効期限があり、期限が来るとそのデータはL1キャッシュから削除されるので、削除後にアクセスがあった時にはCから再度データを取ってきてDのL1キャッシュに格納することになる。この有効期限は記事データを置く時に指定される。
  • このシステムでのRPCのGET、SET、REMOVEはJGroupsを転送手段として用いるため、転送を定義するXMLファイルによって転送タイプや QoS(サービスの質)をコントロールしたりカスタマイズすることができる。たとえば、データ圧縮したり、RPC送信データ全体を暗号化したりできる。またUDP(IPマルチキャストおよび(あるいは)UDPデータグラム)やTCPも利用できる。
  • コネクタ(org.jgroups.blocks.memcachedConnector)はmemcachedプロトコルをパースして PartitionedHashMapに対するリクエストをおこなう役割をもつ。memcachedの実体はPartitionedHashMapであり、サーバ( (org.jgroups.demos.memcachedServer)やL1・L2 キャッシュ(org.jgroups.blocks.Cache)は任意に構築したり変更したりすることができる。そのためJGroups memcached実装は簡単にカスタマイズが可能で、たとえばバイナリプロトコルをパースするようなmemcachedコネクタを使うこともできる(もちろんクライアントも合わせる必要がある)。
  • 全ての管理情報および管理操作はJMX(Java Management Extensions:Javaでリソースを管理/監視するための仕様)を通して外部からアクセス可能である

JGroups memcachedの実行を開始するクラスは主にorg.jgroups.demos.memcachedServerだ。このクラスはL1キャッシュ(設定されていれば)とL2キャッシュ(全てのデータを格納するデフォルトのハッシュマップ)、そしてmemcachedコネクタを生成する。この APIは非常にシンプルで、それには次のようなキャッシング用のメソッドが含まれる。

  • public void put(K key, V val):keyとvalの組をキャッシュに置く。キャッシュする有効期限はデフォルトのが設定される。
  • public void put(K key, V val, long caching_time):上のputと同じだが、キャッシングの有効期限を設定できる。0だと期限なし、-1だとキャッシュしない、正の数はデータキャッシングのミリ秒での時間を表す。
  • public V get(K key):key Kに対応する値を取得する
  • public void remove(K key):キーと値の組をキャッシュ(L2およびL1)から削除する。

InfoQはJGroupsによるmemcached実装の動機についてBela Ban氏に聞いた。彼によるとJGroupsのmemcached実装によってJGroupsが分散キャッシュを試すことができ、そして様々なキャッシングの方法のどれがどれだけJBoss Clustringに合うかが分かるようになるという。また彼は、この新しいmemcached実装とJBoxxCacheキャッシングフレームワークとを比較してこう述べた。

わたしたちはキャッシングを、クラスタ内の複数のノード(ホスト)に分散したデータ間の(冗長性がない)連続体だと考え、またトータルデータレプリケーション(全てのクラスタノードに全てのデータを複製する)とも考えています。分散と完全な複製の中間に位置するものとしてバディレプリケーション(特定のノードでだけ複製する)がありますが、これは指定したいくつかのバックアップノードにデータをコピーするものです。この点についてRAIDを見るなら、RAID 0は冗長性のないもの(分散したもの)、RAID 0+1は十分な冗長性のあるもの、RAID 5は部分的な冗長性があるものといえます。
現時点では、JGroupsのPartitionedHashMapは分散性を、JBossCacheはトータルレプリケーションおよび(バディレプリケーション(buddy replication)による)部分的なデータ複製を提供しています。考え方としては、ユーザがクラスタへ置くデータアイテムごとにKという値を設定します。K=0の時は分散を意味します。しかし一つのノードが一つあるいは複数のストライプ(データの分散ブロック)をホストする場合、クラッシュするとデータは失われてしまいます。K=X(ただしX<N)だとRAID 5、K=Nだと完全な複製を意味します。

JGroupsのmemcached実装はK=0、つまり冗長性のない完全なデータ分散を試す最初のステップです。これはいずれJBossCacheに取り込まれることになります。

memcached実装はJBoss Application Serverのどのモジュールに組み込むことができるでしょうか。

memcached 実装はJBossCacheで提供するようになる予定で、そのことでJBoss Clustringのサブシステムとなります。私たちの実装ではJavaで書かれたクライアントを想定しているので、マーシャリング/アンマーシャリング /コピーのオーバヘッドがかかるひどく非効率的なmemcachedプロトコルを使う必要はありません。


JGroupsのmemcached実装を使った典型的なケースについて、氏はこう語った。

JBoss あるいはTomcatのクラスタ上で動くサーバサイドプログラム(サーブレットなど)ですね。そのようなプログラムはDBへアクセスし、DBのボトルネックを解消したり動作を早くするのにキャッシュを必要とします。これに似ていますが、DBへのアクセスでなくファイルシステムへのアクセスをおこなうプログラムも別の利用ケースになります。たとえば、HTMLページのキャッシングサーバが考えられます(Squid(オープンソースのウェブプロキシ/キャッシュサーバ)を頭に浮かべた)。

将来的にこのmemcachedをJBoss Application Serverに組み込むプランはあるのだろうか。


間違いありません。このData Partitioning機能(Data Partitioning feature)によってユーザは必要に応じてキャッシングの設定をおこなえるようになります。分散キャッシュのようなものはそれ自体新しい機能ではなく、 JBossCacheの設定においての課題なのです。設定が動的にでき、ディベロッパが冗長性の種類(none=分散、full=完全あるいは部分的な複製)をJBossCacheに置くデータアイテムごとに決めることができるようになるのがクールなのです。

このプロジェクトの将来の方向性のうち新機能の点について、氏はTODOリストにある次のようなことを挙げた。

  • キャッシュにあるデータの数でなくバイト数によってキャッシュ解放をおこなうポリシーを提供する。
  • キャッシュするデータをリモートサーバから受ける時に、オブジェクトでなくbyte[]バッファで受け取る。最初のアクセスではこのバイトバッファをオブジェクトにアンマーシャリングすることになります。これはJBossのHTTPセッション複製で使われている方法で、不必要なアンマーシャリングのためにパフォーマンスが下がらないようにうまく機能しています。
  • memcachedプロトコルの全てを実装する。現時点ではまだGET、 GET-MULTI、SET、DELETEしかできません。他のもの(APPEND、PREPEND、CAS)を実装するのは簡単ですが、わたしたちの memcached実装で主に想定しているケースは同一JVM内にあるJavaクライアントからの利用で、memcachedプロトコルが必要ではないというのが未実装の主な理由です。
  • コンシステントハッシュ法のより良い実装。

JGroupsのmemcached実装とそれが依存するライブラリは、JGroupsのSourceforgeウェブサイトからダウンロードできる(リンク)。下はプログラムを実行するコマンドだ。

java -jar memcached-jgroups.jar

Bela Ben氏はコミュニティからのフィードバックを望んでいる。氏が語ったようにこれは実験的だが、将来JBossCacheでサポートされる予定の機能で、コミュニティからのフィードバックはこの機能の将来に大きな影響を与えることになるだろう。

原文はこちらです:http://www.infoq.com/news/2008/10/jgroups-memcached

この記事に星をつける

おすすめ度
スタイル

BT