第8章 キャッシュモードとクラスタリング
本章では、 JBoss Cache のクラスタリングについて説明します。
8.1. キャッシュレプリケーションモード リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
JBoss Cache はローカル (スタンドアロン) またはクラスタとして設定することができます。 クラスタの場合は、 変更をレプリケートまたは無効にするよう設定することができます。 この詳細は後ほど説明します。
8.1.1. ローカルモード リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
ローカルキャッシュはクラスタに参加せず、 クラスタ内の他のノードと通信しません。 JGroups チャネルは起動されませんが JGroups ライブラリへ依存します。
8.1.2. レプリケートされたキャッシュ リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
レプリケートされたキャッシュは、 クラスタ内にある他のキャッシュインスタンスの一部またはすべてへの変更をレプリケートします。 レプリケーションは変更後 (トランザクションまたはバッチなし) か、 トランザクションまたはバッチの終了後に行われます。
レプリケーションは同期的または非同期的に行うことができます。 オプションの使用はアプリケーションに依存します。 同期レプリケーションは、 変更がクラスタ内のすべてのノードに正常にレプリケートされるまで呼出元 (
put() 上など) をブロックします。 非同期レプリケーションは、 レプリケーションをバックグラウンドで実行します (put() は即座に返します)。 また、 JBoss Cache は、 変更が定期的に行われる場合 (間隔ベースの場合など) や、 キューの大きさが要素の数を超えた場合にレプリケーションキューを提供します。 そのため、 レプリケーションキューはバックグラウンドスレッドによって実行される実際のレプリケーションよりも高いパフォーマンスを提供できます。
非同期レプリケーションは、 同期レプリケーションよりも高速です (呼出元のブロックなし)。 これは、 同期レプリケーションはクラスタ内のすべてのノードからノードが変更を正常に受け取り適用したという確認を必要とするためです (ラウンドトリップ時間)。 しかし、 同期レプリケーションが正常に返されると、 呼出元はすべての変更がすべてのノードで適用されたことを確信できますが、 これは非同期レプリケーションでは確信できません。 非同期レプリケーションでは、 エラーは単にログに書き込まれます。 トランザクションを使用している場合でも、 トランザクションに成功してもすべてのキャッシュインスタンスでレプリケーションに成功していないことことがあります。
8.1.2.1. レプリケートされたキャッシュトランザクション リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
トランザクションを使用している場合、 レプリケーションはトランザクション境界でのみ実行されます (トランザクションのコミット時など)。 この結果、 個々の変更の集まりではなく単一の変更がブロードキャストされるためレプリケーションのトラフィックが最小化され、 トランザクションを使用しない場合よりも非常に効率的になります。 また、 これによりトランザクションをロールバックした時はクラスタ全体に何もブロードキャストされません。
JBoss Cache はクラスタを非同期モードで稼働している場合は単相コミットプロトコル、 同期モードで稼働している場合は 2 相コミットプロトコルを使用します。
8.1.2.1.1. 単相コミット リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
キャッシュモードが REPL_ASYNC の場合に使用されます。すべての変更は、変更をローカルのインメモリステートに適用し、ローカルでコミットするようリモートキャッシュに指示する単一の呼び出しでレプリケーションされます。通信は非同期であるため、リモートエラー/ロールバックはトランザクションの開始元に通知されません。
8.1.2.1.2. 2 相コミット リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
キャッシュモードが REPL_SYNC である場合に使用されます。 トランザクションのコミット時に JBoss Cache が、 トランザクションに関連するすべての変更を実行する準備呼び出しをブロードキャストします。 リモートキャッシュはインメモリステートでローカルロックを取得し、 変更を適用します。 すべてのリモートキャッシュが準備呼び出しに応答すると、トランザクションの開始元がコミットをブロードキャストします。 これにより、 すべてのリモートキャッシュがデータをコミットするよう指示されます。 いずれかのキャッシュが準備フェーズの応答に失敗すると、 開始元がロールバックをブロードキャストします。
準備フェーズは同期的ですが、 コミットフェーズとロールバックフェーズは非同期的です。 これは、 Sun の JTA 仕様には、 この段階のトランザクション障害のトランザクションリソースによる対処方法が指定されておらず、 トランザクションに参加している他のリソースが中間のステートであることがあるからです。 したがって、 このフェーズのトランザクションに対する同期通信のオーバーヘッドは考慮しません。
SyncCommitPhase および SyncRollbackPhase 設定属性を使用すると、 強制的に同期にすることができます。
8.1.2.2. バディレプリケーション リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
バディレプリケーションでは、クラスタ内のすべてのインスタンスにデータをレプリケートすることを回避できます。各インスタンスはクラスタ内の 1 つまたは複数の「バディ (仲間)」を選択し、これらの特定のバディにのみレプリケートします。これにより、他のインスタンスがクラスタに追加された時にメモリとネットワークトラフィックの影響がなくなり、 スケーラビリティが大幅に向上します。
バディレプリケーションの典型的な使用例としては、 HTTP セッションデータを保存するためにサーブレットコンテナによってレプリケートされたキャッシュが使用される場合などがあります。 バディレプリケーションを正常に動作し、 効果的に使用するには「セッションアフィニティ」 (HTTP セッションレプリケーションでは「スティッキーセッション」とも呼ばれる) を使用する必要があります。 これは、特定のデータが頻繁にアクセスされる場合に、 そのデータがラウンドロビン方式ではなく 1 つのインスタンスで常にアクセスされることが好ましいことを意味します。 これによりキャッシュクラスタがバディを選択する方法やデータの保存場所を最適化し、 レプリケーショントラフィックを最低限に抑えることができます。
これが不可能な場合はバディレプリケーションの利点はなく、 オーバヘッドが増加します。
8.1.2.2.1. バディの選択 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
図8.1 BuddyLocator
バディレプリケーションは、 ネットワーク内でのバディ選択に使用する論理が含まれる
BuddyLocator のインスタンスを使用します。 現在、 JBoss Cache には実装が提供されない場合にデフォルトで使用される単一の実装 NextMemberBuddyLocator が同梱されています。 NextMemberBuddyLocator は、 名前の通りクラスタ内の次のメンバーを選択し、 各インスタンスに対してバディを均等に分散します。
NextMemberBuddyLocator は 2 つのパラメータを受け取ります (両方ともオプション)。
numBuddies- 各インスタンスがデータをバックアップするバディの数を指定します。このデフォルト値は 1 です。ignoreColocatedBuddies- 各インスタンスは異なる物理ホスト上でバディの選択を試みます。 選択できない場合は、 共同の場所にあるインスタンスに戻ります。 デフォルトはtrueです。
8.1.2.2.2. BuddyPools リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
バディプールは「レプリケーショングループ」とも呼ばれるオプションのコンストラクタで、 クラスタ内の各インスタンスをバディプール名で設定できます。 バディを選択する時にバディプールをサポートする
BuddyLocator が同じバディプール名を共有するバディを選択しようとする「会員制クラブ」のようなものと考えてみてください。 これにより、 システム管理者にある程度の柔軟性を提供し、 バディーの選択方法を制御できるようになります。 例えば、 システム管理者は同じバディプール内の 2 つの異なる物理ラック上にある 2 つの異なる物理サーバーに 2 つのインスタンスを置くことができます。 したがって、 同じラックの異なるホストにあるインスタンスを選択する代わりに、 BuddyLocator は異なるラックの同じバディプールのインスタンスを選択するため、 ある程度の冗長性が追加されることがあります。
8.1.2.2.3. フェイルオーバー リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
不幸にもインスタンスがクラッシュすると、 キャッシュに接続しているクライアント (HTTP セッションレプリケーションなどの他の一部のサービスを使用して直接的または間接的に行う) がクラスタ内の他のキャッシュインスタンスに要求をリダイレクトできるとみなされます。 ここで「データグラビテーション」の概念が重要になります。
データグラビテーションとは、 クラスタ内のキャッシュに対する要求が行われ、 キャッシュにその情報が含まれない場合にクラスタ内の他のインスタンスにデータを要求する概念です。 データはレイジーに転送され、 他のノードが要求する場合のみ移行します。 これにより、 1 つまたは少数のノードのみが犠牲となるため、 ノードの周りに多くのデータが押し込まれるネットワークストームによる影響を回避することができます。
ノードの第 1 セクションにデータが見つからない場合、 他のキャッシュに対して保存したバックアップデータを確認するよう他のインスタンスに要求します (オプション)。 そのため、 セッションが含まれるキャッシュが消失しても、 このデータのバックアップを検索するようクラスタに要求し、 他のインスタンスはこのデータにアクセスすることができます。
見つかったデータは要求したインスタンスへ転送され、 インスタンスのデータツリーに追加されます。 セッションアフィニティが使用された場合にアフィニティがこのデータの「所有権」を取得した新しいキャッシュインスタンスに対して設定されるよう、 このデータは他のインスタンス (およびバックアップ) すべてから削除されます (オプション)。
データグラビテーションはインターセプタとして実装されます。データグラビテーションに関する設定プロパティは以下の通りです (すべてオプション)。
dataGravitationRemoveOnFind- データを所有するかデータのバックアップを保持するすべてのリモートキャッシュがそのデータを削除し、 要求元のキャッシュが新しいデータ所有者になるよう強制します。 新しい所有者がバディへデータをレプリケートした後でのみ削除が実行されます。falseに設定すると、 削除ではなくエビクションがブロードキャストされ、 キャッシュローダーに持続されたステートはそのままの状態となります。 共有されたキャッシュローダーが設定されている場合に便利です。 デフォルト値はtrueです。dataGravitationSearchBackupTrees- バックアップと主要なデータツリーを検索するようリモートインスタンスに要求します。 デフォルト値はtrueです。trueに設定されている場合、 バックアップノードはデータ所有者だけでなくデータグラビテーション要求にも応答できます。autoDataGravitation- キャッシュミスが発生する度にデータグラビテーションを実行するかどうかを設定します。 不必要なネットワーク呼び出しを防ぐため、 デフォルト値はfalseになっています。 ほとんどのユースケースでは、 データのグラビテーションが必要な時やOptionを渡す時を認識し、 呼び出し毎にデータグラビテーションを有効します。autoDataGravitationがtrueの場合は、このOptionは必要ありません。
8.1.2.2.4. 設定 リンクのコピーリンクがクリップボードにコピーされました!
リンクのコピーリンクがクリップボードにコピーされました!
バディーレプリケーションの設定に関する詳細は 12章設定に関する参考資料 を参照してください。