Javaアプリケーションサーバのクラスタリング機能比較 3

ステートフルセッションBean

ステートフルセッションBean

ステートフルセッションBeanは状態を保持するため、セッション情報のレプリケーションが必要になります。

デフォルトポリシーはHomeインターフェースに対しては"RoundRobin"、Remoteインターフェースに対しては"FirstAvailable"です。

レプリケーションはコストのかかる処理であるため、なるべく発生させないようにすることが望ましいのです。例えば、HTTPセッションレプリケー ションではセッションが変更されなければレプリケーションは起こりませんし、"replication-trigger"と"replication- granularity"を組み合わせれば、レプリケーションの発生を抑えられます。

ステートフルセッションBeanでは"isModified"メソッドによってレプリケーションの発生をコントロールできます。

"isModified"メソッドのシグニチャ

public boolean isModified();

EJBコンテナはレプリケーションを実行する前にこのメソッドを呼び出します。このメソッドの戻り値がtrueだった場合、EJBの状態が変更されているものとしてレプリケーションを実行します。

このロジックは自由に実装できます。例えば、EJBのフィールドとして"private boolean modified"という変数を用意し、レプリケーションして欲しいような変更が加わったときにのみ"modified"にtrueをセットします。そし て"isModified"メソッドが"modified"をreturnするように実装すれば、自分の望むタイミングでレプリケーションを発生させるこ とができます。

実装例

public class SampleSFSB implements SessionBean {

     private boolean modified = false;

     ⁄⁄ その他のフィールド

     public boolean isModified() {
          return modified;
     }

     public void setModified(boolean flag) {
          modified = flag;
     }

     ⁄⁄ その他のメソッド

}

 

エンティティBean

エンティティBeanではロードバランスが行われます。デフォルトポリシーはHomeインターフェースが"RoundRobin"、Remoteインターフェースは"FirstAvailable"です。

エンティティBeanはクラスタ間にまたがって整合性を維持するための分散ロックやレプリケーションの機構を持っていません。例えば、2つのクライアントがそれぞれクラスタノードAとクラスタノードBに対して同時に、同じレコードを表すエンティティBeanにアクセスした場合、クラスタノードAでの 更新がクラスタノードBでは反映されていない可能性があります。

整合性が取れない場合
図1:整合性が取れない場合

よって"read-only"以外のエンティティBeanを利用する場合には、表2のどちらかを選ぶ必要があります。

  • 「row-lock」要素をtrueに設定し、データベースレベルで行ロックをかけます
  • データベースのトランザクション独立性レベルをSERIALIZABLEにします
表2:read-only以外のエンティティBeanを利用する場合の選択肢

また、クラスタリングされるエンティティBeanのデフォルト値はコミットオプションBであり、トランザクションごとにデータベースから値を読み込んで同期を取ります。これではキャッシュによるパフォーマンス向上は期待できません。

コミットオプションAであればトランザクション間でキャッシュを共有できるのですが、上記と同様に分散ロックあるいはレプリケーションの機構がない ためクラスタ間でのキャッシュの整合性が取れません。この問題を解決するためJBossには"cache invalidation"という機能があります。

"cache invalidation"はエンティティBeanが更新された際、クラスタノード全体に「更新された」ということを伝えます。各ノードのエンティティ Beanが持つキャッシュはもはや無効であるため、次回のアクセスではエンティティBeanは最初にデータベースと同期を取ります。これによりクラスタリ ングとコミットオプションAを両立できます。

設定は"conf/standardjboss.xml"にすでに用意されているため、EJBの"jboss.xml"に、以下のように"container-name"を指定するだけです。

"container-name"の指定


     
          
               SampleEB
               SampleEBBean
               Standard CMP 2.x EntityBean with cache invalidation
          


(省略)

"cache invalidation"は更新の多いエンティティBeanでは逆にパフォーマンスが落ちる可能性があります。その場合は素直にコミットオプションBを使えばよいでしょう。

ここまではEJB 2.0の話をしてきましたが、EJB 3.0にも簡単に触れておきます。JBoss 4.0ではEJB 3.0のモジュールもデプロイ可能です(EJB 3.0仕様はまだ正式リリースされていません)。

EJB 3.0におけるエンティティBeanではリモートアクセスは提供していないので、ロードバランスという概念はありません。しかしJBossではEJB 3.0のエンティティBeanの実装にHibernateを使用しており、そのキャッシュにJBossCacheが統合されているため、EJB 2.0のエンティティBeanにはない分散キャッシュ(レプリケーション)が働き、クラスタ間で整合性の取れたキャッシュが実現されます。

 

 

この記事をシェアしてください

人気記事トップ10

人気記事ランキングをもっと見る