第23章 リモートクエリー
23.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 エンティティーを保存することも可能です。
23.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 |
結果のソート |
可 |
可 |
可 |
可 |
可 |
結果のフィルター |
可 (クエリー内および先頭に追加された演算子) |
クエリー内 |
クエリー内 |
クエリー内 |
クエリー内 |
結果のページネーション |
可 |
可 |
可 |
可 |
可 |
継続的クエリー |
不可 |
可 |
可 |
不可 |
不可 |
クエリーの集約操作 |
不可 |
可 |
可 |
可 |
可 |
23.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 上で実行できるようになります。
23.4. Hot Rod C++ クライアントでのリモートクエリー リンクのコピーリンクがクリップボードにコピーされました!
Hot Rod C++ クライアントでリモートクエリーを使用する手順は、「Hot Rod C++ クライアントを用いたリモートクエリーの実行」を参照してください。
23.5. Hot Rod C# クライアントでのリモートクエリー リンクのコピーリンクがクリップボードにコピーされました!
Hot Rod C# クライアントでリモートクエリーを使用する手順は、「Hot Rod C# クライアントを用いたリモートクエリーの実行」を参照してください。
23.6. Protobuf エンコーディング リンクのコピーリンクがクリップボードにコピーされました!
23.6.1. Protobuf エンコーディング リンクのコピーリンクがクリップボードにコピーされました!
Infinispan Query DSL は Hot Rod 経由で使用できます。これには、Protocol Buffers を使用してキャッシュエントリーの保存およびマーシャリングに共通の形式を採用します。
詳細は、https://developers.google.com/protocol-buffers/docs/overview を参照してください。
23.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
23.6.3. Protobuf メッセージ リンクのコピーリンクがクリップボードにコピーされました!
Protobuf メッセージに関する重要事項は次のとおりです。
- メッセージを入れ子にすることは可能ですが、結果として構造は常にツリーになり、グラフにはなりません。
- 型の継承はありません。
- コレクションはサポートされませんが、繰り返されるフィールドを使用してアレイを簡単にエミュレートできます。
23.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
はありません。
23.6.5. エンティティーごとのマーシャラーの登録 リンクのコピーリンクがクリップボードにコピーされました!
リモートクエリーの目的で ProtoStreamMarshaller
を使用する場合、各ドメインモデル型に対してエントリーごとにマーシャラーを登録しないと、マーシャリングに失敗します。マーシャラーの 1 つのインスタンスが使用されるため、ステートレスでスレッドセーフなマーシャラーを作成する必要があります。
以下の例はマーシャラーの書き方を示しています。
BookMarshaller.java
クライアントが設定されたら、リモートキャッシュへの Java オブジェクトの読み書きにはエンティティーマーシャラーが使用されます。関係するすべての型のリモートクライアントでマーシャラーが登録された場合、キャッシュに格納される実際のデータは protobuf でエンコードされます。この例では、Book
と Author
になります。
protobuf 形式で格納されたオブジェクトは、異なる言語で書かれた互換性のあるクライアントと使用することができます。
23.6.6. Protobuf エンコードされたエンティティーのインデックス化 リンクのコピーリンクがクリップボードにコピーされました!
クライアントが Protobuf を使用するよう設定したら、JBoss Data Grid でキャッシュのインデックス化を設定できます。
キャッシュでエントリーをインデックス化するには、JBoss Data Grid は Protobuf スキーマに定義されたメッセージ型にアクセスできる必要があります。Protobuf スキーマは .proto 拡張子が付いているファイルです。
put
、putAll
、putIfAbsent
、または replace
操作で Protobuf スキーマを ___protobuf_metadata
キャッシュに置き、JBoss Data Grid に Protobuf スキーマを提供します。この代わりに、JMX 経由で ProtobufMetadataManager
MBean を呼び出すこともできます。
___protobuf_metadata
のキーと値は両方 String です。キーはファイル名で、値はスキーマファイルの内容になります。
___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 エンコードされたすべてのエントリーは、インデックス化が有効になっているかどうかに関わらず検索可能です。
インデックス化はパフォーマンスの向上のために推奨されますが、リモートクエリーの使用時には必須ではありません。インデックス化を使用すると検索速度が向上しますが、インデックスの維持に必要なオーバーヘッドにより挿入および更新の速度が低下します。
23.6.7. Protobuf によるカスタムフィールドのインデックス化 リンクのコピーリンクがクリップボードにコピーされました!
デフォルトでは、キャッシュのインデックス化を有効にした後、すべての Protobuf 型フィールドはインデックス化および格納されます。ほとんどの場合でこのインデックス化は適していますが、多くのフィールドまたは非常に大きなフィールドを持つ Protobuf メッセージ型を処理する場合は、パフォーマンスが劣化したり、十分でない可能性があります。
そのため、@Indexed
および @Field
アノテーションを直接コメント定義内の Protobuf スキーマで使用して、どのフィールドがインデックス化されるかを制御する必要があります。
インデックス化されるフィールドの指定
アノテーションは、アノテーションが付けられる要素 (メッセージまたはフィールドのいずれか) の前にあるコメントの最終行に付けられます。
@Indexed
アノテーションに関する説明は次のとおりです。
-
メッセージ型のみに適用され、デフォルトが
true
. であるブール値を持ちます。そのため、@Indexed
の使用は@Indexed(true)
と同等になります。 -
このアノテーションは、インデックス化されたメッセージ型のフィールドの指定を可能にします。
@Indexed(false)
の使用はインデックス化されるフィールドがないことを示します。そのため、@Field
アノテーションは無視されます。
@Field
アノテーションに関する説明は次のとおりです。
-
フィールドのみに適用され、
index
、store
、およびanalyze
の 3 つの属性を持ちます。 デフォルトは
@Field(index=Index.YES, store=Store.NO, analyze=Analyze.NO)
です。これらの属性は以下の定義を持ちます。-
index
属性はフィールドがインデックスされるべきであるかどうかを示し、インデックス化されたクエリーでの使用を許可します。 -
store
属性はフィールドがインデックスに格納されるべきかどうかを示し、プロジェクションでの使用を許可します。 -
analyze
属性は、フルテキスト検索にフィールドを使用できるかどうかを示します。
-
すべての Protobuf メッセージ型のインデックス化を無効化
アノテーションが付けられていないすべての Protobuf メッセージ型のインデックス化を無効にすることができます。各スキーマファイルの最初にある indexed_by_default
Protobuf スキーマオプションの値を次のように false
に設定します。
option indexed_by_default = false; //Disable indexing of all types that are not annotated for indexing.
option indexed_by_default = false; //Disable indexing of all types that are not annotated for indexing.
23.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 スキーマ要素にアタッチされるドキュメンテーションコメントを指定します (メッセージ型、フィールド定義、列挙型、列挙値定義)。 |
任意 |
単一の String パラメーター、ドキュメンテーションテキスト。 |
|
クラス |
生成されたメッセージ型の名前を指定します。指定がない場合はクラス名が使用されます。 |
任意 |
名前 (String)、生成されたメッセージ型の名前。指定がない場合はデフォルトで Java クラス名が使用されます。 |
|
フィールド、ゲッターまたはセッター |
Protobuf フィールド番号とその Protobuf 型を指定します。また、フィールドが繰り返されるかどうか、任意または必須であるかどうかも示し、任意でデフォルト値を示します。Java フィールド型がインターフェースまたは抽象クラスである場合、その実際の型を示す必要があります。フィールドが繰り返し可能で、宣言されたコレクション型が抽象である場合、実際のコレクション実装型を指定する必要があります。このアノテーションがない場合、マーシャリングでこのフィールドが無視されます (一時的です)。Protobuf がマーシャル可能と見なされるには、クラスに |
必須 |
数 (int、必須)、Protobuf 番号型 (org.infinispan.protostream.descriptors.Type、任意)、Protobuf 型: 通常は必須と推測されます (ブール値、任意)、名前 (String、任意)、 Protobuf namejava型 (Class、任意)、実際の型: 宣言された型が抽象 collectionImplementation の場合のみ必要 (Class、任意)、実際のコレクション型: 宣言された型が抽象 defaultValue の場合のみ必要 (String、任意)、文字列は Java フィールド型に基づいた適切な形式である必要があります。 |
|
列挙型 |
生成された列挙型の名前を指定します。指定がない場合は Java 列挙名が使用されます。 |
任意 |
名前 (String)、生成された列挙型の名前。指定がない場合、デフォルトで Java 列挙名が使用されます。 |
|
列挙型メンバー |
対応する Protobuf 列挙値の数値を指定します。 |
必須 |
数 (int、必須)、Protobuf 番号名 (String)、Protobuf 名。指定のない場合、Java メンバーの名前が使用されます。 |
@ProtoDoc
アノテーションを使用すると、生成されたスキーマでドキュメンテーションコメントを提供できます。また、@Indexed
および @Field
アノテーションを必要な場所にインジェクトすることもできます。詳細は「Protobuf でのカスタムフィールドのインデックス化」を参照してください。