この章では、Coherence*Extendの構成および実行のベスト・プラクティスについて説明します。この章は次の各項で構成されています。
プロキシ・サーバーも含めて、パーティション・キャッシュ内の各サーバーには、データの一部を格納できます。ただし、プロキシ・サーバーには予測できない潜在的クライアントの処理負荷を管理するための負荷が加わり、その負荷はCPUやメモリーの使用率を大きく消費する可能性があります。プロキシ・サーバーではリソースを維持するためにローカル記憶域を無効にする必要があります。
記憶域を無効にするには、次のような方法が使用されます。
Javaプロパティtangosol.coherence.distributed.localstorage
を使用して、プロキシ・サーバーのローカル記憶域を有効または無効に設定できます。例:
-Dtangosol.coherence.distributed.localstorage=false
また、キャッシュ構成ファイルで記憶域を無効にすることもできます。<local-storage>
要素の詳細は、『Oracle Coherence開発者ガイド』のdistributed-schemeに関する項を参照してください。
さらに、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>
定義上、ニア・キャッシュでは、最近使用されたデータと頻繁に使用されるデータの両方のローカル・キャッシュへのアクセスが提供されます。プロキシ・サーバーでニア・キャッシュが構成されている場合、リモート・クライアントがアクセスするデータがローカル・キャッシュに保存されます。これらのクライアントが同じデータ・サブセットに継続的にアクセスする可能性は低いため、ニア・キャッシュでのヒット率は高くありません。プロキシ・サーバーでニア・キャッシュを実行した場合、プロキシ・ノードのヒープ使用率とネットワーク・トラフィックが増加するばかりで、利点はまったくないかほとんどありません。このような理由から、プロキシ・サーバーではニア・キャッシュを使用しないことをお薦めします。プロキシ・サーバーでニア・キャッシュが実行されないようにするには、プロキシに使用するキャッシュ構成からすべてのニア・スキームを削除します。
NIOメモリーは、プロキシへのTCP接続とPOFのシリアライズおよびデシリアライズに使用されます。以前のJavaインストールでは、ヒープ・メモリーが少なく構成されていたため不足しがちでした。新しいJava JDKでは、ヒープNIO領域が最大ヒープ領域と同じサイズに構成されます。Sun JVMでは、次の値を指定して手動で設定することもできます。
-XX:MaxDirectMemorySize=512M
クライアント・アプリケーションは、アクティブとパッシブの2つの一般カテゴリに分類できます。
アクティブ・アプリケーションでは、Coherence*Extendクライアントは、putやgetなどの多数のリクエストをプロキシに送信します。これらのリクエストはプロキシ・サービスによって処理されます。プロキシはキャッシュに書き込むPOFデータをデシリアライズし、クライアントに返すデータをシリアライズします。これらのタスクに対応するため、プロキシ・サービスには、より多くのデーモン(ワーカー)・スレッドを構成するようにします。
パッシブ・アプリケーションでは、クライアントは、特定の基準に基づいてイベント(マップ・リスナーなど)を待ちます。イベントはDistributedCacheサービスによって処理されます。このサービスはワーカー・スレッドを使用してイベントをクライアントにプッシュします。このタスクに対応するため、DistributedCacheサービスのスレッド・プール構成には、十分なワーカー・スレッドを確保するようにします。
Extendクライアントのニア・キャッシュでは、ALL
、PRESENT
およびAUTO
の無効化方針に対応して、ひそかにマップ・リスナーが使用されます。書込み量が多く、ニア・キャッシュを使用するアプリケーションでは、多数のマップ・イベントが生成されます。
InvocationServiceを使用すると、サービスのメンバーがクラスタ内の任意のノードで任意のコードを起動できます。ただし、Coherence*Extendでは、InvocationServiceコールは、クライアントがデフォルトで接続されるプロキシによって処理されます。プロキシ経由でコールを送信する場合、コードの実行先とする特定のノードを選択できません。
Coherence*Extendクライアントがコレクション・オブジェクト(ArrayList
、HashSet
、HashMap
など)をキャッシュに直接書き込む場合、オブジェクトは不変の配列としてデシリアライズされます。次にこのオブジェクトを抽出して元の型にキャストすると、ClassCastExceptions
が返されます。代替策としては、Javaインタフェース・オブジェクト(List
、Set
、Map
など)を使用するか、またはコレクション・オブジェクトを別のオブジェクトにカプセル化します。次の例では、この両方のテクニックを示しています。
例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()); } }
プロキシ・サーバーは、POFデータをJavaオブジェクトにデシリアライズする処理を担当します。C++または.NETのアプリケーションを実行してデータをキャッシュに格納する場合、Javaオブジェクトへの変換が不要な手順に思えることがあります。現在のリリースのCoherenceでは、キャッシュ・サーバーに対してPOFシリアライザを構成するオプションがあります。
これによって、アプリケーションに次の影響が及ぶ可能性があります。
putまたはgetの操作のみを実行する.NETまたはC++のクライアントでは、Javaバージョンのオブジェクトは不要です。(入力プロセッサやキャッシュ・ストアなどのために)サーバー側でデシリアライズが実行される場合、Javaバージョンは必要です。
POFシリアライザを使用することで、プロキシでシリアライズ/デシリアライズを実行する必要がなくなるため、メモリーとCPUの要件が小さくなります。
例5-3は、オペレーション・デプロイメント・ディスクリプタで定義されるデフォルトのPOFシリアライザを構成する、キャッシュ構成ファイルの抜粋を示しています。
Coherence*Extendクライアントは、lock、putおよびunlockのリクエストをクラスタに送信できます。ロックはクライアントにかわってプロキシが保持します。ロックおよびロック解除のリクエストは、スレッド・レベルまたはノード・レベルで発行できます。スレッド・レベルのロックでは、プロキシに属する特定のスレッド・インスタンス(スレッド1など)が、lockリクエストを発行します。他のスレッド(スレッド3など)がunlockリクエストを発行しても、無視されます。unlockリクエストが正常に処理されるのは、最初のlockリクエストを発行したスレッドによって発行された場合のみです。この場合、unlockリクエストは、そのロック解除リクエストを受け取るスレッドと元のロックを発行したスレッドが同じでないかぎり正常に処理されないため、アプリケーション・エラーが発生する可能性があります。
ノード・レベルのロックでは、プロキシに属する特定のスレッド(スレッド1など)がlockリクエストを発行した場合、他のスレッド(スレッド3など)もunlockリクエストを正常に発行できます。
Coherenceでは、ロックを使用するかわりにEntryProcessor
APIを使用することをお薦めします。