ヘッダーをスキップ
Oracle Coherence開発者ガイド
リリース3.5
B56039-01
  目次
目次

戻る
戻る
 
次へ
次へ
 

N Coherence Extendのベスト・プラクティス

この章では、Coherence*Extendの構成および実行のベスト・プラクティスについて説明します。この章は次の各項で構成されています。

ローカル記憶域を無効にしてプロキシ・サーバーを実行する

プロキシ・サーバーも含めて、パーティション・キャッシュ内の各サーバーには、データの一部を格納できます。プロキシ・サーバーは、クライアント(Java、C++、.NETのいずれか)からPOF形式のデータを受け入れ、そのPOFデータをデシリアライズしてJavaオブジェクトを取得し、Javaオブジェクトをシリアライズしてから結果のデータをクラスタに置く処理を担当します。これらのタスクでは、CPUとメモリーの面でコストが高くなることがあります。プロキシ・サーバーのローカル記憶域を無効にすることによって、サーバーのリソースを保持できます。

記憶域を無効にするには、次のような方法が使用されます。

Javaプロパティtangosol.coherence.distributed.localstorageを使用して、プロキシ・サーバーのローカル記憶域を有効または無効に設定できます。次に例を示します。

-Dtangosol.coherence.distributed.localstorage=false

また、キャッシュ・コンフィギュレーション・ファイルで記憶域を無効にすることもできます。「distributed-scheme」の<local-storage>要素の説明を参照してください。

さらに、tangosol-coherence.xml(またはtangosol-coherence-override.xml)ファイルの<local-storage>の設定を変更して、プロキシ・サーバーの記憶域を無効にすることもできます。例N-1は、tangosol-coherence-override.xmlファイルで<local-storage>の設定をfalseにする方法を示しています。

例N-1 tangosol-coherence-override.xmlでの記憶域の無効化

<!--
Example using tangosol-coherence-override.xml
-->
<coherence>
  <cluster-config>
    <services>
      <!--
      id value must match what's in tangosol-coherence.xml for DistributedCache service
      -->
      <service id="3">
        <init-params>
          <init-param id="4">
            <param-name>local-storage</param-name>
            <param-value system-property="tangosol.coherence.distributed.localstorage">false</param-value>
          </init-param>
        </init-params>
      </service>
    </services>
  </cluster-config>
</coherence>

プロキシ・サーバーでニア・キャッシュを実行しない

定義上、ニア・キャッシュでは、最近使用されたデータや頻繁に使用されるデータのローカル・キャッシュへのアクセスが提供されます。プロキシ・サーバーでニア・キャッシュが構成されている場合、リモート・クライアントがアクセスするデータがローカル・キャッシュに保存されます。これらのクライアントが同じデータ・サブセットに継続的にアクセスする可能性は低いため、ニア・キャッシュでのヒット率は高くありません。したがって、ニア・キャッシュを使用した場合、プロキシ・ノードのヒープ使用率とネットワーク・トラフィックが増加するばかりで、利点はまったく、またはほとんどありません。このような理由から、プロキシ・サーバーではニア・キャッシュを使用しないことをお薦めします。プロキシ・サーバーでニア・キャッシュが実行されないようにするには、プロキシに使用するキャッシュ・コンフィギュレーションからすべてのニア・スキームを削除します。詳細は、「ニア・キャッシュ」を参照してください。

ヒープNIO領域を最大ヒープ・サイズと同じ値に構成する

NIOメモリーは、プロキシへのTCP接続とPOFのシリアライズおよびデシリアライズに使用されます。以前のJavaインストールでは、ヒープ・メモリーが少なく構成されていたため不足しがちでした。新しいJava JDKでは、ヒープNIO領域が最大ヒープ領域と同じサイズに構成されます。Sun JVMでは、次の値を指定して手動で設定することもできます。

-XX:MaxDirectMemorySize=512M

アプリケーションのニーズに応じてワーカー・スレッドのプール・サイズを設定する

クライアント・アプリケーションは、アクティブとパッシブの2つの一般カテゴリに分類できます。

アクティブ・アプリケーションでは、Coherence*Extendクライアントは、putやgetなどの多数のリクエストをプロキシに送信します。これらのリクエストはプロキシ・サービスによって処理されます。プロキシはキャッシュに書き込むPOFデータをデシリアライズし、クライアントに返すデータをシリアライズします。これらのタスクに対応するため、プロキシ・サービスには、より多くのデーモン(ワーカー)・スレッドを構成するようにします。

パッシブ・アプリケーションでは、クライアントは、特定の基準に基づいてイベント(マップ・リスナーなど)を待ちます。イベントはDistributedCacheサービスによって処理されます。このサービスはワーカー・スレッドを使用してイベントをクライアントにプッシュします。このタスクに対応するため、DistributedCacheサービスのスレッド・プール構成には、十分な数のワーカー・スレッドを確保するようにします。

Extendクライアントのニア・キャッシュでは、ALLPRESENTおよびAUTOの無効化方針に対応して、ひそかにマップ・リスナーが使用されます。書込み量が多く、ニア・キャッシュを使用するアプリケーションでは、多数のマップ・イベントが生成されます。

InvocationServiceをコールするときの注意事項

InvocationServiceを使用すると、サービスのメンバーがクラスタ内の任意のノードで任意のコードを起動できます。ただし、Coherence*Extendでは、InvocationServiceコールは、クライアントがデフォルトで接続されるプロキシによって処理されます。プロキシ経由でコールを送信する場合、コードの実行先とする特定のノードを選択できません。

キャッシュにコレクション・クラスを書き込むときの注意事項

Coherence*Extendクライアントがコレクション・オブジェクト(ArrayListHashSetHashMapなど)をキャッシュに直接書き込む場合、オブジェクトは不変の配列としてデシリアライズされます。次にこのオブジェクトを抽出して元の型にキャストすると、ClassCastExceptionsが返されます。代替策としては、Javaインタフェース・オブジェクト(ListSetMapなど)を使用するか、またはコレクション・オブジェクトを別のオブジェクトにカプセル化します。次の例では、この両方のテクニックを示しています。

例N-2 ArrayListオブジェクトのキャスト

public class ExtendExample
    {
    @SuppressWarnings({ "unchecked" })
    public static void main(String asArgs[])
        {
        System.setProperty("tangosol.coherence.cacheconfig", "client-config.xml");
        NamedCache cache = CacheFactory.getCache("test");

        // Create a sample collection
        List list  = new ArrayList();
        for (int i = 0; i < 5; i++)
            {
            list.add(String.valueOf(i));
            }
        cache.put("list", list);

        List listFromCache = (List) cache.get("list");

        System.out.println("Type of list put in cache: " + list.getClass());
        System.out.println("Type of list in cache: " + listFromCache.getClass());

        Map map = new TreeMap();
        for (Iterator i = list.iterator(); i.hasNext();)
            {
            Object o = i.next();
            map.put(o, o);
            }
        cache.put("map", map);

        Map mapFromCache = (Map) cache.get("map");

        System.out.println("Type of map put in cache: " + map.getClass());
        System.out.println("Type of map in cache: " + mapFromCache.getClass());
        }
    }

スレッド・プールのサイズを大きくするかわりに複数のプロキシを実行する

プロキシはサービス・スレッドでPOF/EL変換を実行します。プロキシ・インスタンスが1つの場合、POF/EL変換が原因で単一コア上でボトルネックが発生しやすくなります。同じボックスで(スレッド・プールのサイズを大きくするかわりに)複数のプロキシ・インスタンスを実行すると、複数のコア間で負荷を分散させることができます。

キャッシュ・サーバーに対してPOFシリアライザを構成する

プロキシ・サーバーが実行するタスクの1つは、POFデータをJavaオブジェクトにデシリアライズすることです。C++または.NETのアプリケーションを実行してデータをキャッシュに格納する場合、Javaオブジェクトへの変換が不要な手順に思えることがあります。現在のリリースのCoherenceでは、キャッシュ・サーバーに対してPOFシリアライザを構成するオプションがあります。その効果として、POF形式のデータがキャッシュに直接格納されるようになります。

これによって、アプリケーションに次の影響が及ぶ可能性があります。

例N-3は、分散キャッシュに対してPOFシリアライザを構成するexample-pof-server.xmlの抜粋です。このトピックには、完全なPOFコンフィギュレーション・ファイルの例が付属しています。

例N-3 分散キャッシュに対するPOFシリアライザの構成

...
    <distributed-scheme>
      <scheme-name>dist-default</scheme-name>

      <serializer>
                <class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name>
                <init-params>
                  <init-param>
                        <param-type>string</param-type>
                        <param-value>custom-types-pof-config.xml</param-value>
                  </init-param>
                </init-params>
          </serializer>

      <backing-map-scheme>
        <local-scheme/>
      </backing-map-scheme>

      <autostart>true</autostart>
    </distributed-scheme>
...

スレッドのロックでなくノードのロックを使用する

Coherence*Extendクライアントは、lock、putおよびunlockのリクエストをクラスタに送信できます。ロックはクライアントにかわってプロキシが保持します。ロックおよびロック解除のリクエストは、スレッド・レベルまたはノード・レベルで発行できます。スレッド・レベルのロックでは、プロキシに属する特定のスレッド・インスタンス(スレッド1など)が、lockリクエストを発行します。他のスレッド(スレッド3など)がunlockリクエストを発行しても、無視されます。unlockリクエストが正常に処理されるのは、最初のlockリクエストを発行したスレッドによって発行された場合のみです。この場合、unlockリクエストは、そのロック解除リクエストを受け取るスレッドと元のロックを発行したスレッドが同じでないかぎり正常に処理されないため、アプリケーション・エラーが発生する可能性があります。

ノード・レベルのロックでは、プロキシに属する特定のスレッド(スレッド1など)がlockリクエストを発行した場合、他のスレッド(スレッド3など)もunlockリクエストを正常に発行できます。

Coherenceでは、ロックを使用するかわりにEntryProcessor APIを使用することをお薦めします。EntryProcessorについては、第2章「トランザクション、ロックおよび並行性の実装」で説明します。