第20章 リモートクエリー
20.1. リモートクエリー リンクのコピーリンクがクリップボードにコピーされました!
Red Hat JBoss Data Gird の Hot Rod プロトコルは、 Infinispan Query Domain-specific Language (DSL)または Ickle (JP-QL のサブセット) のいずれかを使用して、リモートの言語中立のクエリーを実現します。どちらを使用した場合でも、リモートの言語中立のクエリーを実行でき、Hot Rod クライアントで現在使用可能なすべての言語に実装できます。
Infinispan Query Domain-specific Language (DSL)
JBoss Data Grid は、内部の DSL を基に独自のクエリー言語を使用します。Infinispan DSL は簡単にクエリーを作成できる方法を提供し、基盤のクエリーメカニズムには依存しません。Infinispan Aquery DSL の詳細情報は Infinispan Query DSL を参照してください。
Ickle
Ickle は、フルテキストおよびリレーショナル検索を実行できる文字別ベースのクエリー言語です。Ickleの詳細は、Building a Query using Ickle, the JP-QL API を参照してください。
Protobuf エンコーディング
Google の Protocol Buffers は、データの保存およびクエリーのエンコーディング形式として使用されます。Infinispan Query DSL は、Protobuf マーシャラーを使用するよう設定された Hot Rod クライアント経由でリモートで使用できます。Protocol Buffers は、キャッシュエントリーの保存とマーシャリングの共通形式を採用するために使用されます。保存されたエンティティーのインデックス化およびクエリーが必要なリモートクライアントは、Protobuf エンコーディング形式を使用する必要があります。また、インデックス化が必要でない場合はインデックス化を有効にせずにプラットフォームの独立性を確保して Protobuf エンティティーを保存することも可能です。
20.2. クエリーの比較 リンクのコピーリンクがクリップボードにコピーされました!
ライブラリーモードでは、Lucene クエリーベースのクエリーと DSL クエリーの両方を利用できます。リモートクライアントサーバーモードでは、DSL を使用したリモートクエリーのみを使用できます。以下の表は、Lucene クエリーベースのクエリー、Infinispan Query DSL、およびリモートクエリーを比較しています。
機能 | ライブラリーモード/Lucene クエリー | ライブラリーモード/DSL クエリー | リモートクライアントサーバーモード/DSL クエリー | ライブラリーモード/Ickle クエリー | リモートクライアントサーバーモード/Ickle クエリー |
---|---|---|---|---|---|
インデックス化 |
必須 |
任意、しかし強く推奨 |
任意、しかし強く推奨 |
任意、しかし強く推奨 |
任意、しかし強く推奨 |
インデックスの内容 |
選択されたフィールド |
選択されたフィールド |
選択されたフィールド |
選択されたフィールド |
選択されたフィールド |
データストレージ形式 |
Java オブジェクト |
Java オブジェクト |
Protocol Buffers |
Java オブジェクト |
Protocol Buffers |
キーワードクエリー |
可 |
不可 |
不可 |
可 |
可 |
範囲クエリー |
可 |
可 |
可 |
可 |
可 |
ファジークエリー |
可 |
不可 |
不可 |
可 |
可 |
ワイルドカード |
可 |
like クエリーに限定 (JPA ルールに従うワイルドカードパターンと一致) |
like クエリーに限定 (JPA ルールに従うワイルドカードパターンと一致) |
可 |
可 |
フレーズクエリー |
可 |
不可 |
不可 |
可 |
可 |
クエリーの組み合わせ |
AND、OR、NOT、SHOULD |
AND、OR、NOT |
AND、OR、NOT |
AND、OR、NOT |
AND、OR、NOT |
結果のソート |
可 |
可 |
可 |
可 |
可 |
結果のフィルター |
可 (クエリー内および先頭に追加された演算子) |
クエリー内 |
クエリー内 |
クエリー内 |
クエリー内 |
結果のページネーション |
可 |
可 |
可 |
可 |
可 |
継続的クエリー |
不可 |
可 |
可 |
不可 |
不可 |
クエリーの集約操作 |
不可 |
可 |
可 |
可 |
可 |
20.3. Hot Rod Java クライアント経由のリモートクエリーの実行 リンクのコピーリンクがクリップボードにコピーされました!
RemoteCacheManager
が Protobuf マーシャラーと設定された後、Hot Rod 上のリモートクエリーを有効にできます。
以下の手順では、キャッシュでのリモートクエリーを有効にする方法を説明します。
前提条件
Protobuf マーシャラーを使用するよう、RemoteCacheManager
を設定する必要があります。
Hot Rod 経由のリモートクエリーの有効化
infinispan-remote.jar の追加
infinispan-remote.jar は uberjar であるため、この機能に必要な他の依存関係はありません。
キャッシュ設定でのインデックス化の有効化
リモートクエリーでは、インデックス化は必須ではありませんが、大量のデータが含まれるキャッシュでの検索が大幅に高速化されるため、強く推奨されます。インデックス化はいつでも設定できます。インデックス化の有効化や設定は、Library モードと同じです。
Infinispan サブシステム要素内にある
cache-container
要素内に以下の設定を追加します。Copy to Clipboard Copied! Toggle word wrap Toggle overflow Protobuf スキーマ定義ファイルの登録
Protobuf スキーマ定義ファイルを登録するには、これらのファイルを
___protobuf_metadata
システムキャッシュに追加します。キャッシュキーはファイル名を意味する文字列で、値は文字列としての .proto ファイルです。この代わりに、サーバーのProtobufMetadataManager
MBean のregisterProtofile
メソッドを呼び出して Protobuf スキーマを登録することもできます。キャッシュコンテナーごとにこの MBean の 1 つのインスタンスがあり、___protobuf_metadata
によってサポートされるため、この 2 つの方法は同等です。___protobuf_metadata
システムキャッシュ経由で Protobuf スキーマを提供する例は、 Protocol Buffers スキーマファイルの登録 を参照してください。注記___protobuf_metadata
キャッシュへの書き込みには、書き込みを実行するユーザーに ___schema_manager ロールを追加する必要があります。以下の例は、
ProtobufMetadataManager
MBean のregisterProtofile
メソッドを呼び出す方法を表しています。JMX での Protobuf スキーマ定義ファイルの登録
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
結果
キャッシュに置かれたすべてのデータは、インデックス化が使用されているかどうかに関わらず、即座に検索可能になります。埋め込みクエリーのように、エントリーにアノテーションを付ける必要はありません。エンティティークラスは Java クラスのみに意味があり、サーバー側には存在しません。
リモートのキューが有効になったら、以下を使用して QueryFactory
を取得できます。
QueryFactory
の取得
これで、ライブラリーモードと同様にクエリーを Hot Rod 上で実行できるようになります。
20.4. Hot Rod C++ クライアントでのリモートクエリー リンクのコピーリンクがクリップボードにコピーされました!
Hot Rod C++ クライアントでリモートクエリーを使用する手順は、Hot Rod C++ クライアントを用いたリモートクエリーの実行を参照してください。
20.5. Hot Rod C# クライアントでのリモートクエリー リンクのコピーリンクがクリップボードにコピーされました!
Hot Rod C# クライアントでリモートクエリーを使用する手順は、Hot Rod C# クライアントを用いたリモートクエリーの実行を参照してください。
20.6. Protobuf エンコーディング リンクのコピーリンクがクリップボードにコピーされました!
20.6.1. Protobuf エンコーディング リンクのコピーリンクがクリップボードにコピーされました!
Infinispan Query DSL は Hot Rod 経由で使用できます。これには、Protocol Buffers を使用してキャッシュエントリーの保存およびマーシャリングに共通の形式を採用します。
詳細は、https://developers.google.com/protocol-buffers/docs/overview を参照してください。
20.6.2. Protobuf エンコードされたエンティティーの格納 リンクのコピーリンクがクリップボードにコピーされました!
Protobuf ではデータを構造化する必要があります。これには、.proto ファイルで Protocol Buffer の型を宣言します。
例を以下に示します。
.library.proto
この例では以下が実行されます。
Book
という名前のエンティティーがbook_sample
という名前のパッケージに配置されます。package book_sample; message Book {
package book_sample; message Book {
Copy to Clipboard Copied! Toggle word wrap Toggle overflow エンティティーは、プリミティブ型の複数のフィールドと
authors
という名前の繰り返し可能なフィールドを宣言します。Copy to Clipboard Copied! Toggle word wrap Toggle overflow Author
メッセージインスタンスはBook
メッセージインスタンスに埋め込みされます。message Author { required string name = 1; required string surname = 2; }
message Author { required string name = 1; required string surname = 2; }
Copy to Clipboard Copied! Toggle word wrap Toggle overflow
20.6.3. Protobuf メッセージ リンクのコピーリンクがクリップボードにコピーされました!
Protobuf メッセージに関する重要事項は次のとおりです。
- メッセージを入れ子にすることは可能ですが、結果として構造は常にツリーになり、グラフにはなりません。
- 型の継承はありません。
- コレクションはサポートされませんが、繰り返されるフィールドを使用してアレイを簡単にエミュレートできます。
20.6.4. Hot Rod での Protobuf の使用 リンクのコピーリンクがクリップボードにコピーされました!
Protobuf を JBoss Data Grid の Hot Rod と使用するには、以下の 2 つのステップを使用します。
専用のマーシャラー (ここでは
ProtoStreamMarshaller
) を使用するようクライアントを設定します。このマーシャラーはProtoStream
ライブラリーを使用して、オブジェクトのエンコーディングを手助けします。重要infinispan-remote
jar が使用されていない場合、infinispan-remote-query-client Maven 依存関係を追加してProtoStreamMarshaller
を使用する必要があります。-
エンティティーごとのマーシャラーを登録し、
ProtoStream
ライブラリーにメッセージ型のマーシャル方法を指示します。
ProtoStreamMarshaller
を使用したメッセージのエンコードおよびマーシャル
この例では以下が実行されます。
-
SerializationContext
がProtoStream
ライブラリーによって提供されます。 -
SerializationContext.registerProtofile
メソッドは、メッセージ型の定義が含まれる .proto クラスパスリソースファイルの名前を受信します。 -
RemoteCacheManager
に関連するSerializationContext
が取得され、ProtoStream
は protobuf 型のマーシャルを指示されます。
ProtoStreamMarshaller
を使用するよう設定されていないと、RemoteCacheManager
に関連する SerializationContext
はありません。
20.6.5. エンティティーごとのマーシャラーの登録 リンクのコピーリンクがクリップボードにコピーされました!
リモートクエリーの目的で ProtoStreamMarshaller
を使用する場合、各ドメインモデル型に対してエントリーごとにマーシャラーを登録しないと、マーシャリングに失敗します。マーシャラーの 1 つのインスタンスが使用されるため、ステートレスでスレッドセーフなマーシャラーを作成する必要があります。
以下の例はマーシャラーの書き方を示しています。
BookMarshaller.java
クライアントが設定されたら、リモートキャッシュへの Java オブジェクトの読み書きにはエンティティーマーシャラーが使用されます。関係するすべての型のリモートクライアントでマーシャラーが登録された場合、キャッシュに格納される実際のデータは protobuf でエンコードされます。この例では、Book
と Author
になります。
protobuf 形式で格納されたオブジェクトは、異なる言語で書かれた互換性のあるクライアントと使用することができます。
20.6.6. Protobuf エンコードされたエンティティーのインデックス化 リンクのコピーリンクがクリップボードにコピーされました!
Protobuf を使用するようクライアントが設定されると、サーバー側のキャッシュに対してインデックス化を設定できます。
エントリーをインデックス化するには、サーバーが Protobuf スキーマによって定義されたメッセージ型を認識できなければなりません。Protobuf スキーマファイルは、.proto 拡張子を持つファイルに定義されます。put
、putAll
、putIfAbsent
、または replace
操作を使用してスキーマを ___protobuf_metadata
キャッシュに置くと、スキーマはサーバーに提供されます。この代わりに、JXM 経由で ProtobufMetadataManager
MBean を呼び出し、スキーマをサーバーに提供することもできます。___protobuf_metadata
キャッシュのキーおよび値はともに文字列で、キーはファイル名、値はスキーマファイルの内容になります。
___protobuf_metadata
キャッシュへの書き込みには、書き込みを実行するユーザーに ___schema_manager ロールを追加する必要があります。
Protocol Buffers スキーマファイルの登録
ProtobufMetadataManager
は、Protobuf スキーマ定義または [path].proto ファイルのクラスター全体でレプリケートされたリポジトリーです。実行中のキャッシュマネージャーごとに個別の ProtobufMetadataManager
MBean インスタンスが存在し、___protobuf_metadata
キャッシュによってサポートされます。ProtobufMetadataManager
ObjectName は以下のパターンを使用します。
<jmx domain>:type=RemoteQuery, name=<cache manager<methodname>putAllname>, component=ProtobufMetadataManager
<jmx domain>:type=RemoteQuery,
name=<cache manager<methodname>putAllname>,
component=ProtobufMetadataManager
以下の署名は、Protobuf スキーマファイルを登録するメソッドによって使用されます。
void registerProtofile(String name, String contents)
void registerProtofile(String name, String contents)
キャッシュのインデックス化が有効になっている場合、Protobuf エンコードされたエントリーのすべてのフィールドがインデックス化されます。Protobuf エンコードされたすべてのエントリーは、インデックス化が有効になっているかどうかに関わらず検索可能です。
インデックス化はパフォーマンスの向上のために推奨されますが、リモートクエリーの使用時には必須ではありません。インデックス化を使用すると検索速度が向上しますが、インデックスの維持に必要なオーバーヘッドにより挿入および更新の速度が低下します。
20.6.7. Protobuf によるカスタムフィールドのインデックス化 リンクのコピーリンクがクリップボードにコピーされました!
デフォルトでは、すべての Protobuf 型フィールドがインデックス化および格納されます。これは、ほとんどの場合で適切な動作ですが、フィールドの数が多すぎたりフィールドが大きすぎると、パフォーマンスの問題が発生することがあります。インデックス化および格納するフィールドを指定するには、メッセージ型定義およびフィールド定義のドキュメンテーションコメントで Protobuf スキーマに直接 @Indexed
および @IndexedField
アノテーションを使用します。
インデックス化されるフィールドの指定
アノテーションが付けられる要素 (メッセージ型またはフィールド定義) の前に付けられるドキュメンテーションコメントの最後の行にドキュメンテーションアノテーションを追加します。
@Indexed
アノテーションはメッセージ型のみに適用され、ブール値を持ちます (デフォルトは true
)。そのため、@Indexed
の使用は @Indexed(true)
と同等になります。このアノテーションは、インデックス化が必要なメッセージ型のフィールドを選択して指定するために使用されます。しかし、@Indexed(false)
はインデックス化されるフィールドがないことを示すため、フィールドレベルの最終的な @IndexedField
アノテーションは無視されます。
@IndexedField
アノテーションはフィールドのみに適用され、2 つの属性 (index
および store
) があります。これらの属性のデフォルトは true
です。@IndexedField
の使用は @IndexedField(index=true, store=true)
と同等です。index
属性はフィールドがインデックス化されるかどうかを示すため、インデックス化されたクエリーに使用されます。store
属性はフィールド値をインデックスに格納する必要があるかどうかを示すため、値は射影に使用できます。
@IndexedField
アノテーションは、含まれるメッセージ型に @Indexed
アノテーションが付けられている場合のみ有効です。
20.6.8. Java アノテーションでの Protocol Buffers スキーマの定義 リンクのコピーリンクがクリップボードにコピーされました!
Java アノテーションを使用して Protobuf メタデータを宣言できます。MessageMarshaller
実装と .proto スキーマファイルを提供する代わりに、最小限のアノテーションを Java クラスとそのフィールドに追加できます。
この方法の目的は、ProtoStream
ライブラリーを使用して Java obujekuto を protobuf にマーシャルすることです。ProtoStream
ライブラリーは内部でマーシャラーを生成し、手動で実装されたマーシャラーは必要ありません。Java アノテーションには、Protobuf タグ番号などの最低限の情報が必要になります。その他は常識的なデフォルトを基に推定され (Protobuf 型、Java コレクション型、およびコレクション要素型)、オーバーライドすることができます。
自動生成されたスキーマは SerializationContext
で登録され、他の言語のドメインモデルクラスおよびマーシャラーを実装するための参照として使用することもできます。
Java アノテーションの例を以下に示します。
User.Java
Note.Java
ProtoSchemaBuilderDemo.Java
以下は、ProtoSchemaBuilderDemo.java の例によって生成される .proto ファイルになります。
Sample_Schema.Proto
以下の表は、サポートされる Java アノテーションとそのアプリケーションおよびパラメーターを示しています。
アノテーション | 適用対象 | 目的 | 要件 | Parameters |
---|---|---|---|---|
|
クラス/フィールド/列挙型/列挙型メンバー |
生成された Protobuf スキーマ要素にアタッチされるドキュメンテーションコメントを指定します (メッセージ型、フィールド定義、列挙型、列挙値定義)。 |
任意 |
単一の文字列パラメーター、ドキュメンテーションテキスト。 |
|
クラス |
生成されたメッセージ型の名前を指定します。指定がない場合はクラス名が使用されます。 |
任意 |
名前 (文字列)、生成されたメッセージ型の名前。指定がない場合はデフォルトで Java クラス名が使用されます。 |
|
フィールド、ゲッターまたはセッター |
Protobuf フィールド番号とその Protobuf 型を指定します。また、フィールドが繰り返されるかどうか、任意または必須であるかどうかも示し、任意でデフォルト値を示します。Java フィールド型がインターフェースまたは抽象クラスである場合、その実際の型を示す必要があります。フィールドが繰り返し可能で、宣言されたコレクション型が抽象である場合、実際のコレクション実装型を指定する必要があります。このアノテーションがない場合、マーシャリングでこのフィールドが無視されます (一時的です)。Protobuf がマーシャル可能と見なされるには、クラスに |
必須 |
数 (整数、必須)、Protobuf 番号型 (org.infinispan.protostream.descriptors.Type、任意)、Protobuf 型: 通常は必須と推測されます (ブール値、任意)、名前 (文字列、任意)、 Protobuf namejava型 (クラス、任意)、実際の型: 宣言された型が抽象 collectionImplementation の場合のみ必要 (クラス、任意)、実際のコレクション型: 宣言された型が抽象 defaultValue の場合のみ必要 (文字列、任意)、文字列は Java フィールド型に基づいた適切な形式である必要があります。 |
|
列挙型 |
生成された列挙型の名前を指定します。指定がない場合は Java 列挙名が使用されます。 |
任意 |
名前 (文字列)、生成された列挙型の名前。指定がない場合、デフォルトで Java 列挙名が使用されます。 |
|
列挙型メンバー |
対応する Protobuf 列挙値の数値を指定します。 |
必須 |
数 (整数、必須)、Protobuf 番号名 (文字列)、Protobuf 名。指定のない場合、Java メンバーの名前が使用されます。 |
@ProtoDoc
アノテーションを使用すると、生成されたスキーマでドキュメンテーションコメントを提供できます。また、@Indexed
および @IndexedField
アノテーションを必要な場所にインジェクトすることもできます (詳細は Protobuf でのカスタムフィールドのインデックス化 を参照してください)。