第20章 ビルディングブロックのクラスター化
JBoss Enterprise Application Platform のクラスタリング機能は、コア機能の多くを提供するローレベルライブラリの上にビルドされています。 図20.1「JBoss Enterprise Application Platform のクラスタリングアーキテクチャー」 に主な機能が記載されています。

図20.1 JBoss Enterprise Application Platform のクラスタリングアーキテクチャー
JGroups は、 信頼できるポイントツーポイント通信やポイントツーマルチポイント通信向けのツールキットです。 JGroups は JBoss Enterprise Application Platform クラスターにおけるノード間のクラスター関連の通信に使用されます。
JBoss Cache は、 大変柔軟なクラスター化されたトランザクションキャッシングライブラリです。 Enterprise Application Platform のクラスタリングサービスの多くが、 メモリ内にステートをキャッシュする必要があります。 この際、 再作成 (Web セッションの内容など) できない場合にステートのバックアップコピーが別のノードで使用できるよう、高可用性を維持し、クラスターの各ノードにキャッシュされたデータの一貫性を維持する必要があります 。JBoss Cache は、JBoss Enterprise Application Platform のクラスター化サービスのこのような懸念に対応します。JBoss Cache は JGroups を使用してグループ通信の要件に対応します。 POJO Cache は JBoss Cache のコアの延長で、 クラスターされた Web セッションステートのきめ細かいレプリケーションをサポートするため JBoss Enterprise Application Platform によって使用されます。 JBoss Enterprise Application Platform が JBoss Cache や POJO Cache をどのように使用するかについては、 「JBoss Cache による分散キャッシング」 を参照してください。
HAPartition は JGroups の上部にあるアダプターで、 複数のサービスが JGroups チャネルを使用できるようにします。 HAPartition は、 クラスターメンバ上で実行されている HAParition ベースのサービスに対する分散レジストリをサポートします。 クラスターメンバーシップやクラスターされたサービスのレジストリが変更した時に、 リスナーに通知を行います。 HAPartition の詳細は 「HAPartition サービス」 を参照してください。
他の高レベルクラスタリングサービスは JBoss Cache か HAPartition を使用します。 HA-JNDI は JBoss Cache と HAPartition の両方を使用します。 例外は JBoss Messaging のクラスタリング機能で、 JGroups と直接対話します。
20.1. JGroups とのグループ通信
JGroups は、 JBoss Enterprise Application Platform クラスタに対する基礎のグループ通信サポートを提供します。 ピアとグループ通信する必要がある JBoss Enterprise Application Platform は JGroups
Channel を取得し、 通信するために使用します。 Channel は、どのノードがグループのメンバーであるかを管理し、 ノードの障害を検出して、 すべてのグループメンバに対してメッセージを失わないよう先着 (FIFO) 順にメッセージを発信します。 また、フロー制御を提供し、低速のメッセージ受信者が高速のメッセージ送信者によって圧倒されないようにします。
JGroups
Channel の特徴は、 JGroups Channel を構成するプロトコルのセットによって決まります。 各プロトコルはグループ通信タスク全体の 1 つのアスペクトを処理します。 例えば、 UDP プロトコルは UDP データグラムの送受信の詳細に対応します。 UDP プロトコルを使用する Channel は UDP ユニキャストとマルチキャストと通信することができます。 TCP プロトコルを使用する Channel は、 すべてのメッセージに対して TCP ユニキャストを使用することができます。 JGroups は多くのプロトコルをサポートしていますが (詳細は 「JGroups チャネルのプロトコルスタックを設定」 を参照)、 Enterprise Application Platform には多くのニーズに対応するチャネル設定のデフォルトセットが同梱されています。
デフォルトでは、Enterprise Application PlatformのJGroupsチャネルがすべてUDPマルチキャストを利用します(TCPベースのJBoss Messaging チャネルは例外)。サーバーに対するデフォルトのマルチキャストタイプを変更するには、
$JBOSS_HOME/bin/でrun.confを作成し、そのファイルを開きJAVA_OPTS="$JAVA_OPTS -Djboss.default.jgroups.stack=<METHOD>"を追加します。
20.1.1. チャネルファクトリサービス
JBoss Enterprise Application Platform 5 と以前のリリースとの大きな違いは、 クラスタリングサービスが必要とする JGroups Channel (分散 HttpSession キャッシュによって使用されるチャネルなど) が、 コンシュームするサービスの設定の一部として詳細に設定にされなくなり、 コンシュームするサービスによって直接インスタンス化されなくなったことです。 その代わりに、 名前付きチャネル設定のレジストリおよび
Channel インスタンスのファクトリとして、 新しい ChannelFactory サービスが使用されるようになりました。 チャネルが必要なサービスは ChannelFactory よりチャネルをリクエストし、 希望する設定の名前を渡します。
ChannelFactory サービスは
server/production/deploy/cluster/jgroups-channelfactory.sar にデプロイされます。 ChannelFactory サービスは起動時に名前 (UDP や TCP など) によって識別される様々な標準 JGroups 設定が含まれる server/production/deploy/cluster/jgroups-channelfactory.sar/META-INF/jgroups-channelfactory-stacks.xml ファイルを構文解析します。チャネルが必要なサービスはチャネルファクトリにアクセスし、特定の名前付き設定を持つチャネルを要求します。
注記
複数のサービスが ChannelFactory より同じ設定名を持つチャネルをリクエストした場合、 同じ基礎のチャネルへの参照はこれらのサービスには提供されません。 各サービスへ独自のチャネルが提供されますが、 チャネルの設定はすべて同じになります。 この場合、 これらのチャネルが同じマルチキャストアドレスやポートを使用する場合など、 チャネル同士がグループを形成しないようにする方法が論理的な問題となります。そのため、 コンシュームするサービスがチャネルに接続し、 サービスに固有の
cluster_name 引数を Channel.connect(String cluster_name) メソッドに渡します。 ネットワーク上で受信したメッセージが意図されたものであるかを判断する要素の 1 つとして、 チャネルは cluster_name を使用します。
20.1.1.1. 標準のプロトコルスタック設定
Enterprise Application Platform 5 に同梱される標準のプロトコルスタック設定は以下のようになります。すべての設定が実際に使用されるわけではありません。 同梱される多くはデフォルトのサーバープロファイルを変更したいユーザー向けの設定となります。 変更されていない本来の Enterprise Application Platform 5 の production サーバープロファイルで実際に使用される設定は、
udp、jbm-control、 jbm-data になります。JBoss Messaging 以外のクラスタリングサービスは udp を使用します。
新しいスタック設定を追加するには、 新しい
stack 要素を server/production/deploy/cluster/jgroups-channelfactory.sar/META-INF/jgroups-channelfactory-stacks.xml ファイルに追加します。 このファイルを編集すると、既存設定の動作を変更できます。 追加や変更を行う前に、 Enterprise Application Platform に同梱される標準設定を確認してみてください。 ニーズに合った標準設定があるかもしれません。 また、 設定を編集する前にどのサービスがこの設定を利用しているか把握し、影響を受ける全サービスに対して、変更したい設定が適切であるよう確認します。特定のサービスに対して変更が不適切な場合、 新しい設定を作成して一部のサービスが新しい設定を使用するよう変更した方がよいかもしれません。
- udpUDP マルチキャストベースのスタックは、 異なるチャンネルによって共有されることを目的としています。 同期グループ RPC の待ち時間が長くなるため、 メッセージのバンドルは無効になっています。 非同期 RPC のみを大量に呼び出すサービス (REPL_ASYNC 向けに設定された JBoss Cache など) の場合、 次のようにキャッシュが
udp-asyncスタックを使用するよう設定するとパフォーマンスを改善できるでしょう。 同期 RPC のみを呼び出すサービス (REPL_SYNC や INVALIDATION_SYNC 向けに設定された JBoss Cache など) の場合、 フロー制御が含まれない次のudp-syncスタックを使用するとパフォーマンスを改善できるでしょう。 - udp-async前述のデフォルトの
udpスタックと同じですが、 トランスポートプロトコルでメッセージバンドルが有効になっています (enable_bundling=true)。 メッセージのバインドによりパフォーマンスが改善できる大量の非同期 RPC (REPL_ASYNC 向けに設定された大量の JBoss Cache インスタンスなど) を呼び出すサービスに対して有用です。 - udp-syncフロー制御やメッセージバンドルがない UDP マルチキャストベースのスタックです。 同期呼び出しが使用され、 メッセージの量 (メッセージ比率とサイズ) が大きくない場合、
udpの代わりに使用することができます。持続率が高い状態でメッセージを送信する場合、 メモリが不足することがあるため、 この設定は使用しないでください。 - tcpフロー制御とメッセージバンドルを持つ TCP ベースのスタックです。TCP スタックは通常、 ネットワークで IP マルチキャストが使用できない場合に使用します (ルーターがマルチキャストを破棄する場合など)。
- tcp-syncフロー制御やメッセージバインドがない TCP ベースのスタックです。 TCP スタックは通常、 ネットワークで IP マルチキャストが使用できない場合に使用します (ルーターがマルチキャストを破棄する場合など)。 同期呼び出しが使用され、 メッセージの量 (メッセージ比率とサイズ) が大きくない場合、 前述の
tcpの代わりにこの設定を使用するようにしてください。高い持続率でメッセージを送信する場合、 メモリが不足することがあるため、 この設定は使用しないでください。 - jbm-controlJBoss Messaging の制御チャネル向けに最適化されたスタックです。 デフォルトでは、 前述の
udpスタックがデフォルトで使用する UDP トランスポートプロトコル設定と同じ設定が使用されます。 これにより、 JBoss Messaging の制御チャネルが、 他の標準 JBoss Enterprise Application Platform のクラスタされたサービスが使用するソケットやネットワークバッファー、 スレッドプールを使用できるようになります (「JGroups 共有トランスポート」 を参照してください)。 - jbm-dataJBoss Messaging データチャネル向けに最適化された TCP ベースのスタックです。
20.1.1.2. プロトコルスタック設定の変更
デフォルトでは、JBoss Messaging 以外のクラスタリングサービスはすべて
udp プロトコルスタック設定を利用します。TCPベースの設定を利用したい場合、system property jboss.default.jgroups.stackをtcp の値(-Djboss.default.jgroups.stack=tcp)に設定してください。この変更により、JGroups チャネルを使うサービスのほとんどをTCPベースの設定に構成します。tcp をデフォルトのプロトコルスタックにするには、Linux プラットフォームでは $JBOSS_HOME/bin/run.confにあるJAVA_OPTS の環境変数に、またWindows プラットフォームでは$JBOSS_HOME/bin/run.conf.batにある環境変数をこのシステムプロパティを追加します。
tcp スタックは、ピア検出に (MPING層経由で) UDPマルチキャストを使います。こうすることで、スタックが環境固有のホスト設定を避け、カスタマイズなしに使うことができます。UDPマルチキャストを利用できない場合、非UDPベースのピア検出層 (TCPPING層)に変更し、必要と考えられるクラスターノードのアドレス/ポートを設定する必要があります。jgroups-channelfactory-stacks.xml からプロトコルスタック設定を変更できます。このファイルには、両ピア検出層の定義をを含みます。デフォルトでは、MPING層の定義はアンコメントされ、TCPPING層はコメントされています。非UDPベースのピア検出に切り替えるには、MPING層をコメント、TCPPING層をアンコメントし、設定します。MPINGおよびTCPPINGの詳細情報は、「ディスカバリプロトコル」 を参照してください。
20.1.1.3. JBoss Messagingのプロトコルスタック設定
JBoss Messagingはデフォルトで
jbm-control および jbm-data プロトコルスタック設定を利用します。jbm-control プロトコルスタックは、完全にUDPベースとなっており、jbm-data はUDPマルチキャストを採用するMPING検出プロトコルを使います。そのため、JBoss Messaging でTCPベースの設定のみを使いたい場合は、JBoss Messaging コントロールチャネルをjbm-control スタックの代わりにtcp プロトコルスタックを使用するよう設定し、jbm-data プロトコルスタックがMPING層の代わりにTCPPING層を利用するように変更しなければなりません。
JBoss Messaging コントロールチャネルを
tcp プロトコルスタックを使うように設定するには、deploy/messaging/RDMS-persistence-service.xmlファイルを開き(RDMS の値はメッセージの永続化に利用している関係データベース管理システムにより変わります)、org.jboss.messaging.core.jmx.MessagingPostOfficeService mbeanのControlChannelName 属性値をtcpに変更します。
<!--<attribute name="ControlChannelName">jbm-control</attribute>--> <attribute name="ControlChannelName">tcp</attribute>
MPING層ではなくTCPPING層を使うようにjbm-data プロトコルスタック定義を変更するには、
定義済みポートが他のTCPPING層で使われているポートと矛盾しないようにしてください。システムプロパティ-Djbm.data.tcpping.initial_hosts を使い、JAVA_OPTSからこの層の初期ホストを設定することができます。
/server/PROFILE/deploy/cluster/jgroups-channelfactory.sar/META-INF/jgroups-channelfactory-stacks.xml を開き、例20.1「TCPPING 定義を持つjbm-data プロトコルスタックの定義」に示されているようにMPING層を同等のTCPPING層に置き換えます。
例20.1 TCPPING 定義を持つjbm-data プロトコルスタックの定義
<!--
<MPING timeout="3000"
num_initial_members="3"
mcast_addr="${jboss.jgroups.tcp.mping_mcast_addr:230.11.11.11}"
mcast_port="${jgroups.tcp.mping_mcast_port:45700}"
ip_ttl="${jgroups.udp.ip_ttl:2}"/>
-->
<TCPPING timeout="5000"
initial_hosts="${jbm.data.tcpping.initial_hosts:localhost[7900],localhost[7901]}"
port_range="1"
num_initial_members="3"/>
20.1.2. JGroups 共有トランスポート
Enterprise Application Platform 上で実行される JGroups ベースのクラスタリングサービスの数が年を追って増加したため、これらのチャネルが使用するリソース (特にソケットとスレッド) を共有する必要性が問題となりました。 Enterprise Application Platform 5 の production 設定は、起動時に 4 つの JGroups チャネルに接続します。分散可能な Web アプリケーション、クラスターされた EJB3 SFSB、 クラスターされた JPA/Hibernate 2 次キャッシュがすべて使用されると合計で 7 つまたは 8 つの JGroups チャネルが接続されます。 チャネルの数が多くリソースが大幅に消費されることがあるため、 ネットワーク環境が設定にクラスター分離を必要とする場合、 設定が大変困難になります。
Enterprise Application Platform 5 より、 JGroups がチャネル間のトランスポートプロトコルインスタンスの共有をサポートするようになりました。 JGroups チャネルは、 個別のプロトコルのスタックにより構成され、各プロトコルはチャネル動作の 1 つのアスペクトを担当しています。ト ランスポートプロトコルは、 実際にメッセージをネットワーク上で送信、あるいはネットワークより受信するプロトコルです。 共有が望ましいリソース (ソケットとスレッドプール) はトランスポートプロトコルにより管理されているため、 チャネル間でトランスポートプロトコルを共有すると、 JGroups のリソースを効率的に共有することができます。
トランスポートプロトコルの共有を設定するには、
singleton_name="someName" 属性をプロトコルの設定に追加します。 トランスポートプロトコル設定が同じ singleton_name 値を使用するすべてのチャネルがトランスポートを共有します。 スタック内の他のプロトコルは共有されません。 図20.2「共有トランスポートを使用するサービス」 では、 仮想マシンで 4 つのサービスが実行され、 各サービスが独自のチャネルを持っています。 3 つのサービスがトランスポートを共有し、 1 つのサービスは独自のトランスポートを使用しています。

図20.2 共有トランスポートを使用するサービス
Enterprise Application Platform 5 の ChannelFactory が使用するプロトコルスタック設定にはすべて
singleton_name が設定されています。 スタックのチャネルを作成する前に singleton_name が含まれていない ChannelFactory にスタックを追加すると、 「unnamed_customStack」 のように 「unnamed_」 ストリングにスタック名を連結して ChannelFactory が合成的に singleton_name を作成します。