この章は次の各項で構成されています。
シリアライズはオブジェクトをバイナリ形式にエンコードするプロセスです。これは、データをネットワークで転送する必要がある際にCoherenceで処理するための重要コンポーネントです。Portable Object Format(POF)は言語に依存しないバイナリ形式です。POFでは領域と時間の両面で効率が向上するように設計され、Coherenceにおける処理の基礎となる要素です。POFのバイナリ・ストリームの詳細は、『Oracle Coherence開発者ガイド』の「PIF-POFバイナリ形式」を参照してください。POF APIの使用法の詳細は、「Portable Object Fromatの使用」を参照してください。
標準的なJavaシリアライズ、POF、独自のカスタム・シリアライズ・ルーチンなどのシリアライズに対して使用可能なオプションがあります。各オプションには独自のトレードオフがあります。標準的なJavaシリアライズは、簡単に実装でき、循環オブジェクト・グラフをサポートし、オブジェクトのIDを保持します。残念ながら、これは処理に比較的時間がかかり、詳細なバイナリ形式があり、使用はJavaオブジェクトにのみ限定されています。
しかし、Portable Object Formatには次の利点があります。
Java、.NETおよびC++における現在のサポートから独立した言語です。
非常に効率的で、String、longおよび3つのintのある簡単なテスト・クラスでは、シリアライズやデシリアライズが7倍高速に処理され、標準のJavaシリアライズに比べて1/6のサイズでバイナリが生成されました。
バージョニングが可能で、オブジェクトは進化でき、上位互換性および下位互換性があります。
シリアライズ・ロジックを外部化する機能をサポートしています。
索引付けにより、オブジェクト全体をデシリアライズせずに値を抽出できます。
POFには、オブジェクトのシリアライズおよびデシリアライズの方法を認識するシリアライズ・ルーチンを実装する必要があります。これを行うには、次の2つの方法があります。
オブジェクトにcom.tangosol.io.pof.PortableObjectインタフェースを実装する方法
com.tangosol.io.pof.PofSerializerインタフェースを使用して、オブジェクトに対するシリアライザを実装する方法
PortableObjectインタフェースは、次の2つのメソッドで構成された単純なインタフェースです。
public void readExternal(PofReader reader)
public void writeExternal(PofWriter writer)
前述のとおり、POF要素は索引付けされます。これを実現するには、POFストリームで書き込んだり読み込む各要素に数値の索引を指定します。これらの索引はPOFストリームで書き込んだり読み込む各要素に対して一意である必要があることに注意してください。特に、索引はスーパークラスと派生クラス間で一意である必要があるため、関連するタイプを派生した場合には注意してください。
例16-1は、PortableObjectインタフェース実装の簡単な例です。
図16-1 PortableObjectインタフェースの実装
public void readExternal(PofReader in)
throws IOException
{
m_symbol = (Symbol) in.readObject(0);
m_ldtPlaced = in.readLong(1);
m_fClosed = in.readBoolean(2);
}
public void writeExternal(PofWriter out)
throws IOException
{
out.writeObject(0, m_symbol);
out.writeLong(1, m_ldtPlaced);
out.writeBoolean(2, m_fClosed);
}
PofSerializerインタフェースを使用すると、シリアライズするクラスからシリアライズ・ロジックを外部化できます。これは、クラスの構造を変更しないでPOFおよびCoherenceを処理する場合に特に便利です。PofSerializerインタフェースは、次の2つのメソッドでも構成されています。
public Object deserializer(PofReader in)
public void writeObject(PofWriter out, Object o)
PortableObjectインタフェースでは、POFストリームで書き込んだり読み込むすべての要素に一意の索引を指定する必要があります。PofSerializerインタフェースの実装例は、次のとおりです。
例16-2 PofSerializerインタフェースの実装
public Object deserialize(PofReader in)
throws IOException
{
Symbol symbol = (Symbol)in.readObject(0);
long ldtPlaced = in.readLong(1);
bool fClosed = in.readBoolean(2);
// mark that we're done reading the object
in.readRemainder(null);
return new Trade(symbol, ldtPlaced, fClosed);
}
public void serialize(PofWriter out, Object o)
throws IOException
{
Trade trade = (Trade) o;
out.writeObject(0, trade.getSymbol());
out.writeLong(1, trade.getTimePlaced());
out.writeBoolean(2, trade.isClosed());
// mark that we're done writing the object
out.writeRemainder(null);
}
POFの索引をオブジェクトの属性に割り当てる場合、次の事項に注意してください。
読取りおよび書込みの順序: シリアライズ・ルーチンの最小索引値から処理を始め、最高索引値で終了します。値をデシリアライズする際に、書き込んだときと同じ順序で読み取ります。
不連続の索引を指定できますが、読取りや書込みは順番に実行する必要があります。
サブクラスに索引の範囲が予約されている場合: 索引は派生したタイプ全体で累積されます。たとえば、各派生タイプはそのスーパークラスによって予約されたPOF索引範囲を認識する必要があります。
索引には別の目的を指定できない: 進化可能のサポートが必要な場合、クラスの補正で属性の索引に別の目的を指定しないでください。
索引のラベル付け: public static final intを使用して索引にラベル付けすると、特にPofExtractorおよびPofUpdaterを使用する場合には、オブジェクトの処理が非常に容易になります。索引にラベル付けすると、前述の順序で読取りと書込みが行われていることを確認できます。
CoherenceではConfigurablePofContextクラスが用意されています。このクラスは、POFのシリアライズされたオブジェクトを適切なシリアライズ・ルーチンにマッピングします(PortableObjectインタフェースを介したコールまたはPofSerializerにより)。各クラスには、オプションのPofSerializerへマッピングできるPOFにおいて一意のtype-idが指定されます。クラスにシリアライズ・ルーチンを指定すると、それらのクラスをConfigurablePofContextに登録する必要があります。POF構成ファイルを使用してConfigurablePofContextにカスタムのユーザー定義型が登録されます。これは、<user-type-list>要素を持つXMLファイルです。この要素には、PortableObjectを実装したり、PofSerializerをそれらのクラスに関連付けるクラスのリストを記述します。各クラスのtype-idは一意である必要があり、クラスタ・インスタンス全体(Extendクライアントを含む)で一致している必要があります。
pof-config.xmlファイルの例は、次のようになります。
<pof-config>
<user-type-list>
<include>coherence-pof-config.xml</include>
...
<!-- User types must be above 1000 -->
<user-type>
<type-id>1001</type-id>
<class-name>com.examples.MyTrade</class-name>
<serializer>
<class-name>com.examples.MyTradeSerializer</class-name>
</serializer>
</user-type>
<user-type>
<type-id>1002</type-id>
<class-name>com.examples.MyPortableTrade</class-name>
</user-type>
...
</pof-config>
|
注意: Coherenceには、最初の1000個のtype-idが内部使用に予約されています。詳しく調べると、user-type-listにはcoherence-pof-config.xmlファイルが含まれています。ここにCoherence固有のユーザー定義型が定義されており、これにはすべてのPOF構成ファイルが含まれます。 |
POFの使用を開始するには、ConfigurablePofContextを使用するための各サービスも構成する必要があります。これを実現するには、キャッシュ構成ファイル内のキャッシュ・スキームの<serializer>要素を使用します。ConfigurablePofContextには、POF構成ファイルをポイントしている<init-param>に基づく文字列が指定されます。
POFを使用するために構成された分散キャッシュ・スキームの例は、次のとおりです。
<distributed-scheme>
<scheme-name>example-distributed</scheme-name>
<service-name>DistributedCache</service-name>
<serializer>
<class-name>com.tangosol.io.pof.ConfigurablePofContext</class-name>
<init-params>
<init-param>
<param-value>my-pof-config.xml</param-value>
<param-type>String</param-type>
</init-param>
</init-params>
</serializer>
...
</distributed-scheme>
または、JVMインスタンス全体を構成して、次のシステム・プロパティによりPOFを使用できます。
tangosol.pof.enabled=true: JVMインスタンス全体のPOFを有効にします。
tangosol.pof.config=CONFIG_FILE_PATH: 使用するPOF構成ファイルへのパスです。これがクラス・パスに指定されていない場合、ファイル・リソース(例: file:///opt/home/coherence/mycustom-pof-config.xml)として存在する必要があることに注意してください。
POFの使用には、パフォーマンス上の利点から言語の非依存性にいたるまでの多くの利点があります。Coherenceにおける処理の際には、シリアライズ・ソリューションとしてPOFを詳細に調べることをお薦めします。C++におけるPOFの処理方法は、『Oracle Coherenceクライアント・ガイド』の「C++クライアントの統合オブジェクトの構築」を参照してください。.NETにおけるPOFの処理方法は、『Oracle Coherenceクライアント・ガイド』の「.NETクライアントの統合オブジェクトの構築」を参照してください。