8 クラスタ・メンバーシップの動的な管理

クラスタおよびサービス・メンバーをプログラムで管理し、メンバーおよびサービスのイベントをリスニングできます。

この章の内容は次のとおりです。

クラスタ・メンバーシップの管理の概要

Coherenceでは、新しいサーバーの起動時にそれらのサーバーをクラスタに自動的に追加し、シャットダウンまたは障害の発生時にそれらのサーバーの離脱を自動的に検出することによって、クラスタ・メンバーシップを管理します。アプリケーションはメンバーシップ情報への完全なアクセスが許可されており、メンバーがクラスタに参加したり、クラスタから離脱した際にイベント通知を受信するようにサインアップできます。また、Coherenceは、各メンバーが提供および消費しているすべてのサービスの追跡も行います。この情報は、サーバーに障害が発生した場合のサービスの回復計画およびクラスタのすべてのメンバーにわたるデータ管理の負荷分散に多用されます。

クラスタ・オブジェクトとサービス・オブジェクトの使用

アプリケーションは、クラスタおよびキャッシュ・サービスのローカル表現を使用して、クラスタに関する重要な情報を検出できます。任意のキャッシュから、キャッシュのサービスのローカル表現への参照を取得することができます。また、任意のサービスからクラスタのローカル表現への参照を取得することもできます。
CacheService service = cache.getCacheService();
Cluster      cluster = service.getCluster();

Clusterオブジェクトで、クラスタ内で実行されているサービス・セットを確認できます。

...
for (Enumeration enum = cluster.getServiceNames(); enum.hasMoreElements(); )
    {
    String sName = (String) enum.nextElement();
    ServiceInfo info = cluster.getServiceInfo(sName);
    // ...
    }
...

ServiceInfoオブジェクトは、名前、タイプ、バージョン、メンバーシップなどの情報を提供します。

メンバー・オブジェクトの使用

アプリケーションは、いくつかのAPIを使用して、クラスタの一部であるメンバー、ローカル・メンバー、およびサービス内のメンバーを検出できます。アプリケーションがクラスタ内の各メンバーについて決定できる主な情報は、次のとおりです。
  • メンバーのIPアドレス

  • メンバーがクラスタに参加した日付/時刻

たとえば、クラスタに4つのサーバーがあり、各サーバーでアプリケーションのコピー(インスタンス)が1つ実行されていて、アプリケーションの4つのインスタンスすべてがクラスタ化されているとします。この場合、そのクラスタは4つのメンバーで構成されます。アプリケーションでは、次のようにClusterオブジェクトからローカルのMemberを確認できます。

Member memberThis = cluster.getLocalMember();

また、Clusterオブジェクトから、クラスタ・メンバーの全体セットを確認することもできます。

Set setMembers = cluster.getMemberSet();

ServiceInfoオブジェクトで、そのサービスに参加しているクラスタ・メンバー・セットを確認できます。

ServiceInfo info = cluster.getServiceInfo(sName);
Set setMembers = info.getMemberSet();

メンバー・イベントのリスニング

アプリケーションは、クラスタおよびサービスのイベントをリスニングして、メンバーシップの変更を判断できます。アプリケーションはMemberListenerインタフェース府を実装する必要があります(例8-1を参照)。その後、リスナー・クラスは、addMemberListenerメソッドを使用するか、キャッシュ・スキーム定義に<member-listener>要素を追加することによって、サービスに追加されます。

プログラムを使用する方法と比較して、構成を使用する方法には次の2つの利点があります。第1に、プログラムを使用した場合は、実行中のサービスにのみリスナーを追加できます。そのため、最初のMEMBER_JOINEDイベントが見逃されます。第2に、対応するサービスを実行するすべてのクラスタ・ノードのそれぞれで、addMemberListenerコールを発行する必要があります。構成による方法では、これら両方の問題が解決されます。

次の例では、addMemberListenerメソッドを使用して、サービスにMyMemberListenerという名前のリスナー実装を追加します。

Service service = cache.getCacheService();
service.addMemberListener(package.MyMemberListener);

このサービスは、名前で検索することもできます。

Service service = cluster.getService(sName);
service.addMemberListener(package.MyMemberListener);

次の例では、<member-listener>要素を分散キャッシュ・スキーム定義に追加することによって、MyMemberListenerという名前のリスナー実装をDistributedCacheという名前のサービスに追加します。

<distributed-scheme>
   <scheme-name>example-distributed</scheme-name>
   <service-name>DistributedCache</service-name>
   <member-listener>
      <class-name>package.MyMemberListener</class-name>
   </member-listener>
   <backing-map-scheme>
      <local-scheme>
         <scheme-ref>example-binary-backing-map</scheme-ref>
      </local-scheme>
   </backing-map-scheme>
   <autostart>true</autostart>
</distributed-scheme>

<member-listener>要素は、<distributed-scheme><replicated-scheme><optimistic-scheme><invocation-scheme>および<proxy-scheme>の各要素で使用できます。キャッシュ構成の要素を参照してください。

ノート:

<member-listener>要素を使用してリスナーをサービスに追加する場合は、MemberListener実装にパブリック・デフォルト・コンストラクタが必要です。

例8-1は、受信したすべてのメンバーシップ・イベントを出力するMemberListener実装を示しています。

例8-1 MemberListener実装のサンプル

public class MemberEventPrinter
        extends Base
        implements MemberListener
    {
    public void memberJoined(MemberEvent evt)
        {
        out(evt);
        }

    public void memberLeaving(MemberEvent evt)
        {
        out(evt);
        }

    public void memberLeft(MemberEvent evt)
        {
        out(evt);
        }
    }

MemberEventオブジェクトは、イベント・タイプ(MEMBER_JOINEDMEMBER_LEAVINGまたはMEMBER_LEFT)、イベントを生成したメンバー、およびイベントのソースとして動作するサービスについての情報を保持します。また、イベントにはisLocal()メソッドが用意されており、これは対象のメンバーがクラスタに参加または離脱しようとしていることをアプリケーションに示します。これは、障害の発生後にアプリケーションがクラスタに自動的に参加しなおす、ソフトな再起動の認識に役立ちます。

ノート:

CacheFactory.shutdown()メソッドをコールすると、すべてのリスナーが登録解除されます。その場合、MEMBER_LEAVINGMEMBER_LEFTの両方のイベントが送信されます。その他の原因でメンバーが終了した場合は、MEMBER_LEFTイベントのみが送信されます。

例8-2は、MemberEventオブジェクトでカプセル化された情報の使用方法を示しています。

例8-2 MemberEventオブジェクトのイベント・タイプ情報の使用

public class RejoinEventPrinter
        extends Base
        implements MemberListener
    {
    public void memberJoined(MemberEvent evt)
        {
        if (evt.isLocal())
            {
            out("this member just rejoined the cluster: " + evt);
            }
        }

    public void memberLeaving(MemberEvent evt)
        {
        }

    public void memberLeft(MemberEvent evt)
        {
        }
    }