プライマリ・コンテンツに移動
Oracle® Fusion Middleware Oracle Coherenceリモート・クライアントの開発
12c (12.1.3)
E56210-03
  ドキュメント・ライブラリへ移動
ライブラリ
製品リストへ移動
製品
目次へ移動
目次

前
 
次
 

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

この章では、Coherence*Extendの構成および実行のベスト・プラクティスとガイドラインについて説明します。

この章には次の項が含まれます:

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

プロキシ・サーバーも含めて、パーティション・キャッシュ内の各サーバーには、データの一部を格納できます。ただし、プロキシ・サーバーには予測できない潜在的クライアントの処理負荷を管理するための負荷が加わり、その負荷はCPUやメモリーの使用率を大きく消費する可能性があります。プロキシ・サーバーではリソースを維持するためにローカル記憶域を無効にする必要があります。

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

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

-Dtangosol.coherence.distributed.localstorage=false

<local-storage要素を使用してキャッシュ構成ファイルの記憶域を無効にすることもできます。詳細は、『Oracle Coherenceでのアプリケーションの開発』を参照してください。

すべてのプロキシ・サービス・インスタンスの記憶域を無効にするには、tangosol-coherence-override.xmlファイルにある<local-storage>設定を変更してください。例5-1は、<local-storage>falseに設定する方法を示しています。

例5-1 記憶域の無効化

<?xml version='1.0'?>

<coherence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xmlns="http://xmlns.oracle.com/coherence/coherence-operational-config"
   xsi:schemaLocation="http://xmlns.oracle.com/coherence/
   coherence-operational-config coherence-operational-config.xsd">
   <cluster-config>
      <services>
         <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>

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

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

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

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

-XX:MaxDirectMemorySize=MAX_HEAP_SIZE

5.4 Proxyサービスのスレッド・プールの構成

プロキシ・サービスは、デーモン(ワーカー)スレッドの動的なスレッド・プールを使用します。スレッド・プールは、クライアント・リクエストの数、リクエストのバックログの合計数およびアイドル・スレッドの合計数を基に自動的にスレッドの追加や削除を実行します。スレッド・プールは、Extendクライアントのリクエストを満たす十分なスレッドを確保し、リソースがアイドル・スレッドによって無駄に使用されないようにするために役立ちます。スレッド・プールのデフォルト設定を変更することで、クライアントのパフォーマンスを最適化できます。

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

5.4.1 Proxyサービスのスレッドの理解

それぞれのアプリケーションのスレッドの要件は、クライアント数と実行中の処理の量に応じて異なります。パフォーマンスを綿密にモニターして、クライアント・リクエストに十分対応するスレッドを確保し、さらにクライアントがスレッドで飽和しないようにします。さらに、スレッド・プールで最大数のスレッドが使用されているときにはログ・メッセージが発行されます。このメッセージによって、追加のスレッドが必要であることを認識できます。

クライアント・アプリケーションは、アクティブ・アプリケーションとパッシブ・アプリケーションの2つの一般カテゴリに分類できます。アクティブなアプリケーションでは、Extendクライアントが多数のリクエスト(PUT、GETなど)を送信し、それらがProxyサービスによって処理されます。Proxyサービスが、これらの多数のタスクを十分に処理するためには大量のスレッドを必要とします。

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


注意:

Extendクライアントのニア・キャッシュでは、ALLPRESENTおよびAUTOの無効化戦略を実行する場合にマップ・リスナーが使用されます。書込み量が多く、ニア・キャッシュを使用するアプリケーションでは、多数のマップ・イベントが生成されます。

5.4.2 Proxyサービスのスレッド・プールのしきい値の設定

デフォルトのスレッド・プールの動作では、コア数の2倍と等しいスレッドの量から始まり、コア数の4倍の最大スレッド量まで増やされます。構成済の最大値に達するとログ・メッセージが発行されます。

スレッド・プールは、スレッドの減少量を上回るスレッドを積極的に作成します。クライアントのリクエストやサービスのブロックが増加すると、追加のスレッドが0.5秒ごとに作成されます。アイドル状態になったスレッドが多すぎる場合は、60秒ごとにスレッドがスレッド・プールから削除されます。

プロキシ・サービスにスレッド・プールのしきい値を設定するには、<proxy-scheme要素内に<thread-count-maxおよび<thread-count-min要素を追加します。これらの要素の詳細なリファレンスは、『Oracle Coherenceでのアプリケーションの開発』を参照してください。次の例は、新しいデフォルト・プール設定を変更します。


注意:

  • 動的なスレッド・プールのサイズ設定を有効にするには、プロキシ・サービスに<thread-count>要素を設定しないでください。

  • 最小および最大スレッド件数をゼロに設定すると、プロキシ・サービスのスレッドがすべてのリクエストを処理するように強制され、ワーカー・スレッドは使用されません。プロキシ・サービス・スレッドを使用してクライアントのリクエストを処理することはお薦めできません。


<proxy-scheme>
   <service-name>ExtendTcpProxyService</service-name>
   <thread-count-max>75</thread-count-max>
   <thread-count-min>10</thread-count-min>
   <acceptor-config>
      <tcp-acceptor>
         <local-address>
            <address>localhost</address>
            <port>9099</port>
         </local-address>
      </tcp-acceptor>
   </acceptor-config>
   <autostart>true</autostart>
</proxy-scheme>

tangosol.coherence.proxy.threads.maxおよびtangosol.coherence.proxy.threads.minシステム・プロパティは、キャッシュ構成ファイルを使用するかわりに、動的なスレッド・プールのしきい値を指定します。例:

-Dtangosol.coherence.proxy.threads.max=75
-Dtangosol.coherence.proxy.threads.min=10

5.4.3 正確なスレッド数の設定

ほとんどの用途で、プロキシ・サービスがリクエストを処理するための十分なスレッドを確保にするには、動的なスレッド・プール設定が最も適しています。クライアントの用途が明確な適切に制御されたアプリケーションでは、<thread-count>要素を使用してスレッド数を明示的に指定できます。次の例では、プロキシ・サービス用に10スレッドを設定します。追加のスレッドは自動的には作成されません。

<proxy-scheme>
   <service-name>ExtendTcpProxyService</service-name>
   <thread-count>10</thread-count>
   <acceptor-config>
      <tcp-acceptor>
         <local-address>
            <address>localhost</address>
            <port>9099</port>
         </local-address>
      </tcp-acceptor>
   </acceptor-config>
   <autostart>true</autostart>
</proxy-scheme>

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

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

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

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

例5-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());
        }
    }

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

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

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

  • putまたはgetの操作のみを実行する.NETまたはC++のクライアントでは、Javaバージョンのオブジェクトは不要です。(入力プロセッサやキャッシュ・ストアなどのために)サーバー側でデシリアライズが実行される場合、Javaバージョンは必要です。

  • POFシリアライザを使用することで、プロキシでシリアライズ/デシリアライズを実行する必要がなくなるため、メモリーとCPUの要件が小さくなります。

例5-3は、オペレーション・デプロイメント・ディスクリプタで定義されるデフォルトのPOFシリアライザを構成する、キャッシュ構成ファイルの抜粋を示しています。

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

...
<distributed-scheme>
   <scheme-name>dist-default</scheme-name>
   <serializer>pof</serializer>
   <backing-map-scheme>
      <local-scheme/>
   </backing-map-scheme>
   <autostart>true</autostart>
</distributed-scheme>
...

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


注意:

NamedCacheロックAPIは非推奨です。入力プロセッサAPI (JavaおよびC++用のEntryProcessor、および.NET用のIEntryProcessor)で提供されるロック・サポートをかわりに使用してください。

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

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