第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 ファイルです。この代わりに、サーバーのProtobufMetadataManagerMBean のregisterProtofileメソッドを呼び出して Protobuf スキーマを登録することもできます。キャッシュコンテナーごとにこの MBean の 1 つのインスタンスがあり、___protobuf_metadataによってサポートされるため、この 2 つの方法は同等です。___protobuf_metadataシステムキャッシュ経由で Protobuf スキーマを提供する例は、「 Protocol Buffers スキーマファイルの登録」を参照してください。注記___protobuf_metadataキャッシュへの書き込みには、書き込みを実行するユーザーに ___schema_manager ロールを追加する必要があります。以下の例は、
ProtobufMetadataManagerMBean の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-remotejar が使用されていない場合、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 でのカスタムフィールドのインデックス化」を参照してください。