6 インメモリー・アナリスト(PGX)の使用
Oracle Spatial and Graphのインメモリー・アナリスト機能は、一連の分析機能をサポートしています。
この章では、インメモリー・アナリストを使用する例について説明します(プロパティ・グラフ・インメモリー分析とも呼ばれ、Javadoc、コマンドライン、パスの説明、エラー・メッセージなどではPGXと省略されます)。
多くの例を実行するには、「グラフ・データのパラレル・ロード」に記載されているように、グラフ・データを最初にロードする必要があります。
- グラフのメモリーへの読込み
このトピックでは、シェル・インタフェースを使用したメモリーへの対話によるグラフの読込みの例について説明します。 - インメモリー・アナリストの構成
起動時にインメモリー・アナリストに単一のJSONファイルを割り当てることにより、インメモリー・アナリスト・エンジンおよびそのランタイム動作を構成できます。 - カスタム・グラフ・データの読取り
ユーザー独自のカスタム・グラフ・データを読み取ることができます。この例では、グラフを作成し、それを変更して正しく読み取る方法を表示します。 - グラフ・データのディスクへの格納
グラフはJavaまたはシェルを使用してメモリーに読み込んだ後、別の形式でディスクに格納できます。格納したグラフ・データは、後でインメモリー・アナリストへの入力として使用できます。 - 組込みアルゴリズムの実行
インメモリー・アナリストには、一連の組込みアルゴリズムが含まれており、Java APIとして使用できます。 - カスタムPGXグラフ・アルゴリズムの使用
カスタムPGXグラフ・アルゴリズムを使用すると、Javaでグラフ・アルゴリズムを記述し、効率的なパラレル実装に自動的にコンパイルできます。 - サブグラフの作成
メモリーにロードされたグラフに基づいてサブグラフを作成できます。 - グラフを使用したパターンマッチング問合せの使用
インメモリー・グラフに対してパターンマッチング問合せを発行してから、その問合せの結果を操作できます。 - インメモリー・アナリスト・サーバーの起動
Big Data Spatial and Graphには、スクリプトの実行によってインメモリー・アナリスト・サーバーを起動できるApache Tomcatの事前構成済バージョンがバンドルされています。 - Apache Tomcatへのデプロイ
インメモリー・アナリストは、Apache TomcatまたはOracle WebLogic Serverにデプロイできます。この例では、Webアプリケーションとしてインメモリー・アナリストをApache Tomcatにデプロイする方法を示しています。 - Oracle WebLogic Serverへのデプロイ
インメモリー・アナリストは、Apache TomcatまたはOracle WebLogic Serverにデプロイできます。 - インメモリー・アナリスト・サーバーへの接続
プロパティ・グラフのインメモリー・アナリストがサーバーとしてデプロイされ、Hadoopクラスタ(またはApache TomcatあるいはOracle WebLogic上のWebアプリケーションとしてHadoopのないクライアント・システム)にインストールされた後、インメモリー・アナリスト・サーバーに接続できます。 - PGXパーティション化グラフの使用
プロパティ・グラフをパーティション化グラフとしてインメモリー分析サーバー(PGX)にロードすると、メモリーが大幅に節約されます。 - PGXロード・バランシングおよび高可用性のためのHAProxyの使用
HAProxy (高可用性プロキシ)は、Webサーバーで着信リクエストを複数のエンドポイントに分散できる、TCP/HTTPロード・バランサおよびプロキシ・サーバーです。 - HDFSでのデータの読取りおよび格納
インメモリー・アナリストは、Hadoop Distributed File System (HDFS)をサポートしています。この例では、インメモリー・アナリストAPIを使用してHDFSのグラフ・データを読み取り、アクセスする方法を示しています。 - PGX RESTエンドポイントの使用の開始
PGX REST APIを使用すると、Java以外の言語でインメモリー・アナリストとやりとりして独自のクライアントを実装できます。 - Oracleの2つの表関係形式の使用
リレーショナル・データ・モデルを使用する場合、グラフ・データは2つのリレーショナル表を使用して表現できます。1つの表はノードとそのプロパティ用で、もう1つの表はエッジとそのプロパティ用です。 - インメモリー・アナリストApache Zeppelinインタプリタの使用
インメモリー・アナリストには、Apache Zeppelinのインタプリタ実装が用意されています。このチュートリアルのトピックでは、ローカルのZeppelinインストールにインメモリー・アナリスト・インタプリタをインストールし、いくつかの簡単な操作を実行する方法について説明します。 - インメモリー・アナリスト・エンタープライズ・スケジューラの使用
インメモリー・アナリスト・エンタープライズ・スケジューラには、高度なスケジューリング機能が用意されています。
6.1 グラフのメモリーへの読込み
このトピックでは、シェル・インタフェースを使用したメモリーへの対話によるグラフの読込みの例について説明します。
サブトピックでは主なステップを示します。
注意:
セキュアなデプロイメントを行うために、root
ユーザーを使用してインメモリー分析サーバーを実行しないでください。
親トピック: インメモリー・アナリスト(PGX)の使用
6.1.1 インメモリー・アナリスト・サーバー・インスタンスへの接続
インメモリー・アナリストを起動する手順:
インメモリー・アナリスト・ソフトウェアが正しくインストールされている場合、エンジン実行ログ・メッセージと、インメモリー・アナリスト・シェル・プロンプト(opg>
)に次の情報が表示されます。
The variables instance, session, and analyst are ready to use.
このトピックの前の例では、pgx
コマンドでリモートURLを指定していないため、シェルがローカル・インスタンスを開始します。
親トピック: グラフのメモリーへの読込み
6.1.3 構成ファイルでのグラフ・メタデータの指定
/opt/oracle/oracle-spatial-graph/property_graph/examples/pgx/graphs/
のインストール・ディレクトリにグラフの例が含まれています。ここでは、インメモリー・アナリストがグラフを読み取る方法を説明する構成ファイルを使用します。
opg> cat /opt/oracle/oracle-spatial-graph/property_graph/examples/pgx/graphs/sample.adj.json
===> {
"uri": "sample.adj",
"format": "adj_list",
"node_props": [{
"name": "prop",
"type": "integer"
}],
"edge_props": [{
"name": "cost",
"type": "double"
}],
"separator": " "
}
uri
フィールドには、グラフ・データの場所を指定します。このパスは構成ファイルの親ディレクトリに対して相対的に解決します。インメモリー・アナリストがグラフをロードするとき、sample.adj
という名のファイルのexamples/graphs
ディレクトリが検索されます。
その他のフィールドは、グラフ・データが隣接するリスト形式で提供され、integer
型のノード・プロパティとdouble
型のエッジ・プロパティで構成されていることを示します。
これは隣接するリスト形式のグラフ・データです。
opg> cat /opt/oracle/oracle-spatial-graph/property_graph/examples/pgx/graphs/sample.adj
===> 128 10 1908 27.03 99 8.51
99 2 333 338.0
1908 889
333 6 128 51.09
図6-1は、データから作成されたプロパティ・グラフを示します。
親トピック: グラフのメモリーへの読込み
6.1.4 グラフ・データのメモリーへの読込み
グラフをメモリーに読み込むには、次の情報を渡す必要があります。
-
グラフのメタデータを指定するグラフ構成ファイルへのパス
-
グラフへの参照に使用できる一意の英数字名
別のグラフですでに使用されているグラフ名を割り当てると、エラーが発生します。
ファイルへのパスを指定する手順:
-
頂点およびエッジが1つのファイルに指定されている場合、
uri
を使用します。{ "uri": "path/to/file.format", ...}
-
複数のファイル(ADJ_LIST、EDGE_LISTなど)を指定するには、
uris
を使用します。{ "uris": ["file1.format", "file2.format"] ...}
ほとんどのプレーン・テキスト形式は、3つのインメモリー・アナリストによって並列で解析できます。
-
頂点またはエッジ(FLAT_FILE、TWO_TABLESなど)が含まれるかどうかに応じてファイル形式が異なる場合は、
vertex_uris
およびedge_uris
を使用します。{ "vertex_uris": ["vertices1.format", "vertices2.format"], "edge_uris": ["edges1.format", "edges2.format"] ...}
注意:
この章の多くの例を実行するには、「グラフ・データのパラレル・ロード」に記載されているように、グラフ・データを最初にロードする必要があります。
サポートされているファイル・システム
インメモリー・アナリストは、様々なプロトコルおよび仮想ファイル・システムを介したグラフ構成ファイルおよびグラフ・データ・ファイルからのロードをサポートしています。ファイル・システムまたはプロトコルのタイプは、Uniform Resource Identifier (URI)のスキームによって決まります。
-
ローカル・ファイル・システム(
file:
)。特定のURIにスキームが含まれていない場合、これがデフォルトにもなります。 -
クラスパス(
classpath:
またはres:
) -
HDFS (
hdfs:
)
相対パスは常に、構成ファイルの親ディレクトリに対して相対的に解決されます。
例: シェルを使用したグラフの読取り
opg> graph = session.readGraphWithProperties("/opt/oracle/oracle-spatial-graph/property_graph/examples/pgx/graphs/sample.adj.json", "sample") ==> PgxGraph[name=sample,N=4,E=4,created=1476225669037] opg> graph.getNumVertices() ==> 4
例: Javaを使用したグラフの読取り
import oracle.pgx.api.*; ServerInstance instance = Pgx.getInstance(Pgx.EMBEDDED_URL); // ServerInstance instance = Pgx.getInstance("http://my-server2:7007"); // remote instance PgxSession session = instance.createSession("my-session"); PgxGraph graph = session.readGraphWithProperties("/opt/oracle/oracle-spatial-graph/property_graph/examples/pgx/graphs/sample.adj.json");
次のトピックでは、プロパティ・グラフをメモリーに読み込むその他の例について説明します。
注意:
多くの例を実行するには、「グラフ・データのパラレル・ロード」に記載されているように、グラフ・データを最初にロードする必要があります。
- Apache HBaseに格納されているグラフのメモリーへの読込み
- Oracle NoSQL Databaseに格納されているグラフのメモリーへの読込み
- ローカル・ファイル・システムに格納されているグラフのメモリーへの読込み
親トピック: グラフのメモリーへの読込み
6.1.4.1 Apache HBaseに格納されているグラフのメモリーへの読込み
Apache HBaseに格納されているプロパティ・グラフを読み取るには、次のようにJSONベースの構成ファイルを作成できます。定数、クライアント・ポート、グラフ名、およびその他の情報は、ユーザーの設定に応じてカスタマイズする必要があります。
% cat /tmp/my_graph_hbase.json { "format": "pg", "db_engine": "hbase", "zk_quorum": "scaj31bda07,scaj31bda08,scaj31bda09", "zk_client_port": 2181, "name": "connections", "node_props": [{ "name": "country", "type": "string" }], "edge_props": [{ "name": "label", "type": "string" }, { "name": "weight", "type": "float" }], "loading": { "load_edge_label": true } } EOF
次のコマンドを使用すると、プロパティ・グラフconnections
がメモリーに読み込まれます。
opg> session.readGraphWithProperties("/tmp/my_graph_hbase.json", "connections") ==> PGX Graph named connections ...
大きいサイズのグラフを扱う場合は、IOワーカー、分析対象のワーカー数、タスクのタイムアウトなどのパラメータを調整する必要があります。「インメモリー・アナリストの構成」を参照してください。
親トピック: グラフ・データのメモリーへの読込み
6.1.4.2 Oracle NoSQL Databaseに格納されているグラフのメモリーへの読込み
Oracle NoSQL Databaseに格納されているプロパティ・グラフを読み取るには、次のようにJSONベースの構成ファイルを作成できます。ホスト、ストア名、グラフ名、およびその他の情報は、ユーザーの設定に応じてカスタマイズする必要があります。
% cat /tmp/my_graph_nosql.json { "format": "pg", "db_engine": "nosql", "hosts": [ "zathras01:5000" ], "store_name": "kvstore", "name": "connections", "node_props": [{ "name": "country", "type": "string" }], "loading": { "load_edge_label": true }, "edge_props": [{ "name": "label", "type": "string" }, { "name": "weight", "type": "float" }] }
次に、構成ファイルをメモリーに読み込みます。次の例では、スニペットがファイルをメモリーに読み込み、方向のないグラフ(名称U
)を元のデータから生成し、三角形の数をカウントします。
opg> g = session.readGraphWithProperties("/tmp/my_graph_nosql.json", "connections") opg> analyst.countTriangles(g, false) ==> 8
親トピック: グラフ・データのメモリーへの読込み
6.1.4.3 ローカル・ファイル・システムに格納されているグラフのメモリーへの読込み
次のコマンドでは、「構成ファイルでのグラフ・メタデータの指定」の構成ファイルおよびmy-graph
という名前を使用します。
opg> g = session.readGraphWithProperties("/opt/oracle/oracle-spatial-graph/property_graph/examples/pgx/graphs/sample.adj.json", "my-graph")
親トピック: グラフ・データのメモリーへの読込み
6.2 インメモリー・アナリストの構成
起動時にインメモリー・アナリストに単一のJSONファイルを割り当てることにより、インメモリー・アナリスト・エンジンおよびそのランタイム動作を構成できます。
このファイルには、次の表に示すパラメータを含めることができます。一部の例はこの表に従います。
構成ファイルを指定するには、「インメモリー・アナリストの構成ファイルの指定」を参照してください。
注意:
-
パラメータ値の相対パスは常に、指定された構成ファイルの親ディレクトリに対して相対的に解決されます。たとえば、構成ファイルが
/pgx/conf/pgx.conf
である場合、そのファイル内のファイル・パスgraph-configs/my-graph.bin.json
は/pgx/conf/graph-configs/my-graph.bin.json
に解決されます。 -
パラメータのデフォルト値は、一連の広範なアルゴリズム全体にわたって最善のパフォーマンスを実現できるよう最適化されます。ワークロードに応じて、様々な戦略、サイズおよびしきい値を使用して試験することにより、パフォーマンスをさらに改善できる場合があります。
表6-1 インメモリー・アナリストの構成パラメータ
パラメータ | 型 | 説明 | デフォルト |
---|---|---|---|
admin_request_cache_timeout |
integer |
管理要求結果がキャッシュから削除されるまでの秒数。実行されていないかまだ使用されていない要求は、このタイムアウトから除外されます。注意: これが該当するのは、PGXがWebアプリケーションとしてデプロイされている場合のみです。 |
60 |
allow_idle_timeout_overwrite |
boolean |
trueの場合、セッションによってデフォルトのアイドル・タイムアウトを上書きできます。 |
true |
allow_local_filesystem |
boolean |
クライアント/サーバー・モードでのローカル・ファイル・システムからのロードを可能にします。デフォルトはfalseです。trueに設定する場合、ディレクトリをリストするプロパティdatasource_dir_whitelist を追加で指定します。サーバーは、ホワイトリストに記載されているディレクトリからのみ読み取ることができます。
|
false |
allow_override_scheduling_information |
boolean |
Trueの場合、タスク重み、タスク優先度、スレッド数などのスケジューリング情報のオーバーライドをすべてのユーザーに許可します |
true |
allowed_remote_loading_locations | stringの配列 |
リモートの場所からPGXエンジンへのグラフのロードを許可します(http、https、ftp、ftps、s3、hdfs)。デフォルトは空です。サポートされる値は"*" (アスタリスク)です。これは、すべてのリモートの場所が許可されることを意味します。事前ロードされるグラフは、この設定の値に関係なく任意の場所からロードされることに注意してください。警告: * (アスタリスク)を指定するのは、PGXリモート・インタフェースのユーザーがローカル・ファイル・システム上のファイルにアクセスするのを明示的に許可する場合のみにする必要があります。 |
[] |
allow_task_timeout_overwrite |
boolean |
trueの場合、セッションによってデフォルトのタスク・タイムアウトを上書きできます |
true |
allow_user_auto_refresh |
boolean |
trueの場合、ユーザーがロードするグラフを自動リフレッシュできます。falseの場合、 |
false |
allowed_remote_loading_locations | stringの配列 | (このオプションを使用するとセキュリティが低下する可能性があるため、作業の内容を把握している場合のみ使用してください。)リモートの場所からPGXエンジンへのグラフのロードを許可します(http、https、ftp、ftps、s3、hdfs)。空の場合は、デフォルトの場合と同様に、リモートの場所は許可されません。配列で"*"を指定すると、すべてのリモートの場所が許可されます。値"*"のみが現在サポートされています。事前ロードされるグラフは、この設定の値に関係なく任意の場所からロードされることに注意してください。 | [] |
basic_scheduler_config | object | 分岐結合プール・バックエンドの構成パラメータ。 | null |
bfs_iterate_que_task_size |
integer |
BFS反復QUEフェーズのタスク・サイズ。 |
128 |
bfs_threshold_parent_read_based |
number |
BFSトラバース・レベル・アイテムを親読取りベースのアクセス戦略に切り替える際のしきい値。 |
0.05 |
bfs_threshold_read_based |
integer |
BFSトラバース・レベル・アイテムを読取りベースのアクセス戦略に切り替える際のしきい値。 |
1024 |
bfs_threshold_single_threaded |
integer |
BFSトラバース・レベル・アイテムの頂点が単一スレッドでアクセスされる数のしきい値。 |
128 |
character_set |
string |
PGX全体にわたって使用する標準文字セット。UTF-8がデフォルトです。注意: 一部の機能には互換性がない場合があります。 |
utf-8 |
cni_diff_factor_default |
integer |
一般的な近傍イテレータ実装で使用されるデフォルトの差異係数値。 |
8 |
cni_small_default |
integer |
一般的な近傍イテレータ実装で使用されるデフォルト値で、このしきい値を下回ると、部分配列が小さいと見なされることを示します。 |
128 |
cni_stop_recursion_default |
integer |
一般的な近傍イテレータ実装で使用されるデフォルト値で、バイナリ検索アプローチが適用される最小サイズを示します。 |
96 |
datasource_dir_whitelist | stringの配列 | allow_local_filesystem が設定されている場合は、ファイルの読取りが許可されているディレクトリのリスト。
|
[] |
dfs_threshold_large |
integer |
DFS実装が多数の頂点に対して最適化されたデータ構造に切り替わるまでにどれくらいの数の頂点がアクセスされる必要があるかを決める値。 |
4096 |
enable_csrf_token_checks |
boolean |
trueの場合、PGX Webアプリケーションは、クライアントから送信された要求パラメータとクロスサイト・リクエスト・フォージェリ(CSRF)トークンCookieが存在して一致するかどうかを検証します。これは、CSRF攻撃を防止することが目的です。 |
true |
enable_gm_compiler |
boolean |
[solaris studioを使用してプロファイリングする場合に関連]有効である場合、'er_label'コマンドを使用して試験にラベルが付けられます。 |
false |
enable_shutdown_cleanup_hook |
boolean |
trueの場合、PGXはJVMのシャットダウン時にPGXを自動的にシャットダウンするJVMシャットダウン・フックを追加します。通知:シャットダウン・フックを非アクティブにし、PGXを明示的にシャットダウンしない場合、一時ディレクトリの汚染につながる可能性があります。 |
true |
enterprise_scheduler_config |
object |
エンタープライズ・スケジューラの構成パラメータ。 |
null |
enterprise_scheduler_flags |
object |
[enterprise_schedulerに関連] エンタープライズ・スケジューラ固有の設定。 |
null |
explicit_spin_locks |
boolean |
trueは、ロックが使用可能になるまでループ内で明示的にスピンすることを意味します。falseは、コンテキストを切り替えるかスピンするかを決定するためにJVMに依存するJDKロック・キーを使用することを意味します。通常、この値をtrueに設定した方がパフォーマンスが向上します。 |
true |
graph_algorithm_language | enum[GM_LEGACY, GM, JAVA] | 使用するフロントエンド・コンパイラ。 | gm |
graph_validation_lever | enum[low, high] | 新しくロードまたは作成されたグラフで実行される検証のレベル。 | low |
ignore_incompatible_backend_operations | boolean | trueの場合、RTSまたはFJプールで互換性のない操作および構成値を検出した場合のみログに記録します。falseの場合、例外がスローされます。 | false |
in_place_update_consistency | enum[ALLLOW_INCONSISTENCIES, CANCEL_TASKS] | インプレース更新の実行時に使用される一貫性モデル。インプレース更新が有効な場合のみ該当します。現時点では、更新が構造的でない場合、更新はインプレースでのみ適用されます(プロパティのみを変更)。現在2つのモデルが実装されており、1つのモデルは更新の実行時に新しいタスクのみが遅延し、もう1つのモデルでは実行中のタスクも遅延します。 | allow_inconsistencies |
init_pgql_on_startup | boolean | trueの場合、PGQLはPGXの起動時に直接初期化されます。そうでない場合、PGQLの初回使用時に初期化されます。 | true |
interval_to_poll_max | integer | 1回到達すると、ジョブ・ステータスのポーリング間隔が固定される、指数バックオフの上限(ミリ秒)。 | 1000 |
java_home_dir | string | Javaのホーム・ディレクトリへのパス。<system-java-home-dir> に設定した場合は、java.home システム・プロパティを使用します。
|
null |
large_array_threshold | integer | 配列のサイズが大きすぎて通常のJava配列を使用できない場合のしきい値。これは使用しているJVMによって異なります。(デフォルトはInteger.MAX_VALUE - 3です) | 2147483644 |
max_active_sessions |
integer |
一度に有効することが許可されたセッションの最大数。 |
1024 |
max_distinct_strings_per_pool | integer | [string_pooling_strategyが索引付けされている場合のみ該当]超えた場合にプーリングを停止する、プロパティごとの個別の文字列の数。制限に達すると、例外がスローされます。 | 65536 |
max_off_heap_size |
integer |
OutOfMemoryErrorがスローされるまでにPGXが割り当てることが許可されたオフピーク・メモリーの最大量(メガバイト単位)。注意: この制限は、丸めおよび同期のトレードオフのため、絶対に超えないことが保証されるわけではありません。これは、PGXが新しいメモリー割当て要求を拒否し始めた際のしきい値としてのみ機能します。 |
<使用可能な物理メモリー> |
max_queue_size_per_session |
integer |
セッションごとにキューに入れておくことが許可された保留タスクの最大数。セッションが最大に達すると、新しく受け取ったそのセッションの要求が拒否されます。マイナスの値は、制限がないことを意味します。 |
-1 |
max_snapshot_count |
integer |
同時にエンジンにロードすることが可能なスナップショットの数。新しいスナップショットは、自動更新または強制更新を介して作成できます。グラフのスナップショットの数がこのしきい値に達した場合、これ以上の自動更新は実行されなくなり、1つ以上のスナップショットがメモリーから削除されるまでは、強制更新を実行すると例外が発生します。値がゼロの場合、無制限の数のスナップショットをサポートすることを示します。 |
0 |
memory_allocator | enum[basic_allocator, enterprise_allocator] | 使用するメモリー・アロケータ。 | basic_allocator |
memory_cleanup_interval |
integer |
メモリーのクリーンアップ間隔(秒単位)。 |
600 |
ms_bfs_frontier_type_strategy |
enum[auto_grow, short, int] |
MS-BFSフロンティアに使用するタイプの戦略。 |
auto_grow |
num_spin_locks |
integer |
生成された各アプリケーションがインストールを作成するスピン・ロックの数。トレードオフ: 数が小さい場合、メモリーの消費量が小さいことを意味し、数が大きい場合、実行処理が速くなることを意味します(アルゴリズムにスピン・ロックが使用されている場合)。 |
1024 |
parallelism | integer | スレッド・プールで使用されるワーカー・スレッド数。注意:呼出し元のスレッドが別のスレッド・プールの一部である場合、この値は無視され、親プールの並列度が使用されます。 | <CPUの数> |
pattern_matching_supernode_cache_threshold | integer | スーパーノードになるノードの近傍の最小数。これはパターン一致エンジン用です。 | 1000 |
pooling_factor | number | [string_pooling_strategyがon_heapの場合のみ該当] この値は、文字列プールがプロパティ・サイズと同じ大きさになり、プーリングが無効になる可能性を防ぎます。 | 0.25 |
preload_graphs |
オブジェクトの配列 |
起動時に登録されるグラフ構成のリスト。各アイテムには、グラフ構成へのパス、グラフの名前、およびグラフを公開するかどうかが含まれます。 |
[] |
random_generator_strategy | enum[non_deterministic, deterministic] | PGXで乱数を生成する方法。 | non_deterministic |
random_seed |
long |
[deterministicランダム数ジェネレータのみに関連]インメモリー・アナリストで使用されるdeterministicランダム数ジェネレータのシード。デフォルトは-24466691093057031です。 |
-24466691093057031 |
release_memory_threshold |
double |
エンジンが未使用のグラフを解放するまでの使用済メモリーのしきい値パーセンテージ(小数)。例: 値が0.0である場合、グラフは参照数がゼロになると同時に解放されることを意味します。つまり、そのグラフをロードしたすべてのセッションが破棄されます/タイムアウトします。値が1.0である場合、グラフは一切解放されず、メモリーに収まらないグラフが必要になると同時にOutOfMemoryErrorsがスローされます。値が0.7である場合、メモリー内のグラフを現在使用しているセッションがない場合でも、メモリー消費量の合計が使用可能なメモリー合計の70%を下回っている限り、これらのグラフがすべて保持されます。消費量が70%を超えているときに別のグラフをロードする必要がある場合、メモリー消費量が再度70%を下回るまで未使用のグラフが解放されます。 |
0.85 |
revisit_threshold | integer | 到達するノードからの一致する結果の最大数。 | 4096 |
scheduler | enum[basic_scheduler, enterprise_scheduler] | 使用するスケジューラ。basic_scheduler は、基本機能を備えたスケジューラを使用します。enterprise_scheduler は、複数のタスクを同時に実行してパフォーマンスを改善するための拡張エンタープライズ機能を備えたスケジューラを使用します。
|
advanced_scheduler |
session_idle_timeout_secs |
integer |
アイドル中のセッションのタイムアウト(秒単位)。ゼロ(0)は、タイムアウトが行われないことを意味します。 |
0 |
session_task_timeout_secs |
integer |
セッション(アルゴリズム、I/Oタスク)によって発行された長時間のタスクを中断までのタイムアウト(秒単位)。ゼロ(0)は、タイムアウトが行われないことを意味します。 |
0 |
small_task_length |
integer |
ワークの合計量がデフォルトのタスクの長さより小さい場合のタスクの長さ(タスク・スティーリング戦略の場合のみ関連)。 |
128 |
spark_streams_interface |
string |
Sparkデータ通信にはインタフェースの名前が使用されます。 |
null |
strict_mode |
boolean |
trueの場合、無効なキー、不一致、および他の潜在的なエラーなどの構成問題が発生した場合は常に例外がスローされ、ERRORレベルで記録されます。falseの場合、(重大度に応じて)問題がERROR/WARNレベルで記録され、推測が行われ、例外をスローする代わりに合理的なデフォルトが使用されます。 |
true |
string_pooling_strategy | enum[indexed, on_heap, none] | [use_string_poolが有効な場合のみ該当] 使用する文字列プーリング戦略。 | on_heap |
task_length |
integer |
デフォルトのタスクの長さ(タスク・スティーリング戦略の場合のみ関連)。100から10000にする必要があります。トレードオフ: 数が小さい場合、よりファイングレインなタスクが生成され、スティーリングのスループットが高くなります。数が大きい場合、メモリー消費量およびGCアクティビティが小さくなります。 |
4096 |
tmp_dir |
string |
コンパイル・アーティファクトおよび他の一時データを格納するための一時ディレクトリ。<system-tmp-dir>に設定されている場合、基礎となるシステムの標準tmpディレクトリ(Linuxの場合は/tmp)を使用します。 |
<system-tmp-dir> |
udf_config_directory |
string |
UDFファイルを含むディレクトリ・パス。 |
null |
use_memory_mapper_for_reading_pgb | boolean | trueの場合、可能な場合はPGB形式でグラフを読み取るためのメモリー・マップ・ファイルを使用してください。falseの場合は、常にストリームベースの実装を使用してください。 | true |
use_memory_mapper_for_storing_pgb | boolean | trueの場合、可能な場合はPGB形式でグラフを格納するためのメモリー・マップ・ファイルを使用してください。falseの場合は、常にストリームベースの実装を使用してください。 | true |
エンタープライズ・スケジューラのパラメータ
次のパラメータは、高度なスケジューラが使用されている場合にのみ該当します。(基本スケジューラを使用している場合は無視されます)。
-
analysis_task_config
分析タスクの構成。型: object。デフォルト:
prioritymediummax_threads<CPUの数>weight<CPUの数>
-
fast_analysis_task_config
高速分析タスクの構成。型: object。デフォルト:
priorityhighmax_threads<CPUの数>weight1
-
maxnum_concurrent_io_tasks
同時タスクの最大数。型: integer。デフォルト: 3
-
num_io_threads_per_task
高速分析タスクの構成。型: object。デフォルト:
<CPUの数>
基本スケジューラのパラメータ
次のパラメータは、基本スケジューラが使用されている場合にのみ該当します。(高度なスケジューラを使用している場合は無視されます)。
-
num_workers_analysis
分析タスクに使用するワーカー・スレッドの数。型: integer。デフォルト:
<CPUの数>
-
num_workers_fast_track_analysis
高速分析タスクに使用するワーカー・スレッドの数。型: integer。デフォルト: 1
-
num_workers_io
I/Oタスク(ロード/リフレッシュ/ディスクへの/からの読込み)タスクに使用するワーカー・スレッドの数。ファイルベースのローダーは常に単一スレッドであるため、この値はこれらには影響しません。データベース・ローダーは、I/Oワーカーごとに新しい接続を開きます。デフォルト:
<CPUの数>
例6-1 最小限のインメモリー・アナリスト構成
次の例を使用すると、インメモリー・アナリストにより、32のワーカーが含まれる分析スレッド・プールが初期化されます。(他のすべてのパラメータにデフォルト値が使用されます。)
{ "enterprise_scheduler_config": { "analysis_task_config": { "max_threads": 32 } } }
例6-2 2つの事前ロードされたグラフ
複数のフィールドを設定し、PGXの起動時にメモリーにロードするための2つの固定グラフを指定します。
{ "enterprise_scheduler_config": { "analysis_task_config": { "max_threads": 32 }, "fast_analysis_task_config": { "max_threads": 32 } }, "memory_cleanup_interval": 600, "max_active_sessions": 1, "release_memory_threshold": 0.2, "preload_graphs": [ { "path": "graph-configs/my-graph.bin.json", "name": "my-graph" }, { "path": "graph-configs/my-other-graph.adj.json", "name": "my-other-graph", "publish": false } ] }
6.2.1 インメモリー・アナリストの構成ファイルの指定
インメモリー・アナリストの構成ファイルは、ServerInstance#startEngine
(または任意のバリアント)が呼び出されるたびに起動時にインメモリー・アナリストによって解析されます。構成ファイルへのパスをインメモリー・アナリストに書き込むことも、プログラム的に指定することもできます。このトピックでは、ファイルを指定する複数の方法を識別します
プログラム的
すべての構成フィールドがJava列挙型として存在します。例:
Map<PgxConfig.Field, Object> pgxCfg = new HashMap<>(); pgxCfg.put(PgxConfig.Field.MEMORY_CLEANUP_INTERVAL, 600); ServerInstance instance = ... instance.startEngine(pgxCfg);
明示的に設定されていないすべてのパラメータにデフォルト値が使用されます。
ファイルの明示的な使用
地図の代わりに、インメモリー・アナリスト構成JSONファイルへのパスを書き込むことができます。例:
instance.startEngine("path/to/pgx.conf"); // file on local file system instance.startEngine("classpath:/path/to/pgx.conf"); // file on current classpath
他のすべてのプロトコルの場合、JSONファイルへの入力ストリームに直接書き込むことができます。例:
InputStream is = ... instance.startEngine(is);
ファイルの暗黙的な使用
startEngine()
が引数なしで呼び出されると、インメモリー・アナリストは、次の場所にある構成ファイルを探し、ファイルが見つかったら停止します。
-
Javaシステム・プロパティ
pgx_conf
内にあるファイル・パス。例:java -Dpgx_conf=conf/my.pgx.config.json ...
-
現在のクラスパスのルート・ディレクトリ内の
pgx.conf
という名前のファイル -
現在の
System.getProperty("user.dir")
ディレクトリに対して相対的なルート・ディレクトリ内のpgx.conf
という名前のファイル
注意: 構成を用意するかどうかは任意です。特定の構成ファイル内でフィールドが見つからない場合、または構成ファイルが用意されていない場合、各フィールドのデフォルト値が使用されます。
ローカル・シェルの使用
シェルによるローカルのインメモリー・アナリスト・インスタンスの構成方法を変更するには、$PGX_HOME/conf/pgx.conf
を編集します。変更は、$PGX_HOME/bin/pgx
を次回呼び出すときに反映されます。
次の例のように構成ファイルの場所を変更することもできます。
./bin/opg --pgx_conf path/to/my/other/pgx.conf
システム・プロパティの設定
インメモリー・アナリストが実行されているJVMに-Dpgx.<FIELD>=<VALUE>
引数を書き込むことにより、Javaシステム・プロパティを使用して任意のパラメータを設定できます。システム・プロパティを設定すると、他の任意の構成が上書きされます。次の例では、他の任意の構成がどのように設定されているかとは関係なく、最大オフピーク・サイズを256GBに設定します。
java -Dpgx.max_off_heap_size=256000 ...
環境変数の設定
インメモリー・アナリストが実行されているJVMの環境変数に'PGX_'を追加することにより、環境変数を使用して任意のパラメータを設定することもできます。環境変数を設定すると、他の任意の構成が上書きされます。ただし、システム・プロパティおよび環境変数が同じパラメータに設定されている場合、システム・パラメータ値が使用されます。次の例では、環境変数を使用して最大オフヒープ・サイズを256GBに設定します。
PGX_MAX_OFF_HEAP_SIZE=256000 java ...
親トピック: インメモリー・アナリストの構成
6.3 カスタム・グラフ・データの読取り
ユーザー独自のカスタム・グラフ・データを読み取ることができます。この例では、グラフを作成し、それを変更して正しく読み取る方法を表示します。
このグラフでは隣接するリスト形式を使用しますが、インメモリー・アナリストでは、複数のグラフ形式をサポートしています。
主なステップは次のとおりです。
6.3.1 単純なグラフ・ファイルの作成
この例では、頂点またはエッジ・プロパティのない、単純な小さいグラフを隣接するリストに作成します。それぞれの線には、頂点(ノード) ID、およびその出力エッジ点が指し示す頂点IDが含まれます。
1 2 2 3 4 3 4 4 2
このリストでは、単一スペースで個々のトークンを区切ります。インメモリー・アナリストではその他のセパレータもサポートしており、グラフ構成ファイルで指定できます。
図6-2は、4つの頂点と5つのエッジのあるプロパティ・グラフとしてレンダリングされたデータを示します。(頂点2および頂点4の間には2つのエッジがあり、各エッジは互いの反対の方向を指し示しています。)
インメモリー・アナリストへのグラフの読込みには、グラフ構成が必要です。グラフ構成は、次のいずれかのメソッドを使用して指定できます。
-
JSON形式での構成設定のファイルへの書込み
-
Java
GraphConfigBuilder
オブジェクトの使用。
次の例では、両方のメソッドを示します。
JSON構成
{ "uri": "graph.adj", "format":"adj_list", "separator":" " }
Java構成
import oracle.pgx.config.FileGraphConfig; import oracle.pgx.config.Format; import oracle.pgx.config.GraphConfigBuilder; FileGraphConfig config = GraphConfigBuilder .forFileFormat(Format.ADJ_LIST) .setUri("graph.adj") .setSeparator(" ") .build();
親トピック: カスタム・グラフ・データの読取り
6.3.2 頂点プロパティの追加
「単純なグラフ・ファイルの作成」のグラフは、頂点プロパティまたはエッジ・プロパティを使用しない頂点とエッジで構成されています。頂点プロパティは、それぞれの線の元の頂点IDに続いて配置されます。double
頂点(ノード)プロパティを値0.1、2.0、0.3および4.56789とともにグラフに追加すると、グラフ・データは次のようになります。
1 0.1 2 2 2.0 3 4 3 0.3 4 4 4.56789 2
注意:
インメモリー・アナリストは同種のグラフのみをサポートしており、すべての頂点のプロパティの数とタイプは同じです。
インメモリー・アナリストで、変更したデータ・ファイルを読み取るには、構成ファイルまたはビルダー・コードで頂点(ノード)プロパティを追加する必要があります。次の例では、プロパティを説明する名前を入力し、タイプをdouble
に設定します。
JSON構成
{ "uri": "graph.adj", "format":"adj_list", "separator":" ", "node_props":[{ "name":"double-prop", "type":"double" }] }
Java構成
import oracle.pgx.common.types.PropertyType; import oracle.pgx.config.FileGraphConfig; import oracle.pgx.config.Format; import oracle.pgx.config.GraphConfigBuilder; FileGraphConfig config = GraphConfigBuilder.forFileFormat(Format.ADJ_LIST) .setUri("graph.adj") .setSeparator(" ") .addNodeProperty("double-prop", PropertyType.DOUBLE) .build();
親トピック: カスタム・グラフ・データの読取り
6.3.3 頂点識別子としての文字列の使用
前の例では、integer
頂点(ノード) IDを使用しています。インメモリー分析のデフォルトはinteger
頂点IDですが、string
頂点IDを使用するようにグラフを定義することもできます。
このデータ・ファイルには桁数だけではなく、"node 1"、"node 2"などを使用できます。
"node 1" 0.1 "node 2" "node 2" 2.0 "node 3" "node 4" "node 3" 0.3 "node 4" "node 4" 4.56789 "node 2"
ここでも、データ・ファイルと一致するようにグラフ構成を変更する必要があります。
JSON構成
{ "uri": "graph.adj", "format":"adj_list", "separator":" ", "node_props":[{ "name":"double-prop", "type":"double" }], "node_id_type":"string" }
Java構成
import oracle.pgx.common.types.IdType; import oracle.pgx.common.types.PropertyType; import oracle.pgx.config.FileGraphConfig; import oracle.pgx.config.Format; import oracle.pgx.config.GraphConfigBuilder; FileGraphConfig config = GraphConfigBuilder.forFileFormat(Format.ADJ_LIST) .setUri("graph.adj") .setSeparator(" ") .addNodeProperty("double-prop", PropertyType.DOUBLE) .setNodeIdType(IdType.STRING) .build();
注意:
string
頂点IDは、integer
頂点IDより多くのメモリーを消費します。
文字列内の一重引用符または二重引用符は、バックスラッシュ(\)でエスケープする必要があります。
文字列内の改行(\n)はサポートされていません。
親トピック: カスタム・グラフ・データの読取り
6.3.4 エッジ・プロパティの追加
この例では、タイプstring
のエッジ・プロパティをグラフに追加します。エッジ・プロパティは、目標の頂点(ノード) IDに続いて配置されます。
"node1" 0.1 "node2" "edge_prop_1_2" "node2" 2.0 "node3" "edge_prop_2_3" "node4" "edge_prop_2_4" "node3" 0.3 "node4" "edge_prop_3_4" "node4" 4.56789 "node2" "edge_prop_4_2"
グラフ構成は、データ・ファイルと一致している必要があります。
JSON構成
{ "uri": "graph.adj", "format":"adj_list", "separator":" ", "node_props":[{ "name":"double-prop", "type":"double" }], "node_id_type":"string", "edge_props":[{ "name":"edge-prop", "type":"string" }] }
Java構成
import oracle.pgx.common.types.IdType; import oracle.pgx.common.types.PropertyType; import oracle.pgx.config.FileGraphConfig; import oracle.pgx.config.Format; import oracle.pgx.config.GraphConfigBuilder; FileGraphConfig config = GraphConfigBuilder.forFileFormat(Format.ADJ_LIST) .setUri("graph.adj") .setSeparator(" ") .addNodeProperty("double-prop", PropertyType.DOUBLE) .setNodeIdType(IdType.STRING) .addEdgeProperty("edge-prop", PropertyType.STRING) .build();
親トピック: カスタム・グラフ・データの読取り
6.4 グラフ・データのディスクへの格納
グラフはJavaまたはシェルを使用してメモリーに読み込んだ後、別の形式でディスクに格納できます。格納したグラフ・データは、後でインメモリー・アナリストへの入力として使用できます。
HTTP/RESTへのグラフの格納は現在サポートされていません。
オプションは、次のとおりです。
6.4.1 頂点プロパティへの分析結果の格納
これらの例では、グラフをメモリーに読み込み、Pagerankアルゴリズムを使用して分析します。この分析では、PageRank値を格納する新しい頂点プロパティが作成されます。
シェルを使用したPageRankの実行
opg> g = session.readGraphWithProperties("/opt/oracle/oracle-spatial-graph/property_graph/examples/pgx/graphs/sample.adj.json", "my-graph") ==> ... opg> rank = analyst.pagerank(g, 0.001, 0.85, 100)
Javaを使用したPageRankの実行
PgxGraph g = session.readGraphWithProperties("/opt/oracle/oracle-spatial-graph/property_graph/examples/pgx/graphs/sample.adj.json", "my-graph"); VertexProperty<Integer, Double> rank = session.createAnalyst().pagerank(g, 0.001, 0.85, 100);
親トピック: グラフ・データのディスクへの格納
6.4.2 エッジリスト形式でのグラフのディスクへの格納
この例では、グラフ、Pagerank分析の結果、および元のエッジ・プロパティすべてをエッジリスト形式でディスクに格納します。
グラフを格納するには、次を指定する必要があります。
-
グラフの形式
-
ファイルが格納されるパス
-
格納されるプロパティ。VertexProperty.
ALL
またはEdgeProperty.ALL
を指定するとすべてのプロパティが格納され、VertexProperty.NONE
またはEdgePropery.NONE
を指定すると、どのプロパティも格納されません。個々のプロパティを指定するには、格納するVertexPropertyまたはEdgePropertyオブジェクトを渡します。 -
既存のファイルを同じ名前で上書きするかどうかを示すフラグ
次の例では、/tmp/sample_pagerank.elist.json
構成ファイルでグラフ・データを/tmp/sample_pagerank.elist
に格納します。戻り値は、格納されているファイルのグラフ構成です。これは再度、グラフの読取りに使用できます。
シェルを使用したグラフの格納
opg> config = g.store(Format.EDGE_LIST, "/tmp/sample_pagerank.elist", [rank], EdgeProperty.ALL, false) ==> {"uri":"/tmp/sample_pagerank.elist","edge_props":[{"type":"double","name":"cost"}],"vertex_id_type":"integer","loading":{},"format":"edge_list","attributes":{},"vertex_props":[{"type":"double","name":"pagerank"}],"error_handling":{}}
Javaを使用したグラフの格納
import oracle.pgx.api.*; import oracle.pgx.config.*; FileGraphConfig config = g.store(Format.EDGE_LIST, "/tmp/sample_pagerank.elist", Collections.singletonList(rank), EdgeProperty.ALL, false);
親トピック: グラフ・データのディスクへの格納
6.5 組込みアルゴリズムの実行
インメモリー・アナリストには、一連の組込みアルゴリズムが含まれており、Java APIとして使用できます。
このトピックでは、Triangle CountingおよびPagerank分析を使用したインメモリー・アナリストの使用方法について説明します。
6.5.1 インメモリー・アナリストについて
インメモリー・アナリストには、一連の組込みアルゴリズムが含まれており、Java APIとして使用できます。APIの詳細は、製品ドキュメント・ライブラリに含まれるJavadocに記載されています。特に、サポートされているインメモリー・アナリストのメソッドのリストについては、Analyst
クラスのメソッド・サマリーを参照してください。
たとえば、Pagerankプロシージャの署名は次のとおりです。:
/** * Classic pagerank algorithm. Time complexity: O(E * K) with E = number of edges, K is a given constant (max * iterations) * * @param graph * graph * @param e * maximum error for terminating the iteration * @param d * damping factor * @param max * maximum number of iterations * @return Vertex Property holding the result as a double */ public <ID> VertexProperty<ID, Double> pagerank(PgxGraph graph, double e, double d, int max);
親トピック: 組込みアルゴリズムの実行
6.5.2 Triangle Countingアルゴリズムの実行
Triangle Countingの場合、countTriangles()
のsortByDegree
ブール・パラメータを使用して、グラフを最初に角度でソートする(true
)かソートしない(false
)かを制御します。true
の場合、さらに多くのメモリーが使用されますが、アルゴリズムの実行は高速になります。ただし、グラフが非常に大きい場合、この最適化をオフにしてメモリー不足を回避する必要があります。
シェルを使用したTriangle Countingの実行
opg> analyst.countTriangles(graph, true) ==> 1
このアルゴリズムでは、サンプル・グラフ内の1つの三角形を検出します。
ヒント:
インメモリー・アナリスト・シェルを使用する場合、ロギング・レベルを変更すると、実行中のログ出力の量を増加できます。:h :loglevel
を指定した:loglevel
コマンドの実行に関する情報を参照してください。
Javaを使用したTriangle Countingの実行
import oracle.pgx.api.*; Analyst analyst = session.createAnalyst(); long triangles = analyst.countTriangles(graph, true);
親トピック: 組込みアルゴリズムの実行
6.5.3 Pagerankアルゴリズムの実行
Pagerankは、グラフ内のそれぞれの頂点(ノード)について、0
と1
の間のランク値を計算し、その値をdouble
プロパティに格納します。このため、アルゴリズムによって、出力に対してタイプdouble
の頂点プロパティが作成されます。
インメモリー・アナリストでは、頂点プロパティとエッジ・プロパティの2つのタイプがあります。
-
永続プロパティ: データ・ソースからグラフとともにロードされ固定されたディスク上のデータのインメモリー・コピーであるため、永続となるプロパティ。永続プロパティは読取り専用のため変更できず、セッション間で共有されます。
-
一時プロパティ: 一時プロパティには値が書き込めるため、セッションでプライベートに使用されます。一時プロパティは、
PgxGraph
オブジェクトでcreateVertexProperty
およびcreateEdgeProperty
を呼び出して作成できます。
この例では、Pagerank値が最も高い上位3つの頂点を取得します。タイプdouble
の一時頂点プロパティを使用して、計算したPagerank値を保持します。Pagerankアルゴリズムでは、入力パラメータのデフォルト値としてエラー許容差 = 0.001、ダンピング係数 = 0.85、および反復の最大数 = 100のデフォルト値を使用します。
シェルを使用したPageRankの実行
opg> rank = analyst.pagerank(graph, 0.001, 0.85, 100); ==> ... opg> rank.getTopKValues(3) ==> 128=0.1402019732468347 ==> 333=0.12002296283541904 ==> 99=0.09708583862990475
Javaを使用したPageRankの実行
import java.util.Map.Entry; import oracle.pgx.api.*; Analyst analyst = session.createAnalyst(); VertexProperty<Integer, Double> rank = analyst.pagerank(graph, 0.001, 0.85, 100); for (Entry<Integer, Double> entry : rank.getTopKValues(3)) { System.out.println(entry.getKey() + "=" + entry.getValue()); }
親トピック: 組込みアルゴリズムの実行
6.6 カスタムPGXグラフ・アルゴリズムの使用
カスタムPGXグラフ・アルゴリズムを使用すると、Javaでグラフ・アルゴリズムを記述し、効率的なパラレル実装に自動的にコンパイルできます。
次のサブトピックに記載されている情報よりも詳しい情報は、https://docs.oracle.com/cd/E56133_01/latest/PGX_Algorithm_Language_Specification.pdfのPGXアルゴリズムの仕様を参照してください。
6.6.1 カスタムPGXアルゴリズムの作成
PGXアルゴリズムは、@graphAlgorithm
の注釈が付けられている単一のクラス定義が含まれた通常の.javaファイルです。次に例を示します。
import oracle.pgx.algorithm.annotations.GraphAlgorithm;
@GraphAlgorithm
public class MyAlgorithm {
...
}
PGXアルゴリズム・クラスには、エントリ・ポイントとして使用されるパブリック・メソッドが1つだけ含まれている必要があります。次に例を示します。
import oracle.pgx.algorithm.PgxGraph;
import oracle.pgx.algorithm.VertexProperty;
import oracle.pgx.algorithm.annotations.GraphAlgorithm;
import oracle.pgx.algorithm.annotations.Out;
@GraphAlgorithm
public class MyAlgorithm {
public int myAlgorithm(PgxGraph g, @Out VertexProperty<Integer> distance) {
System.out.println("My first PGX Algorithm program!");
return 42;
}
}
通常のJavaメソッドと同様に、PGXアルゴリズムのメソッドは値(この例では整数)を戻すことができます。さらに興味深いのは、頂点プロパティdistance
を出力パラメータとしてマークする@Out
注釈です。呼出し元は、出力パラメータを参照渡しします。このようにして、呼出し側はアルゴリズムの終了後に、変更されたプロパティへの参照を持ちます。
親トピック: カスタムPGXグラフ・アルゴリズムの使用
6.6.1.1 コレクション
コレクションを作成するには、.create()関数を呼び出します。たとえば、VertexProperty<Integer>は次のように作成されます。
VertexProperty<Integer> distance = VertexProperty.create();
特定の頂点v
でプロパティの値を取得するには、次のようにします。
distance.get(v);
同様に、特定の頂点v
のプロパティを値e
に設定するには、次のようにします。
distance.set(v, e);
コレクションのプロパティを作成することもできます。
VertexProperty<VertexSequence> path = VertexProperty.create();
ただし、PGXアルゴリズムの割当ては常に(参照ではなく)値で行われます。これを明示的にするには、コレクションの割当て時に.clone()
を呼び出す必要があります。
VertexSequence sequence = path.get(v).clone();
値が値で渡される別の結果として、Javaメソッド.equals()
ではなく==
演算子を使用して等価性をチェックできるようになりました。次に例を示します。
PgxVertex v1 = G.getRandomVertex();
PgxVertex v2 = G.getRandomVertex();
System.out.println(v1 == v2);
親トピック: カスタムPGXアルゴリズムの作成
6.6.1.2 反復
PGXアルゴリズムで発生する最も一般的な操作は、反復(すべての頂点のループ、頂点の近傍のループなど)およびグラフのトラバース(幅優先または深さ優先)です。すべてのコレクションは、forEach
メソッドとforSequential
メソッドを公開します。これらのメソッドにより、コレクションをそれぞれ並列および順番に反復処理できます。
次に例を示します。
- グラフの頂点を並列で反復処理するには、次のようにします。
G.getVertices().forEach(v -> { ... });
- グラフの頂点を順番に反復処理するには、次のようにします。
G.getVertices().forSequential(v -> { ... });
- グラフの頂点を
r
から幅優先でトラバースするには、次のようにします。import oracle.pgx.algorithm.Traversal; Traversal.inBFS(G, r).forward(n -> { ... });
forward
(またはbackward
)ラムダ内部では、calling currentLevel()
によって現在のBFS(またはDFS)トラバースのレベルにアクセスできます。
親トピック: カスタムPGXアルゴリズムの作成
6.6.1.3 削減
これらのパラレル・ブロック内では、ラムダの外部に定義される変数をアトミックに更新または削減するのが一般的です。このアトミック削減は、Scalar<T>: reduceAdd, reduceMul, reduceAnd
などでメソッドとして使用できます。たとえば、グラフ内の頂点の数をカウントするには、次のようにします。
public int countVertices() {
Scalar<Integer> count = Scalar.create(0);
G.getVertices().forEach(n -> {
count.reduceAdd(1);
});
return count.get();
}
複数の値をアトミックに更新する場合があります。たとえば、最小のプロパティ値と、その最小値にプロパティ値が到達した頂点を検出する場合があります。パラレル実行のために、2つの別々の削減文によって一貫性がない状態になる場合があります。
この問題を解決するために、Reductions
クラスにはargMin
関数とargMax
関数が用意されています。argMin
の最初の引数は現在の値で、2番目の引数は潜在的な新しい最小値です。また、ArgMinMax
オブジェクトのandUpdate
呼び出しを連鎖させて、その他の変数と、それらが(アトミックに)更新された後の値を指定できます。次に例を示します。
VertexProperty<Integer> rank = VertexProperty.create();
int minRank = Integer.MAX_VALUE;
PgxVertex minVertex = PgxVertex.NONE;
G.getVertices().forEach(n ->
argMin(minRank, rank.get(n)).andUpdate(minVertex, n)
);
親トピック: カスタムPGXアルゴリズムの作成
6.6.2 PGXアルゴリズムのコンパイルおよび実行
カスタムPGXアルゴリズムをコンパイルおよび実行できるようにするには、次のいくつかの処理を実行する必要があります。
conf/pgx.conf
ファイルの2つの構成パラメータを設定します。graph_algorithm_language
オプションをJAVA
に設定します。java_home_dir
オプションを、Javaホームへのパスに設定します(PGXにシステム・プロパティからJavaホームを推測させるには、<system-java-home-dir>
を使用します)。
- セッションを作成します(シェルで暗黙的に、またはJavaで明示的に行います)。次に例を示します。
cd $PGX_HOME ./bin/opg
- PGXアルゴリズムをコンパイルします。次に例を示します。
myAlgorithm = session.compileProgram("/path/to/MyAlgorithm.java")
- アルゴリズムを実行します。次に例を示します。
graph = session.readGraphWithProperties("/path/to/config.edge.json") property = graph.createVertexProperty(PropertyType.INTEGER) myAlgorithm.run(graph, property)
親トピック: カスタムPGXグラフ・アルゴリズムの使用
6.6.3 カスタムPGXアルゴリズムの例: Pagerank
次に、PGXアルゴリズムとしてpagerank
を実装します。
import oracle.pgx.algorithm.PgxGraph;
import oracle.pgx.algorithm.Scalar;
import oracle.pgx.algorithm.VertexProperty;
import oracle.pgx.algorithm.annotations.GraphAlgorithm;
import oracle.pgx.algorithm.annotations.Out;
@GraphAlgorithm
public class Pagerank {
public void pagerank(PgxGraph G, double tol, double damp, int max_iter, boolean norm, @Out VertexProperty<Double> rank) {
Scalar<Double> diff = Scalar.create();
int cnt = 0;
double N = G.getNumVertices();
rank.setAll(1 / N);
do {
diff.set(0.0);
Scalar<Double> dangling_factor = Scalar.create(0d);
if (norm) {
dangling_factor.set(damp / N * G.getVertices().filter(v -> v.getOutDegree() == 0).sum(rank::get));
}
G.getVertices().forEach(t -> {
double in_sum = t.getInNeighbors().sum(w -> rank.get(w) / w.getOutDegree());
double val = (1 - damp) / N + damp * in_sum + dangling_factor.get();
diff.reduceAdd(Math.abs(val - rank.get(t)));
rank.setDeferred(t, val);
});
cnt++;
} while (diff.get() > tol && cnt < max_iter);
}
}
親トピック: カスタムPGXグラフ・アルゴリズムの使用
6.7 サブグラフの作成
メモリーにロードされたグラフに基づいてサブグラフを作成できます。
フィルタ式を使用するか、2部グラフの左側の集合を指定する頂点(ノード)に基づく2部サブグラフを作成できます。
グラフのメモリーへの読込みについては、「グラフ・データのメモリーへの読込み」を参照してください。
- フィルタ式について
- 簡易エッジ・フィルタを使用したサブグラフの作成
- 簡易頂点フィルタを使用したサブグラフの作成
- 複合フィルタを使用したサブグラフの作成
- 式フィルタの結合
- 式フィルタを使用した一連の頂点またはエッジの作成
- 頂点集合を使用した2部サブグラフの作成
親トピック: インメモリー・アナリスト(PGX)の使用
6.7.1 フィルタ式について
フィルタ式は、各頂点または各エッジで評価される式です。式によって、結果(この場合はサブグラフ)に含まれるようにエッジを完成させる述部を定義できます。
4つの頂点(ノード)と4つのエッジで構成される図6-1のグラフを検討します。フィルタ式src.prop1 == 10
と一致するエッジについては、元の頂点のprop
プロパティが10になります。図6-3に示すフィルタ式と一致する2つのエッジ。
次のエッジ・フィルタ式は、
src.prop1 == 10
ソース頂点のprop1
という名前のプロパティの値が10である各エッジがフィルタ式と一致するよう指定します。この場合、次のエッジが式と一致します。
-
頂点
id
: 128から頂点id
: 1908までを上部でつなぐエッジ(cost
: 27.03) -
頂点
id
: 128から頂点id
: 99までを左側でつなぐエッジ(cost
: 8.51)
図6-4は、前述のフィルタ式が適用されたときに生成されるサブグラフを示しています。このサブグラフには、id: 128を持つ頂点、左側と上部のエッジ、および各エッジの宛先頂点(id
: 1908およびid
: 99を持つ頂点)が含まれます。
次の頂点フィルタ式は、
vertex.prop1 < 10
prop1
という名前のプロパティの値が10未満である各頂点がフィルタ式と一致するよう指定します。この場合、次のエッジが式と一致します。
-
頂点
id
: 99から頂点id
: 333までを下部でつなぐエッジ(cost
: 338.0)
フィルタ式の例
-
日付。次の式は、エッジのプロパティ
date
にアクセスし、これが03/27/2007 06:00
と等しいかどうかを確認します。edge.date = date('2007-03-27 06:00:00')
-
入力/出力角度。
inDegree()
は頂点の入力エッジの数を返し、outDegree()
は頂点の出力エッジの数を返します。次の例では、srcは現在のエッジのソース(出力)頂点を示し、dstは宛先(入力)頂点を示します。src.inDegree() > 3 dst.outDegree() < 5
-
ラベル。
hasLabel
は、頂点に特定のラベルがある場合、true
を返します。次は、頂点にcity
ラベルがあり、そのpopulationが10000を超えている場合、true
を返します。vertex.hasLabel('city') && (vertex.population > 10000)
-
ラベル。
label
は、エッジのラベルを返します。次の例では、エッジのラベルがfriend_of
またはclicked_by
である場合、true
を返します。edge.label() = 'friend_of' || edge.label() = 'clicked_by'
-
型変換: 次の例では、ソース頂点のcostプロパティの値を整数に変換します。
(int) src.cost
-
算術のサポート: 次の例は、フィルタ式で使用できる算術式を示しています。
1 + 5 -vertex.degree() edge.cost * 2 > 5 src.value * 2.5 = (dst.inDegree() + 5) / dst.outDegree()
親トピック: サブグラフの作成
6.7.2 簡易エッジ・フィルタを使用したサブグラフの作成
次の例では、「フィルタ式について」で説明した最初のサブグラフを作成します。
シェルを使用したサブグラフの作成
subgraph = graph.filter(new EdgeFilter("src.prop1 == 10"))
Javaを使用したサブグラフの作成
import oracle.pgx.api.*; import oracle.pgx.api.filter.*; PgxGraph graph = session.readGraphWithProperties(...); PgxGraph subgraph = graph.filter(new EdgeFilter("src.prop1 == 10"));
親トピック: サブグラフの作成
6.7.3 簡易頂点フィルタを使用したサブグラフの作成
次の例では、「フィルタ式について」で説明した2番目のサブグラフを作成します。
シェルを使用したサブグラフの作成
subgraph = graph.filter(new VertexFilter("vertex.prop1 < 10"))
Javaを使用したサブグラフの作成
import oracle.pgx.api.*; import oracle.pgx.api.filter.*; PgxGraph graph = session.readGraphWithProperties(...); PgxGraph subgraph = graph.filter(new VertexFilter("src.prop1 < 10"));
親トピック: サブグラフの作成
6.7.4 複合フィルタを使用したサブグラフの作成
この例では、複合エッジ・フィルタを使用してサブグラフを作成します。ここでは、識別子の送信エッジの数(ソースsrc
または宛先dst
)を計算するoutDegree
関数を使用します。次のフィルタ式は、cost
プロパティ値が50を超え、outDegree
が1を超える宛先の頂点(ノード)のエッジと一致します。
dst.outDegree() > 1 && edge.cost > 50
図6-5では、サンプル・グラフのエッジの1つがこのフィルタ式と一致します。
図6-6はフィルタを適用した結果のグラフを示します。フィルタは頂点99と1908に対応するエッジを除外するため、その頂点も除外します。
親トピック: サブグラフの作成
6.7.5 式フィルタの結合
頂点フィルタをエッジ・フィルタと結合できます。
両方のフィルタが個別に評価され、後で次のいずれかを作成することによってマージされます。
-
結果の結合
-
結果の交差
2つのフィルタの結合の作成
結合の実行対象としてエッジ・フィルタと、
src.prop1 == 10
頂点フィルタを選択すると、
vertex.prop1 < 10
次のグラフに示す結果が得られます。
シェルの例:
edgeFilter = new EdgeFilter("src.prop1 == 10") vertexFilter = new VertexFilter("vertex.prop1 < 10") filter = edgeFilter.union(vertexFilter) subgraph = g.filter(filter)
Javaの例:
import oracle.pgx.api.filter.*; ... EdgeFilter edgeFilter = new EdgeFilter("src.prop1 == 10"); VertexFilter vertexFilter = new VertexFilter("vertex.prop1 < 10"); GraphFilter filter = edgeFilter.union(vertexFilter); PgxGraph subgraph = g.filter(filter);
2つのフィルタの交差の作成
結合の例で説明したフィルタの交差を作成すると、単一の頂点のみで構成された次のグラフが生成されます。
シェルの例:
edgeFilter = new EdgeFilter("src.prop1 == 10") vertexFilter = new VertexFilter("vertex.prop1 < 10") filter = edgeFilter.intersect(vertexFilter) subgraph = g.filter(filter)
Javaの例:
import oracle.pgx.filter.expressions.*; ... EdgeFilter edgeFilter = new EdgeFilter("src.prop1 == 10"); VertexFilter vertexFilter = new VertexFilter("vertex.prop1 < 10"); GraphFilter filter = edgeFilter.intersect(vertexFilter); PgxGraph subgraph = g.filter(filter);
親トピック: サブグラフの作成
6.7.6 式フィルタを使用した一連の頂点またはエッジの作成
式フィルタを使用したサブグラフの作成(他のトピックで説明しています)以外にも、式フィルタを使用してグラフから一連の頂点またはエッジのみを選択することもできます。
たとえば、次の頂点フィルタ式を使用して「フィルタ式について」のサンプル・グラフで頂点セットを作成できます。
vertex.prop1 < 10
これにより、ID値99および333を持つ頂点セットが生成されます。
例6-3 頂点セットの作成
シェルの例:
vertices = g.getVertices( new VertexFilter("vertex.prop1 < 10") ) ==> PgxVertex with ID 99 ==> PgxVertex with ID 333
Javaの例:
import oracle.pgx.api.*; import oracle.pgx.filter.expressions.*; ... VertexSet<Integer> = g.getVertices( new VertexFilter("vertex.prop1 < 10") );
例6-4 エッジ・セットの作成
シェルの例:
edges = g.getEdges( new EdgeFilter("src.prop1 == 10") ) ==> PgxEdge with ID 0 ==> PgxEdge with ID 1
Javaの例:
import oracle.pgx.api.*; import oracle.pgx.filter.expressions.*; ... EdgeSet = g.getEdges( new EdgeFilter("src.prop1 == 10") );
親トピック: サブグラフの作成
6.7.7 頂点集合を使用した2部サブグラフの作成
2部サブグラフは、左側に使用される頂点(ノード)集合を指定して作成できます。2部サブグラフには、左側の頂点集合と右側の頂点集合の間にのみエッジがあります。左側の2つの頂点(ノード)間など、これらの集合内にエッジはありません。インメモリー・アナリストでは、入力および出力エッジが削除されたために分離された頂点は、2部サブグラフの一部ではありません。
次の図は、2部サブグラフを示します。プロパティは示していません。
次の例では、図6-1で作成した単一のグラフから2部サブグラフを作成します。左側の頂点集合を作成し、それに頂点を入力します。
シェルを使用した2部サブグラフ作成
opg> s = graph.createVertexSet() ==> ... opg> s.addAll([graph.getVertex(333), graph.getVertex(99)]) ==> ... opg> s.size() ==> 2 opg> bGraph = graph.bipartiteSubGraphFromLeftSet(s) ==> PGX Bipartite Graph named sample-sub-graph-4
Javaを使用した2部サブグラフ作成
import oracle.pgx.api.*; VertexSet<Integer> s = graph.createVertexSet(); s.addAll(graph.getVertex(333), graph.getVertex(99)); BipartiteGraph bGraph = graph.bipartiteSubGraphFromLeftSet(s);
サブグラフを作成すると、インメモリー・アナリストで、頂点が左側にあるかどうかを示すブール頂点(ノード)プロパティが自動的に作成されます。このプロパティには一意の名前を指定できます。
結果の2部サブグラフは次のようになります。
頂点1908は2部サブグラフから除外されます。頂点に繋がっている唯一のエッジは、128から1908に伸びています。エッジはサブグラフの2部プロパティに反しているため削除されています。頂点1908にはその他のエッジがないため、これも削除されています。
親トピック: サブグラフの作成
6.8 グラフを使用したパターンマッチング問合せの使用
インメモリー・グラフに対してパターンマッチング問合せを発行してから、その問合せの結果を操作できます。
パターンマッチング問合せの例のデータ・セット
パターンマッチングの例では、2つの異なるデータ・セットを使用します。
-
政治家、スポーツ選手、著名人および会社の間の関係
-
装置、結線およびスイッチが含まれる電気ネットワーク
PGQLを使用したパターンマッチング問合せの発行
Property Graph Suery Language (PGQL)でグラフのパターンマッチング問合せを発行できます。PGQLは、SQLに似た宣言言語で、頂点とエッジ、および頂点とエッジのプロパティに関する制約で構成されたパターンを表現できます。
インメモリー・アナリストに対する問合せを発行するには、PgxGraph
(session
を使用してグラフをロードするときに取得するオブジェクトのタイプ)のqueryPgql()
Javaメソッドを使用します。
次のトピックでは、問合せのパターンマッチングを使用します。
6.8.1 例: 敵の敵は味方である
このトピックの例では、古来の有名な格言である「敵の敵は味方である」から着想を得たグラフ・パターンについて説明します。特に、このグラフには、2つのfeuds
エッジ・ラベルによって接続された2つのエンティティが含まれます。頂点は、人々、一族または国を表します。互いに反目する頂点のペアは、feuds
エッジ・ラベルが付けられたエッジを持ちます。
このような問合せは、次のようにPGQLで作成されます。
SELECT x.name, z.name WHERE (x) -[e1:feuds]-> (y), (y) -[e2:feuds]-> (z), x != y ORDER BY x.name, z.name
この問合せでは、結果はx.name
によって順序付けされた後、z.name
順序付けされます。
PGXに対する問合せの発行:
シェルの例:
opg> resultSet = connectionsGraph.queryPgql("SELECT x.name, z.name WHERE (x) -[e1:feuds]-> (y), (y) -[e2:feuds]-> (z), x != z ORDER BY x.name, z.name")
Javaの例:
import oracle.pgx.api.*; ... PgqlResultSet resultSet = connectionsGraph.queryPgql("SELECT x.name, z.name WHERE (x) -[e1:feuds]-> (y), (y) -[e2:feuds]-> (z), x != z ORDER BY x.name, z.name");
PgqlResultSet
は、問合せの結果セットを管理します。結果セットには、複数の結果が含まれます(このような問合せでは、多くのサブグラフが照合される場合があります)。各結果は、結果要素のリストで構成されています。結果要素の順序は、問合せのSELECT
句内の変数の順序に従います。
問合せ結果を反復することは、一連のPgqlResultElement
インスタンスを反復することを意味します。PgqlResultElement
は、結果要素の型および変数名を保持します。
PgqlResultElement
インスタンスのリストは、次のように取得できます。
シェルの例:
opg> resultElements = resultSet.getPgqlResultElements()
Javaの例:
import oracle.pgx.api.*; import java.util.List; ... List<PgqlResultElement> resultElements = resultSet.getPgqlResultElements();
最初の結果要素の型および変数名を取得します。
シェルの例:
opg> resultElement = resultElements.get(0) opg> type = resultElement.getElementType() // STRING opg> varName = resultElement.getVarName() // x.name
Javaの例:
import oracle.pgx.api.*; ... PgqlResultElement resultElement = resultElements.get(0); PqglResultElement.Type = resultElement.getElementType(); // STRING String varName = resultElement.getVarName(); // x.name
ループのfor-eachスタイルを使用して結果セットを反復します。ループ内では、問合せ結果が含まれるPgqlResult
インスタンスを取得します。
シェルの例:
opg> resultSet.getResults().each { \ // the variable 'it' is implicitly declared to references each PgqlResult instance }
Javaの例:
import oracle.pgx.api.*; ... for (PgqlResult result : resultSet.getResults()) { ... }
シェル内では、PqglResultSet
のprint
メソッドを使用してテキスト形式で結果セットを適切に印刷できます。
opg> resultSet.print(10) // print the first 10 results
次の結果が表示されます。
-------------------------------- | x.name | z.name | ================================ | ABC | CBS | | ABC | NBC | | Alibaba | Beyonce | | Alibaba | Google | | Alibaba | eBay | | Amazon | Carl Icahn | | Amazon | Facebook | | Amazon | Tencent | | Angela Merkel | Barack Obama | | Angela Merkel | John Kerry | --------------------------------
個々のPgqlResult
インスタンスまたはそれらの要素のハンドルを取得することもできます。
結果要素の索引別:
opg> nameX = it.getString(0) opg> nameZ = it.getString(1)
結果要素の変数名別:
opg> nameX = it.getString("x.name") opg> nameZ = it.getString("z.name")
型を知らずに結果要素を取得することもできます。
opg> nameX = it.get(0) // or opg> nameX = it.get("x.name")
親トピック: グラフを使用したパターンマッチング問合せの使用
6.8.2 例: 協力者の最も多い上位10人
この例では、グラフ内の協力者の最も多い上位10人を協力者の数の降順で見つけます。このような問合せではPGQLの様々な機能を活用しますが、これには、WHERE句で見つかったグラフ・パターンのグループ化、集計、順序付けおよび制限が含まれます。次の問合せ文字列は、PGQLでのユーザーの照会を表します。
opg> resultSet = connectionsGraph.queryPgql("SELECT x.name, COUNT(*) AS num_collaborators WHERE (x) -[:collaborates]-> () GROUP BY x ORDER BY DESC(num_collaborators) LIMIT 10")
この問合せでは、次の処理を実行します。
-
`collaborates'エッジ・ラベルを照合することにより、グラフから協力関係パターンをすべて見つけます。
-
見つかったパターンをソース頂点別にグループ化します。
-
各グループにカウント集計を適用し、協力者の数を見つけます。
-
協力者の数別に降順でグループに順序を付けます。
-
最初の10個の結果のみを採用します。
print()
メソッドは、問合せの結果を表示し、この例では、グラフ内で協力者の最も多い上位10人の名前および協力者数を表示します。
opg> resultSet.print()
次の結果が表示されます。
--------------------------------------------------- | x.name | num_collaborators | =================================================== | Barack Obama | 10 | | Charlie Rose | 4 | | Omar Kobine Layama | 3 | | Dieudonne Nzapalainga | 3 | | Nicolas Guerekoyame Gbangou | 3 | | NBC | 3 | | Pope Francis | 3 | | Beyonce | 2 | | Eric Holder | 2 | | Tom Steyer | 2 | ---------------------------------------------------
親トピック: グラフを使用したパターンマッチング問合せの使用
6.8.3 例: 電気装置間の推移的な接続性
この例では、頂点間で到達可能性をテストします。
ここでは、次の図の電気ネットワークのグラフを使用します。(データファイルは/opt/oracle/oracle-spatial-graph/property_graph/data/electric-network/electric_graph.edge.json
にあります。)
この例では、グラフ内のすべてのDevice
が他のすべてのDevice
と推移的に接続されているかどうかを確認しようとしてします。装置は、Connection
頂点およびSwitch
頂点によって接続されています。
最初に、次のPGQL問合せを発行することにより、グラフ内にいくつの装置があるか確認します。
SELECT COUNT(*) AS numDevices WHERE (n:Device)
結果は6031です。
-------------- | numDevices | ============== | 6031 | --------------
装置ごとに、ゼロ以上Connection
またはSwitch
頂点(および必要なエッジ)を辿ることによって到達できる装置の数を計算します。この問合せは、次のようにPGQLで表すことができます。
PATH connects_to := () <- (/*:Connection|Switch*/) -> () SELECT n.nickname AS device, count(m) AS reachabilityCount WHERE (n:Device) -/:connects_to*/-> (m:Device) GROUP BY n ORDER BY COUNT(m), n.nickname
この問合せでは、隣接する2つの装置/接続の間の明確な接続がパス・パターンconnects_to
を使用して表されています。クリーネ・スター(*)は、推移的接続を確認することを目的として、パス・パターンがゼロ以上の回数繰り返して一致する可能性があることを表しています。(インメモリー・アナリストではこの機能がまだサポートされていないため、パス・パターン内のラベルはコメントアウトされます。)
この問合せでは、GROUP BY
を使用して、ソース装置n
ごとにグループを作成してから、到達可能な宛先装置m
の数を計算します。最初の20の結果は次のとおりです。
------------------------------------------------ | device | reachabilityCount | ================================================ | 190-7361-M1089120 | 6031 | | 190-8581-D5587291-3_INT | 6031 | | 190-8593-D5860423-3_INT | 6031 | | 196-29518-L3122816 | 6031 | | 196-29519-L3066815 | 6031 | | 196-29520-L3160109 | 6031 | | 196-29521-N1136355 | 6031 | | 196-31070-D5861005-2_INT | 6031 | | 196-35541-M1108317 | 6031 | | 196-35813-N1140519 | 6031 | | 196-36167-L3011298 | 6031 | | 198-5320-221-311359 | 6031 | | 221-240988-L3141411 | 6031 | | 221-240991-L3066817 | 6031 | | 221-242079-L3011293 | 6031 | | 221-282818-N1230123 | 6031 | | 221-282819-N1230122 | 6031 | | 221-306686-L2970258 | 6031 | | 221-306687-L2916625 | 6031 | | 221-308718-L2803199 | 6031 | ------------------------------------------------
結果はreachabilityCount
の数を増加させることによってソートされるため、および結果内の最初の装置でさえグラフ内のすべての装置に推移的に接続されるため(reachabilityCount = 6031
)、ここでは、グラフ内のすべての装置が相互に完全に到達可能であることが分かります。
親トピック: グラフを使用したパターンマッチング問合せの使用
6.9 インメモリー・アナリスト・サーバーの起動
Big Data Spatial and Graphには、スクリプトの実行によってインメモリー・アナリスト・サーバーを起動できるApache Tomcatの事前構成済バージョンがバンドルされています。
サーバーを起動する前に構成する必要がある場合は、「インメモリー・アナリスト・サーバーの構成」を参照してください。
サーバーを起動するには、スクリプト/opt/oracle/oracle-spatial-graph/property_graph/pgx/bin/start-server
を実行します
6.9.1 インメモリー・アナリスト・サーバーの構成
インメモリー・アナリスト・サーバーは、/opt/oracle/oracle-spatial-graph/property_graph/pgx/conf/server.confファイルを変更することによって構成できます。次の表は、JSON形式で指定できる有効な構成オプションを示します。
表6-2 インメモリー・アナリスト・サーバーの構成オプション
オプション | 型 | 説明 | デフォルト |
---|---|---|---|
authorization |
string |
クライアントを認可のロールにマップするファイル。 |
server.auth.conf |
ca_certs |
stringの配列 |
信頼できる証明書のリスト(PEM形式)。'enable_tls'がfalseに設定されている場合、このオプションは無効です。 |
[この表の後の情報を参照してください。] |
enable_client_authentication |
boolean |
trueの場合、クライアントはTLSハンドシェイク時に認証されます。詳細は、TLSプロトコルを参照してください。'enable_tls'がfalseである場合、このフラグは無効です。 |
true |
enable_tls |
boolean |
trueの場合、トランスポート層セキュリティ(TLS)が有効になります。 |
true |
port |
integer |
PGXサーバーがリッスンする必要があるポート |
7007 |
server_cert |
string |
TLSクライアントに提示されるサーバー証明書へのパス(PEM形式)。'enable_tls'がfalseに設定されている場合、このオプションは無効です |
null |
server_private_key |
string |
サーバーの秘密キー(PKCS#8、PEM形式)。'enable_tls'がfalseに設定されている場合、このオプションは無効です |
null |
インメモリー・アナリストWebサーバーを使用すると、デフォルトで双方向のSSL/TLS (トランスポート層セキュリティ)が有効になります。このサーバーでは、TLS 1.2が適用され、攻撃に対して脆弱であることが知られている特定の暗号スイートが無効になります。TLSハンドシェイク時には、サーバーとクライアントの両方が相互に証明書を提示し合い、これらを使用して相手側の信頼性が検証されます。クライアント・アプリケーションの認可にはクライアント証明書も使用されます。
次に、server.conf
構成ファイルの例を示します。
{ "port": 7007, "server_cert": "certificates/server_certificate.pem", "server_private_key": "certificates/server_key.pem", "ca_certs": [ "certificates/ca_certificate.pem" ], "authorization": "auth/server.auth.conf", "enable_tls": true, "enable_client_authentication": true }
次に、server.auth.conf
構成ファイルの例を示します。マッピング・クライアント(アプリケーション)は、ロールに対する証明書のDN文字列によって識別されます。
{ "authorization": [{ "dn": "CN=Client, OU=Development, O=Oracle, L=Belmont, ST=California, C=US", "admin": false }, { "dn": "CN=Admin, OU=Development, O=Oracle, L=Belmont, ST=California, C=US", "admin": true }] }
サーバー構成ではクライアント側の認証またはSSL/TLS認証全体をオフにすることができます。ただし、任意の本番環境に対して双方向のSSL/TLSを有効にすることをお薦めします。
親トピック: インメモリー・アナリスト・サーバーの起動
6.10 Apache Tomcatへのデプロイ
インメモリー・アナリストはApache TomcatまたはOracle WebLogic Serverにデプロイできます。この例では、Webアプリケーションとしてインメモリー・アナリストをApache Tomcatにデプロイする方法を示しています。
注意:
これらのステップは、インメモリー・アナリストのテストのみを目的としています。本格的なデプロイメントの場合、正しい認証および認可を適用し、資格情報を安全に格納し、HTTPSを介して接続のみを許可するよう、Apache Tomcatを構成する必要があります。
親トピック: インメモリー・アナリスト(PGX)の使用
6.11 Oracle WebLogic Serverへのデプロイ
インメモリー・アナリストはApache TomcatまたはOracle WebLogic Serverにデプロイできます。
この例では、Webアプリケーションとしてインメモリー・アナリストをOracle WebLogic Serverにデプロイする方法を示しています。(Big Data Spatial and Graph 2.5.3はOracle WebLogic Server 12.2.1.3では機能しません)
注意:
これらのステップは、インメモリー・アナリストのテストのみを目的としています。本格的なデプロイメントの場合、正しい認証および認可を適用し、資格情報を安全に格納し、HTTPSを介して接続のみを許可するよう、WebLogic Serverを構成する必要があります。
6.11.1 Oracle WebLogic Serverのデプロイ
注意:
Big Data Spatial and Graph 2.5.3はOracle WebLogic Server 12.2.1.3では機能しません。
Oracle WebLogic Serverのダウンロードおよびインストールについては、次を参照してください。
https://www.oracle.com/technetwork/middleware/weblogic/downloads/wls-for-dev-1703574.html
親トピック: Oracle WebLogic Serverへのデプロイ
6.11.2 インメモリー・アナリストのデプロイ
Oracle WebLogicにインメモリー・アナリストをデプロイするには、次のようなコマンドを使用します。ユーザーの管理資格証明とWARファイルをこの例に示す値に入力します。
. $MW_HOME/user_projects/domains/mydomain/bin/setDomainEnv.sh . $MW_HOME/wlserver/server/bin/setWLSEnv.sh java weblogic.Deployer -adminurl http://localhost:7001 -username username -password password -deploy -source $PGX_HOME/server/pgx-webapp-wls.war
スクリプトが正常に実行されると、次のようなメッセージが表示されます。
Target state: deploy completed on Server myserver
親トピック: Oracle WebLogic Serverへのデプロイ
6.11.3 サーバーが動作していることの確認
サーバーに接続できることを確認します。
$PGX_HOME/bin/pgx --base_url http://localhost:7001/pgx
親トピック: Oracle WebLogic Serverへのデプロイ
6.12 インメモリー・アナリスト・サーバーへの接続
プロパティ・グラフのインメモリー・アナリストがサーバーとしてデプロイされ、Hadoopクラスタ(またはApache TomcatあるいはOracle WebLogic上のWebアプリケーションとしてHadoopのないクライアント・システム)にインストールされた後、インメモリー・アナリスト・サーバーに接続できます。
6.12.1 インメモリー・アナリスト・シェルによる接続
インメモリー・アナリスト・インスタンスへの最も単純な接続方法は、サーバーのベースURLを指定することです。
--base_url
コマンド・ライン引数を使用して、そのベースURL上で実行されているサーバーに接続できます。たとえば、サーバーのSSL/TLSが無効であり、認証が必要なく、サーバーがhttp://localhost:8080/pgx
上で実行されている場合、次を入力することにより、PGXシェルを使用してサーバーに接続できます。
cd $PGX_HOME ./bin/opg --base_url http://scott:<password>@localhost:8080/pgx
同じ方法でリモート・インスタンスに接続できます。
サーバーにBASIC認証が必要である場合、次の例のようにユーザー名およびパスワードを指定できます。
./bin/opg --base_url http://localhost:8080/pgx --username scott --password <password-for-scott>
サーバーのSSL/TLSが有効である場合、--truststore
オプションを使用して、サーバー証明書を検証するために使用される信頼ストアへのパスを(JKS形式で)指定できます。
./bin/opg --base_url https://localhost:8080/pgx --truststore path/to/truststore.jks
サーバーの双方向SSL/TLSが有効である場合、--keystore
および–-password
オプションを使用して、クライアント証明書およびキーストア・パスワードが含まれるキーストア・ファイルを指定できます。
./bin/opg --base_url https://localhost:8080/pgx --truststore path/to/truststore.jks --keystore path/to/keystore.jks --password <password>
6.12.1.1 HTTPリクエストのロギングについて
インメモリー・アナリスト・シェルでは、デフォルトでデバッグ・メッセージをすべて非表示にします。どのHTTPリクエストが実行されたかを確認するには、この例に示すように、oracle.pgx
のログ・レベルをDEBUG
に設定します。
opg> :loglevel oracle.pgx DEBUG ===> log level of oracle.pgx logger set to DEBUG opg> session.readGraphWithProperties("sample_http.adj.json", "sample") 10:24:25,056 [main] DEBUG RemoteUtils - Requesting POST http://scott:<password>@localhost:8080/pgx/core/session/session-shell-6nqg5dd/graph HTTP/1.1 with payload {"graphName":"sample","graphConfig":{"uri":"http://path.to.some.server/pgx/sample.adj","separator":" ","edge_props":[{"type":"double","name":"cost"}],"node_props":[{"type":"integer","name":"prop"}],"format":"adj_list"}} 10:24:25,088 [main] DEBUG RemoteUtils - received HTTP status 201 10:24:25,089 [main] DEBUG RemoteUtils - {"futureId":"87d54bed-bdf9-4601-98b7-ef632ce31463"} 10:24:25,091 [pool-1-thread-3] DEBUG PgxRemoteFuture$1 - Requesting GET http://scott:<password>@localhost:8080/pgx/future/session/session-shell-6nqg5dd/result/87d54bed-bdf9-4601-98b7-ef632ce31463 HTTP/1.1 10:24:25,300 [pool-1-thread-3] DEBUG RemoteUtils - received HTTP status 200 10:24:25,301 [pool-1-thread-3] DEBUG RemoteUtils - {"stats":{"loadingTimeMillis":0,"estimatedMemoryMegabytes":0,"numEdges":4,"numNodes":4},"graphName":"sample","nodeProperties":{"prop":"integer"},"edgeProperties":{"cost":"double"}}
親トピック: インメモリー・アナリスト・シェルによる接続
6.12.2 Javaによる接続
Javaを使用してインメモリー・アナリストを初期化する場合、ベースURLを指定できます。この例は次のようになります。インメモリー・アナリスト・サーバーへのURLは、getInstance
API呼出しに提供されます。
import oracle.pg.nosql.*; import oracle.pgx.api.*; PgNosqlGraphConfig cfg = GraphConfigBuilder.forNosql().setName("mygraph").setHosts(...).build(); OraclePropertyGraph opg = OraclePropertyGraph.getInstance(cfg); ServerInstance remoteInstance = Pgx.getInstance("http://scott:tiger@hostname:port/pgx"); PgxSession session = remoteInstance.createSession("my-session"); PgxGraph graph = session.readGraphWithProperties(opg.getConfig());
Javaを使用した接続時に信頼ストア、キーストア、およびキーストア・パスワードを指定するには、javax.net.ssl.trustStore
、javax.net.ssl.keyStore
およびjavax.net.ssl.keyStorePassword
システム・プロパティをそれぞれ設定する必要があります。
親トピック: インメモリー・アナリスト・サーバーへの接続
6.13 PGXパーティション化グラフの使用
プロパティ・グラフをパーティション化グラフとしてインメモリー分析サーバー(PGX)にロードすると、メモリーが大幅に節約されます。
インメモリー・パーティション化グラフ・モデルは、グラフが異なる型の頂点およびエッジを持ち、それぞれの型の頂点またはエッジが異なるプロパティ・セットを持つ場合に特に適しています。
たとえば、人と場所を表すグラフでは、Person (個人)型の頂点にはName (名前)やBirthday (誕生日)などのプロパティがあり、Place (場所)型の頂点にはAddress (住所)などのプロパティがあります。同様に、PersonからPersonへのエッジにはMeeting date (面会日)などのプロパティがあり、PersonからPlaceへのエッジにはLives at floor (居住階)などのプロパティがある場合があります。
パーティション化グラフの使用には、次の考慮事項があります。
- NULL値を含むキーに対してGROUP BY集計を実行するPGQL問合せはサポートされていません。
- パーティション分析アルゴリズム(パーティション・オブジェクトを返すアナリスト・メソッド)、頂点フィルタまたはエッジ・フィルタを使用するアルゴリズムおよびDijkstraアルゴリズムはサポートされません。
- 一部の制約に従い、パーティション化グラフは変更セットを使用して変更できません。
- パーティション化グラフは、GraphBuilder APIを使用して作成できません。
- 既存のプロパティ・グラフ・スキーマ(NoSQLまたはApache HBase)からのグラフの読取り
既存のOracleプロパティ・グラフ・スキーマのグラフをパーティション形式で読み取るには、グラフのconfig
ファイルのpartition_while_loading
フラグをtrue
に設定します。 - CSVファイルからのグラフの読取り
次の例では、2つのCSVファイルからグラフを読み取り、メモリー内のパーティション化モデルにロードします。 - パーティション化グラフの頂点IDとエッジID
PGXはデフォルトで、グラフの頂点とエッジごとに一意の識別子の存在を強制しています。 - PGQLでのパーティション化グラフの問合せ
パーティション化グラフでは、一部の頂点またはエッジにすべてのプロパティが定義されていない場合があります。
親トピック: インメモリー・アナリスト(PGX)の使用
6.13.1 既存のプロパティ・グラフ・スキーマ(NoSQLまたはApache HBase)からのグラフの読取り
既存のOracleプロパティ・グラフ・スキーマのグラフをパーティション形式で読み取るには、グラフのconfig
ファイルのpartition_while_loading
フラグをtrue
に設定します。
次に、NoSQLの例を示します。
{
"format": "pg",
"db_engine": "nosql",
"partition_while_loading": "by_label",
"hosts": [
"my-host1:5000",
"my-host2:5000",
"my-host3:5000"
],
"store_name": "my-store",
"name": "my-graph",
"vertex_props": [{
"name": "prop",
"type": "float"
}],
"edge_props": [{
"name": "name",
"type": "string"
}, {
"name": "cost",
"type": "double"
}]
}
メモリー内のパーティション化モデルにグラフをロードしない場合は、partition_by_label
フラグの値をno
に設定します。
Apache HBaseから読み取られるグラフのconfig
ファイルまたはフラット・ファイル(opv
/ope
)にも同じpartition_by_label
フラグを設定できます。
親トピック: PGXパーティション化グラフの使用
6.13.2 CSVファイルからのグラフの読取り
次の例では、2つのCSVファイルからグラフを読み取り、メモリー内のパーティション化モデルにロードします。
{
"name": "simpleGraph",
"vertex_providers":[{
"name": "simpleVertexProvider",
"format": "csv",
"uris": ["simple.csv"],
"key_column": 0
}],
"edge_providers":[{
"name": "simpleEdgeProvider",
"format": "csv",
"uris": ["simple.csv"],
"source_vertex_provider":"simpleVertexProvider",
"destination_vertex_provider":"simpleVertexProvider",
"key_column": 0,
"source_column": 1,
"destination_column": 2
}]
}
メモリー内のパーティション化グラフにロードする構成ファイルは、次の例に示すように、プログラムによって作成することもできます。
HeterogeneousGraphConfigBuilder configBuilder = GraphConfigBuilder.forHeterogeneous().setName("simpleGraph");
FileEntityProviderConfigBuilder vertexProviderBuilder1 = new FileEntityProviderConfigBuilder(ProviderFormat.CSV)
.setName("simpleVertexProvider1")
.setKeyColumn(1)
.addUri("simple1.csv");
FileEntityProviderConfigBuilder vertexProviderBuilder2 = new FileEntityProviderConfigBuilder(ProviderFormat.CSV)
.setName("simpleVertexProvider2")
.setKeyColumn(1)
.addUri("simple2.csv");
FileEntityProviderConfigBuilder edgeProviderBuilder = new FileEntityProviderConfigBuilder(ProviderFormat.CSV)
.setName("simpleEdgeProvider")
.addUri("simple.csv")
.setSourceVertexProvider("simpleVertexProvider1")
.setDestinationVertexProvider("simpleVertexProvider2")
.setKeyColumn(1)
.setSourceColumn(2)
.setDestinationColumn(3);
HeterogeneousGraphConfig graphConfig = configBuilder
.addVertexProvider(vertexProviderBuilder1)
.addVertexProvider(vertexProviderBuilder2)
.addEdgeProvider(edgeProviderBuilder)
.build();
グラフのconfig
ファイルが生成されたら、通常のreadGraphWithProperties()
APIを使用して、グラフをPGXに読み込むことができます。
親トピック: PGXパーティション化グラフの使用
6.13.3 パーティション化グラフの頂点IDおよびエッジID
PGXはデフォルトで、グラフの頂点とエッジごとに一意の識別子の存在を強制しています。
これは、PgxGraph.getVertex(ID id)
およびPgxGraph.getEdge(ID id)
メソッド、または組込みのid()
メソッドを使用するPGQL問合せでこれらを取得できるようにするためです。このことは、パーティション化グラフの場合もそのままです。
IDを生成するデフォルトの方法は、グラフのロード中に指定されたキーを使用することです。その場合、各頂点はすべての型の頂点に対して一意である頂点キーを持つ必要があります。同様に、エッジはデフォルトでグラフ全体に対して一意のエッジ・キーを持つ必要があります。
ただし、パーティション化グラフでこのような識別子を定義するのは面倒であるため、vertex_id_strategy
およびedge_id_strategy
グラフ構成フィールドを値no_ids
に設定することによって、頂点またはエッジ(あるいはその両方)の要件を無効にできます。頂点(resp. edge
) IDを無効にすることは、前に示した頂点を含む、頂点(resp. edge
) IDを使用したAPIへの呼び出しをPGXが禁止することを意味します。
親トピック: PGXパーティション化グラフの使用
6.13.4 PGQLでのパーティション化グラフの問合せ
パーティション化グラフでは、一部の頂点またはエッジにすべてのプロパティが定義されていない場合があります。
このプロパティを持たない頂点またはエッジに対してプロパティ・アクセスが試行されると、PGQL問合せエンジンはこのアクセスの結果としてNULL値を提供し、問合せを続行します。このNULL値が式の残りの問合せで使用される場合、SQL 3値論理と同じルールが式の評価に使用されます。
ORDER BY句でのNULL値のソートがサポートされており、NULL値は、昇順の並べ替えを使用する場合はNULL以外の値の後に配置され、降順の並べ替えを使用する場合はNULL以外の値の前に配置されます。
親トピック: PGXパーティション化グラフの使用
6.14 PGXロード・バランシングおよび高可用性のためのHAProxyの使用
HAProxy (高可用性プロキシ)は、Webサーバーで着信リクエストを複数のエンドポイントに分散できる、TCP/HTTPロード・バランサおよびプロキシ・サーバーです。
高可用性を実現するために、HAProxyをインメモリー分析サーバー(PGX)と一緒に使用できます。このトピックの例では、PGXに接続するクライアントとしてopgシェルを使用します。
このトピックの手順を使用するには、「インメモリー・アナリスト・サーバーの起動」の説明に従って、インメモリー・アナリスト・サーバーがすでにインストールおよび構成されている必要があります。
- HAProxyがまだBig Data ApplianceまたはOracle Linuxディストリビューションにインストールされていない場合は、次のコマンドを実行します。
yum install haproxy
- PGXサーバーを起動します。
たとえば、Big Data Applianceの4つのノード(bda02、bda03、bda04、bda05など)にわたってPGXをロード・バランシングする場合は、これらの各ノードでPGXを開始し、ポート7007をリッスンします。
- HAProxyを構成します。
次の内容を含む新しいファイル
haproxy.cfg
を作成します。(この例では、HAProxyはホストbda01上のポート8888をリッスンします)global maxconn 50000 log /dev/log local0 defaults mode http option httplog log global option forwardfor timeout connect 5s timeout client 5s timeout server 5s balance source hash-type consistent listen www bind :8888 server web1 bda02:7007 check server web2 bda03:7007 check server web3 bda04:7007 check server web4 bda05:7007 check
balance source
を指定すると、クライアントのIPアドレスが対応するサーバーのIPアドレスにマップされます。PGXサーバーは分析セッション中にセッションのスティッキネスに依存するため、これは重要です。(HAProxyの構成の詳細は、http://cbonte.github.io/haproxy-dconv/2.0/intro.htmlの公式ドキュメントを参照してください。) - ロード・バランサを起動します。
前の手順で作成した構成ファイルを渡すことによって、bda01のHAProxyを起動します。
haproxy -- haproxy.cfg
- ロード・バランサをテストします。
任意のクライアント・ホストから、エンドポイントをbase_urlパラメータとしてopgクライアント・シェルに渡して、HAProxyサーバーに接続します。次に例を示します。
cd /opt/oracle/oracle-spatial-graph/property_graph ./bin/opg --base_url http://bda01:8888
サーバーが停止すると、インメモリー状態は失われます。HAProxyはコマンドを別のサーバーにルーティングしますが、クライアントはグラフをロードしたスクリプトを再実行するなどを行う必要があります。
一連のPGXコマンドを実行してセッション・アフィニティをテストすることをお薦めします。サーバーを強制終了し、opgシェルを再起動して、HAProxyがリクエストを新しいサーバーにリダイレクトしていることを確認します。
親トピック: インメモリー・アナリスト(PGX)の使用
6.15 HDFSでのデータの読取りおよび格納
インメモリー・アナリストでは、Hadoop Distributed File System (HDFS)をサポートしています。この例では、インメモリー・アナリストAPIを使用してHDFSのグラフ・データを読み取り、アクセスする方法を示しています。
グラフ構成ファイルはクライアント側で解析されます。グラフ・データと構成ファイルはHDFSに格納されます。Hadoopクライアントはインメモリー分析と同じコンピュータにインストールする必要があります。『Oracle Big Data Applianceソフトウェア・ユーザーズ・ガイド』を参照してください。
注意:
インメモリー・アナリスト・エンジンは、Hadoopクラスタの1つのノードのメモリーでのみ実行されます。
6.15.1 HDFSからのデータの読込み
この例では、sample.adj
グラフ・データとその構成ファイルをHDFSにコピーし、それをメモリーに読み込みます。
-
グラフ・データをHDFSにコピーします。
cd $PGX_HOME hadoop fs -mkdir -p /user/pgx hadoop fs -copyFromLocal ../examples/pgx/graphs/sample.adj /user/pgx
-
グラフ構成ファイル
sample.adj.json
のuri
フィールドを、HDFSリソースを指し示すように編集します。{ "uri": "hdfs:/user/pgx/sample.adj", "format": "adj_list", "node_props": [{ "name": "prop", "type": "integer" }], "edge_props": [{ "name": "cost", "type": "double" }], "separator": " " }
-
構成ファイルをHDFSにコピーします。
cd $PGX_HOME hadoop fs -copyFromLocal ../examples/pgx/graphs/sample.adj.json /user/pgx
-
次の例に示すように、HDFSからサンプル・グラフをインメモリー・アナリストに読み込みます。
シェルを使用したHDFSからのグラフの読込み
g = session.readGraphWithProperties("hdfs:/user/pgx/sample.adj.json"); ===> PgxGraph[name=sample,N=4,E=4,created=1475525438479]
Javaを使用したHDFSからのグラフの読込み
import oracle.pgx.api.*; PgxGraph g = session.readGraphWithProperties("hdfs:/user/pgx/sample.adj.json");
親トピック: HDFSでのデータの読取りおよび格納
6.15.2 グラフ・スナップショットのHDFSへの格納
インメモリー・アナリストのバイナリ形式(.pgb
)は、インメモリー・アナリスト独自のバイナリ・グラフ形式です。基本的に、.pgb
ファイルはグラフとそのプロパティ・データのバイナリ・ダンプであり、インメモリー・アナリスト操作を効率的にします。この形式を使用すると、グラフ・スナップショットをディスクにすぐにシリアル化し、後でメモリーに読み込んで戻すことができます。
既存の.pgb
ファイルは変更しないでください。
次の例では、HDFSで、現在メモリー内にあるサンプル・グラフをPGB形式でHDFSに格納します。
シェルを使用したグラフのHDFSへの格納
g.store(Format.PGB, "hdfs:/user/pgx/sample.pgb", VertexProperty.ALL, EdgeProperty.ALL, true)
Javaを使用したグラフのHDFSへの格納
import oracle.pgx.config.GraphConfig; import oracle.pgx.api.*; GraphConfig pgbGraphConfig = g.store(Format.PGB, "hdfs:/user/pgx/sample.pgb", VertexProperty.ALL, EdgeProperty.ALL, true);
PGBファイルが作成されたことを確認するには、/user/pgx
HDFSディレクトリでファイルをリストします。
hadoop fs -ls /user/pgx
親トピック: HDFSでのデータの読取りおよび格納
6.15.3 HadoopでのJavaアプリケーションのコンパイルおよび実行
前の例のHdfsDemo
Javaクラスを次に示します。
import oracle.pgx.api.Pgx; import oracle.pgx.api.PgxGraph; import oracle.pgx.api.PgxSession; import oracle.pgx.api.ServerInstance; import oracle.pgx.config.Format; import oracle.pgx.config.GraphConfig; import oracle.pgx.config.GraphConfigFactory; public class HdfsDemo { public static void main(String[] mainArgs) throws Exception { ServerInstance instance = Pgx.getInstance(Pgx.EMBEDDED_URL); instance.startEngine(); PgxSession session = Pgx.createSession("my-session"); GraphConfig adjConfig = GraphConfigFactory.forAnyFormat().fromPath("hdfs:/user/pgx/sample.adj.json"); PgxGraph graph1 = session.readGraphWithProperties(adjConfig); GraphConfig pgbConfig = graph1.store(Format.PGB, "hdfs:/user/pgx/sample.pgb"); PgxGraph graph2 = session.readGraphWithProperties(pgbConfig); System.out.println("graph1 N = " + graph1.getNumVertices() + " E = " + graph1.getNumEdges()); System.out.println("graph2 N = " + graph1.getNumVertices() + " E = " + graph2.getNumEdges()); } }
これらのコマンドは、HdfsDemo
クラスをコンパイルします。
cd $PGX_HOME mkdir classes javac -cp ../lib/'*' HdfsDemo.java -d classes
このコマンドはHdfsExample
クラスを実行します。
java -cp ../lib/*:conf:classes:$HADOOP_CONF_DIR HdfsDemo
親トピック: HDFSでのデータの読取りおよび格納
6.16 PGX RESTエンドポイントの使用の開始
PGX REST APIを使用すると、Java以外の言語でインメモリー・アナリストとやりとりして独自のクライアントを実装できます。
PGX RESTエンドポイントの使用に際し、このトピックでは次のことを前提としています。
- curlを含むLinuxがインストールされていること。(curlは、RESTエンドポイントと対話するための単純なコマンドライン・ユーティリティです。)
- PGXサーバーが起動し、
http://localhost:7007
で稼働していること。 - PGXサーバーで認証/認可が無効になっていること。これはデフォルト以外の設定で、本番用には推奨されません (
/opt/oracle/oracle-spatial-graph/property_graph/pgx/conf/server.conf
内)。"enable_tls": false
- PGXを使用すると、ローカル・ファイル・システムからのグラフの読取りが可能になります。これはデフォルト以外の設定で本番用には推奨されません(
/opt/oracle/oracle-spatial-graph/property_graph/pgx/conf/pgx.conf
内)。:"allow_local_filesystem": true
サポートされるエンドポイントの完全なリストを表示するには、http://localhost:7007/swagger.json
を開きます。
- ステップ1: CSRFトークンの取得
- ステップ2:セッションの作成
- ステップ3:グラフの読込み
- ステップ4:プロパティの作成
- ステップ5: PageRankアルゴリズムの実行
- ステップ6: PGQL問合せの実行
ステップ1: CSRFトークンの取得
CSRFトークンをリクエストします。
curl -v http://localhost:7007/token
レスポンスは次のようになります。
* Trying 127.0.0.1... * Connected to localhost (127.0.0.1) port 7007 (#0) > GET /token HTTP/1.1 > Host: localhost:7007 > User-Agent: curl/7.47.0 > Accept: */* > < HTTP/1.1 201 < SET-COOKIE: _csrf_token=9bf51c8f-1c75-455e-9b57-ec3ca1c63cc0;Version=1; HttpOnly < Content-Length: 0
レスポンス内に表示されるとおり、cookie _csrf_token
はトークン値に設定されます。この例で、9bf51c8f-1c75-455e-9b57-ec3ca1c63cc0
は後続のリクエストに対するトークンです。書込みリクエストの場合、PGXサーバーではcookieとペイロードの両方に同じトークンが存在している必要があります。
ステップ2:セッションの作成
新規セッションを作成するには、JSONペイロードを送信します。
curl -v --cookie '_csrf_token=9bf51c8f-1c75-455e-9b57-ec3ca1c63cc0' -H 'content-type: application/json' -X POST http://localhost:7007/core/v1/sessions -d '{"source":"my-application", "idleTimeout":0, "taskTimeout":0, "timeUnitName":"MILLISECONDS", "_csrf_token":"9bf51c8f-1c75-455e-9b57-ec3ca1c63cc0"}'
my-applicationを、実行中のアプリケーションを示す値に置き換えます。この値は、サーバー管理者がセッションをアプリケーションにマッピングするために使用できます。アイドル・タイムアウトおよびタスク・タイムアウトを0に設定した場合、セッションおよび送信されたタスクがタイムアウトするタイミングをサーバーが決定することを意味します。cookieヘッダーとJSONペイロードの両方に同じCSRFトークンを指定する必要があります。レスポンスは次のようになります。
* Trying 127.0.0.1... * Connected to localhost (127.0.0.1) port 7007 (#0) > POST /core/v1/sessions HTTP/1.1 > Host: localhost:7007 > User-Agent: curl/7.47.0 > Accept: */* > Cookie: _csrf_token=9bf51c8f-1c75-455e-9b57-ec3ca1c63cc0 > content-type: application/json > Content-Length: 159 > * upload completely sent off: 159 out of 159 bytes < HTTP/1.1 201 < SET-COOKIE: SID=abae2811-6dd2-48b0-93a8-8436e078907d;Version=1; HttpOnly < Content-Length: 0
レスポンスにより、作成されたセッションID値にcookieが設定されます。セッションID abae2811-6dd2-48b0-93a8-8436e078907d
は、後続のリクエストの例として使用されます。
ステップ3:グラフの読込み
注意:
事前ロードしたグラフまたは別のセッションによってすでに公開されているグラフを分析する場合は、このステップをスキップできます。事前ロードしたグラフまたは公開したグラフにアクセスするために必要な情報は、グラフの名前のみです。
グラフを読み込むには、次の例に示すように、グラフ構成をJSONとしてサーバーに送信します。
curl -v -X POST --cookie '_csrf_token=9bf51c8f-1c75-455e-9b57-ec3ca1c63cc0;SID=abae2811-6dd2-48b0-93a8-8436e078907d' http://localhost:7007/core/v1/loadGraph -H 'content-type: application/json' -d '{"graphConfig":<graph-config>,"graphName":null,"_csrf_token":"9bf51c8f-1c75-455e-9b57-ec3ca1c63cc0"}'
<graph-config>を、実際のPGXグラフ構成のJSON表現に置換します。Apache HBaseからプロパティ・グラフを読み込むグラフ構成の例を次に示します。
{
"format": "pg",
"db_engine": "hbase",
"zk_quorum": "hbasenode01:2181",
"name": "my_graph",
"edge_label": true,
"edge_props": [{
"name": "cost",
"type": "double"
}],
"error_handling": {
"on_prop_conversion": "silent"
}
}
"graphName": null
を渡すと、サーバーに名前を生成するよう通知します。
サーバーは、次のように応答します。
* upload completely sent off: 315 out of 315 bytes < HTTP/1.1 202 < Location: http://localhost:7007/core/v1/futures/8a46ef65-01a9-4bd0-87d3-ffe9dfd2ce3c/status < Content-Type: application/json;charset=utf-8 < Content-Length: 51 < Date: Mon, 05 Nov 2018 17:22:22 GMT < * Connection #0 to host localhost left intact {"futureId":"8a46ef65-01a9-4bd0-87d3-ffe9dfd2ce3c"}
非同期リクエストについて
PGX RESTエンドポイントの大部分は非同期です。結果が完成するまで接続をオープンしたままにしないで、PGXサーバーはタスクとして送信し、将来のIDをステータス・コード200でただちに返します。このIDは、クライアントがタスクのステータスを定期的にリクエストしたり、終了後に結果値をリクエストするために使用できます。前のレスポンスから、次のような将来のステータスをリクエストできます。
curl -v --cookie 'SID=abae2811-6dd2-48b0-93a8-8436e078907d' http://localhost:7007/core/v1/futures/8a46ef65-01a9-4bd0-87d3-ffe9dfd2ce3c/status
これによって次のような値が返されます。
< HTTP/1.1 200 < Content-Type: application/json;charset=utf-8 < Content-Length: 730 < Date: Mon, 05 Nov 2018 17:35:19 GMT < * Connection #0 to host localhost left intact {"id":"eb17f75b-e4c1-4a66-81a0-4ff0f8b4cb92","links":[{"href":"http://localhost:7007/core/v1/futures/eb17f75b-e4c1-4a66-81a0-4ff0f8b4cb92/status","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"http://localhost:7007/core/v1/futures/eb17f75b-e4c1-4a66-81a0-4ff0f8b4cb92","rel":"abort","method":"DELETE","interaction":["async-polling"]},{"href":"http://localhost:7007/core/v1/futures/eb17f75b-e4c1-4a66-81a0-4ff0f8b4cb92/status","rel":"canonical","method":"GET","interaction":["async-polling"]},{"href":"http://localhost:7007/core/v1/futures/eb17f75b-e4c1-4a66-81a0-4ff0f8b4cb92/value","rel":"related","method":"GET","interaction":["async-polling"]}],"progress":"succeeded","co
ステータスの他に(この場合は"succeeded")、この出力では、タスクを取り消す(DELETE)ためのリンク、および完了後にタスクの結果を取得するためのリンク(GET <future-id>/value
)が提供されます。
curl -X GET --cookie 'SID=abae2811-6dd2-48b0-93a8-8436e078907d' http://localhost:7007/core/v1/futures/cdc15a38-3422-42a1-baf4-343c140cf95d/value
サーバーで生成された名前を含む、ロードされたグラフの詳細を返します(sample
)。
{"id":"sample","links":[{"href":"http://localhost:7007/core/v1/graphs/sample","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"http://localhost:7007/core/v1/graphs/sample","rel":"canonical","method":"GET","interaction":["async-polling"]}],"nodeProperties":{"prop1":{"id":"prop1","links":[{"href":"http://localhost:7007/core/v1/graphs/sample/properties/prop1","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"http://localhost:7007/core/v1/graphs/sample/properties/prop1","rel":"canonical","method":"GET","interaction":["async-polling"]}],"dimension":0,"name":"prop1","entityType":"vertex","type":"integer","transient":false}},"vertexLabels":null,"edgeLabel":null,"metaData":{"id":null,"links":null,"numVertices":4,"numEdges":4,"memoryMb":0,"dataSourceVersion":"1536029578000","config":<graph-config>,"creationRequestTimestamp":1541242100335,"creationTimestamp":1541242100774,"vertexIdType":"integer","edgeIdType":"long","directed":true},"graphName":"sample","edgeProperties":{"cost":{"id":"cost","links":[{"href":"http://localhost:7007/core/v1/graphs/sample/properties/cost","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"http://localhost:7007/core/v1/graphs/sample/properties/cost","rel":"canonical","method":"GET","interaction":["async-polling"]}],"dimension":0,"name":"cost","entityType":"edge","type":"double","transient":false}},"ageMs":0,"transient":false}
<graph-config>には、リクエストで送信したグラフ構成が含まれます。
簡略化のために、同期タスクのステータスまたは値の追加のリクエストはここではスキップされています。
ステップ4:プロパティの作成
ロードされたグラフでPageRankアルゴリズムを実行する場合もあります。そのためには、計算されたランク値を保持できるグラフ上で、DOUBLE型の頂点プロパティを作成する必要があります。
curl -v -X POST --cookie '_csrf_token=9bf51c8f-1c75-455e-9b57-ec3ca1c63cc0;SID=abae2811-6dd2-48b0-93a8-8436e078907d' http://localhost:7007/core/v1/graphs/sample/properties -H 'content-type: application/json' -d '{"entityType":"vertex","type":"double","name":"pagerank", "hardName":false,"dimension":0,"_csrf_token":"9bf51c8f-1c75-455e-9b57-ec3ca1c63cc0"}'
返される将来の結果をリクエストすると、次のような結果が返されます。
{"id":"pagerank","links":[{"href":"http://localhost:7007/core/v1/graphs/sample/properties/pagerank","rel":"self","method":"GET","interaction":["async-polling"]},{"href":"http://localhost:7007/core/v1/graphs/sample/properties/pagerank","rel":"canonical","method":"GET","interaction":["async-polling"]}],"dimension":0,"name":"pagerank","entityType":"vertex","type":"double","transient":true}
ステップ5:PageRankアルゴリズムの実行
次の例は、アルゴリズムを呼び出す方法を示しています。アルゴリズムIDはURLの一部であり、アルゴリズムに渡すパラメータはJSONペイロードの一部です。
curl -v -X POST --cookie '_csrf_token=9bf51c8f-1c75-455e-9b57-ec3ca1c63cc0;SID=abae2811-6dd2-48b0-93a8-8436e078907d' http://localhost:7007/core/v1/analyses/pgx_builtin_k1a_pagerank/run -H 'content-type: application/json' -d '{"args":[{"type":"GRAPH","value":"sample"},{"type":"DOUBLE_IN","value":0.001},{"type":"DOUBLE_IN","value":0.85},{"type":"INT_IN","value":100},{"type":"BOOL_IN","value":true},{"type":"NODE_PROPERTY","value":"pagerank"}],"expectedReturnType":"void","workloadCharacteristics":["PARALLELISM.PARALLEL"],"_csrf_token":"9bf51c8f-1c75-455e-9b57-ec3ca1c63cc0"}'
将来の作業が完了すると、結果は次のようになります。
{"success":true,"canceled":false,"exception":null,"returnValue":null,"executionTimeMs":50}
ステップ6:PGQL問合せの実行
PageRankアルゴリズムの結果を問い合せるには、次の例に示すようにPGQL問合せを実行します。
curl -v -X POST --cookie '_csrf_token=9bf51c8f-1c75-455e-9b57-ec3ca1c63cc0;SID=abae2811-6dd2-48b0-93a8-8436e078907d' http://localhost:7007/core/v1/pgql/run -H 'content-type: application/json' -d '{"pgqlQuery":"SELECT x.pagerank MATCH (x) WHERE x.pagerank > 0","semantic":"HOMOMORPHISM", "schemaStrictnessMode":true, "graphName" : "sample", "_csrf_token":"9bf51c8f-1c75-455e-9b57-ec3ca1c63cc0"}'
結果は、問合せの結果セットと対話するために使用できるリンクのセットです。
{"id":"pgql_1","links":[{"href":"http://localhost:7007/core/v1/pgqlProxies/pgql_1","rel":"self","method":"GET","interaction":["sync"]},{"href":"http://localhost:7007/core/v1/pgqlResultProxies/pgql_1/elements","rel":"related","method":"GET","interaction":["sync"]},{"href":"http://localhost:7007/core/v1/pgqlResultProxies/pgql_1/results","rel":"related","method":"GET","interaction":["sync"]},{"href":"http://localhost:7007/core/v1/pgqlProxies/pgql_1","rel":"canonical","method":"GET","interaction":["async-polling"]}],"exists":true,"graphName":"sample","resultSetId":"pgql_1","numResults":4}
結果セットの最初の2048要素をリクエストするには、次を送信します。
curl -X GET --cookie 'SID=abae2811-6dd2-48b0-93a8-8436e078907d' http://localhost:7007/core/v1/pgqlProxies/pgql_1/results?size=2048
レスポンスは次のようになります。
{"id":"/pgx/core/v1/pgqlProxies/pgql_1/results","links":[{"href":"http://localhost:7007/core/v1/pgqlProxies/pgql_1/results","rel":"self","method":"GET","interaction":["sync"]},{"href":"http://localhost:7007/core/v1/pgqlProxies/pgql_1/results","rel":"canonical","method":"GET","interaction":["async-polling"]}],"count":4,"totalItems":4,"items":[[0.3081206521195582],[0.21367103988538017],[0.21367103988538017],[0.2645372681096815]],"hasMore":false,"offset":0,"limit":4,"showTotalResults":true}
親トピック: インメモリー・アナリスト(PGX)の使用
6.17 Oracleの2つの表関係形式の使用
リレーショナル・データ・モデルを使用する場合、グラフ・データは2つのリレーショナル表を使用して表現できます。1つの表はノードとそのプロパティ用で、もう1つの表はエッジとそのプロパティ用です。
インメモリー・アナリストでは、2つのリレーショナル(RDBMS)表がノードとエッジを表すようなリレーショナル・グラフ表現でグラフを読み込むことができます。必要なのは、グラフのconfig
オブジェクトで次の追加フィールドを指定することのみです。
表6-3 2つの表形式の追加フィールド
フィールド | 型 | 説明 | デフォルト |
---|---|---|---|
edges_key_column |
string |
エッジ表内の主キー列の名前 |
eid |
edges_table_name |
string |
エッジ表の名前 |
null |
from_nid_column |
string |
ソース・ノードの列名 |
svid |
insert_batch_size |
integer |
挿入する行のバッチ・サイズ |
10000 |
max_prefetched_rows |
integer |
ラウンドトリップ時にプリフェッチされた行の最大数(結果セット - データベース)。 |
10000 |
nodes_key_column |
string |
ノード表内の主キー列の名前 |
vid |
nodes_table_name |
string |
ノード表の名前 |
null |
num_connections |
integer |
2つの表から/にデータを読み取る/書き込むための接続数 |
<no-of-cpus> |
schema |
string |
表の書込み先のスキーマ |
null |
tablespace |
string |
表の書込み先の表領域 |
users |
to_nid_column |
string |
宛先ノードの列名 |
dvid |
vertex_id_type |
enum[long, string] |
頂点IDの型 |
long |
注意:
2つの表形式を使用してOracle DatabaseからOracle Big Data Spatial and Graphインメモリー・アナリストにデータを直接読み込むには、次の1つ以上のライセンスが必要です。-
Oracle Big Data Appliance上のOracle Big Data Spatial and Graphライセンス、または
-
サポートされている別の構成上のOracle Big Data Spatial and Graphライセンス、およびOracle Database Enterprise Editionシステム上のOracle Spatial and Graphオプションのライセンス。
Oracle Big Data Spatial and Graphのライセンスの詳細は、『Oracle Big Data Applianceライセンス情報ユーザー・マニュアル』を参照してください。
-
2つの表形式の使用例
-
NULL値の処理方法
2つの表形式の使用例
次の例では、次の表に示す値を使用して、2つのリレーション表(NODESおよびEDGES)からグラフ・データを読み込みます。
表6-4 2つの表の例のノード表値
nid | NP1 | NP2 | NP3 |
---|---|---|---|
1829107 |
“hello” |
06/06/2012 |
0.30 |
1829179 |
“world” |
06/08/2012 |
0.999 |
表6-5 2つの表の例のエッジ表値
eid | from_nid | to_nid | EP1 | EP2 | EP3 |
---|---|---|---|---|---|
21123 |
1829107 |
1829179 |
“alpha” |
06/06/2012 |
10.5 |
48180 |
1788817 |
1829179 |
“beta” |
06/08/2012 |
22.3 |
これらの表からデータをグラフとしてロードするには、最初に構成ファイルを作成する必要があります。この構成ファイルには、表名、ユーザー名などが含まれています。
構成ファイルにパスワードを渡すには、Oracle JDKとともに自動的にインストールされるkeytoolコマンドライン・ユーティリティを使用して、新しいJavaキーストア・ファイルを作成します。次に例を示します。
keytool -importpass -alias database1 -keystore keystore.jks
次の入力を求めるプロンプトが表示されます。
- キーストア・ファイルへのアクセスを保護するためのオプションのキーストア・パスワード。
- 格納する実際のパスワード。これは後で
database1
などの指定された別名と関連付けられます。複数のパスワードを同じキーストア・ファイルに格納できます。
別のパスワードを追加するには、異なる別名パラメータを使用して同じコマンドを再度使用します。次に例を示します。
keytool -importpass -alias database2 -keystore keystore.jks
keytoolコマンドの使用方法の詳細は、JDKのドキュメントhttps://docs.oracle.com/javase/8/docs/technotes/tools/unix/keytool.html#CHDBGFHEを参照してください。
シークレットを含むキーストア・ファイルがある場合、そのファイルをPGXに登録する必要があります。
-
クライアント・シェルを使用している場合は、
--secret-store
コマンドライン・オプションを使用してファイルを登録できます。次に例を示します。./bin/opg --secret_store path/to/keystore.jks
-
Javaアプリケーションを記述している場合は、グラフをメモリーに読み取る前に、
PgxSession#registerKeystore(keystorePath, keystorePassword)
APIを使用してキーストアを登録します。
キーストアが現在のセッションに登録されたら、グラフ構成ファイルをパスワードではなく別名を参照するように変更します。次に例を示します。
{
"jdbc_url": "jdbc:oracle:thin:@localhost:1521:rdbmsod",
"format": "two_tables",
"datastore": "rdbms",
"username": "scott",
"keystore_alias": "database1",
"nodes_table_name": "nodes",
"edges_table_name": "edges",
"node_props": [{
"name": "NP1",
"type": "string"
},{
"name": "NP2",
"type": "date"
},{
"name": "NP3",
"type": "double"
}],
"edge_props": [{
"name": "EP1",
"type": "string"
},{
"name": "EP2",
"type": "date"
},{
"name": "EP3",
"type": "float"
}]
}
その後、通常のAPIを使用してグラフを読み取ります。たとえば、PgxGraph graph = session.readGraphWithProperties("config.json")
などです。
NULL値の処理方法
インメモリー・アナリストの場合、ノードまたはエッジ内のプロパティ値をnullにすることはできません。このため、ノードまたはエッジ表内のプロパティ値がnullに設定されている場合は常に、代わりにデフォルト値が割り当てられます。config
オブジェクトに指定されていない場合、デフォルト値はプロパティ・タイプのJavaデフォルト値です(たとえば、double
に対する0.0など)。
ただし、次の例に示すように、config
オブジェクトに異なるデフォルト値を指定することもできます。
{
"name": "NP1",
"type": "double",
"default": 1.0
}
親トピック: インメモリー・アナリスト(PGX)の使用
6.18 インメモリー・アナリストApache Zeppelinインタプリタの使用
インメモリー・アナリストには、Apache Zeppelinのインタプリタ実装が用意されています。このチュートリアルのトピックでは、ローカルのZeppelinインストールにインメモリー・アナリスト・インタプリタをインストールし、いくつかの簡単な操作を実行する方法について説明します。
インタプリタのインストール
次のステップはZeppelinバージョン0.8.1を使用してテストしたものであり、これよりバージョンが新しい場合は変更する必要がある場合があります。
-
Apache Zeppelinのダウンロードおよびインストールがまだ完了していない場合は、これらを実行します。
-
インメモリー・アナリスト・インタプリタのパッケージを見つけます: /opt/oracle/oracle-spatial-graph/property_graph/pgx/client/pgx-<version>-zeppelin-interpreter.zip
-
公式のインタプリタのインストール・ステップに従います。
-
インメモリー・アナリスト・インタプリタのパッケージを
$ZEPPELIN_HOME/interpreter/pgx
に解凍します。 -
$ZEPPELIN_HOME/conf/zeppelin-site.xml
を編集し、インメモリー・アナリストZeppelinインタプリタ・クラスnameoracle.pgx.zeppelin.PgxInterpreter
をzeppelin.interpreters
プロパティ・フィールドに追加します。 -
次のステップ(Zeppelinの再起動)の前に、CLASSPATH設定を消去します。Linuxシステムでは、シェルで
unset CLASSPATH
を実行します。 -
Zeppelinを再起動します。
-
Zeppelinインタプリタ・ページで、「+Create」ボタンをクリックし、インタプリタ・グループ
pgx
の新しいインタプリタを追加します。
-
-
新しいインメモリー・アナリスト・インタプリタを構成します。
-
「interpreter for note」のオプションを選択します。
-
Shared: すべてのノートが同じインメモリー・アナリスト・セッションを共有します(非推奨)。
-
Scoped: すべてのノートが独自のインメモリー・アナリスト・セッションを取得しますが、同じプロセスを共有します(推奨)。
-
Isolated: すべてのノートが独自のインメモリー・クライアント・シェル・プロセスを取得します。これが最高の分離レベルですが、Zeppelinインタプリタを実行しているシステム上で不要なリリースが消費される可能性があります。
-
-
pgx.baseUrlについては、インメモリー・アナリスト・インタプリタがリモートのインメモリー・アナリスト・サーバーと通信するクライアントのように機能するため、インメモリー・アナリスト・サーバーが実行されているベースURLを少なくとも指定する必要があります。
-
インタプリタの使用
インメモリー・アナリスト・インタプリタにpgx
という名前を付けた場合、他の任意のインタプリタの場合と同じように、パラグラフの先頭を%pgx
ディレクティブにすることにより、パラグラフをインメモリー・アナリスト・インタプリタに送信できます。
インメモリー・アナリストZeppelinインタプリタは、インメモリー・アナリストと同じ方法でパラグラフを評価し、出力を返します。したがって、次の例のように、任意の有効なインメモリー・アナリスト・シェル・スクリプトがインメモリー・アナリスト・インタプリタ内で動作します。
%pgx
g_brands = session.readGraphWithProperties("/opt/data/exommerce/brand_cat.json")
g_brands.getNumVertices()
rank = analyst.pagerank(g_brands, 0.001, 0.85, 100)
rank.getTopKValues(10)
次の図は、その問合せのアイコンをクリックして実行した後の結果を示します。
この図から分かるように、インメモリー・アナリストZeppelinインタプリタは、rank.getTopKValues(10)
から返された値をZeppelin表としてレンダリングすることにより、結果をより便利に閲覧しやすくします。
プロパティ値(getTopKValues()、getBottomKValues()およびgetValues()
)以外にも、次の戻り型がパラグラフから返される場合、これらも表として自動的にレンダリングされます。
-
PgqlResultSet
-PgxGraph
クラスのqueryPgql("...")
メソッドから返されるオブジェクト -
MapIterable
-PgxMap
クラスのentries()
メソッドから返されるオブジェクト
他のすべての戻り型およびエラーは、インメモリー・アナリスト・シェルによる場合と同じように、標準の文字列として返されます。
Zeppelinの詳細は、公式のZeppelinドキュメントを参照してください。
親トピック: インメモリー・アナリスト(PGX)の使用
6.19 インメモリー・アナリスト・エンタープライズ・スケジューラの使用
インメモリー・アナリスト・エンタープライズ・スケジューラには、高度なスケジューリング機能が用意されています。
注意:
高度なスケジューリング機能は現在、Linux (x86_64)、Mac OS X (x86_64)およびSolaris (x86_64、SPARC)に対してのみ使用可能です。
このチュートリアルのトピックでは、インメモリー・アナリスト・エンタープライズ・スケジューラの高度なスケジューリング機能を使用する方法を示します。次について説明します。
-
インメモリー・アナリスト・サーバーの構成による高度なスケジューリング機能の有効化方法
-
実行環境の取得および検査方法
-
実行環境の変更方法および実行環境でのタスクの実行方法
高度なスケジューリング機能の有効化
高度なスケジューリング機能を有効にするには、インメモリー・アナリスト・インスタンス構成のフラグallow_override_scheduling_information
をtrue
に設定します。
{ "allow_override_scheduling_information": true }
実行環境の取得および検査
実行環境はセッションにバインドされています。セッションの実行環境を取得するには、PgxSession
に対してgetExecutionEnvironment()
を呼び出します。
opg> execEnv = session.getExecutionEnvironment() ==> ExecutionEnvironment[session=576af1fd-73aa-4866-abf0-00a71757d75b]
実行環境は、3つのサブ環境(タスク・タイプごとに1つ)に分割されます。
-
IO環境: IOタスク用
-
分析環境: CPUバウンドの分析タスク用
-
高速分析環境: 軽量だがCPUバウンドの分析タスク用
実行環境の現在の状態を問い合せるには、getValues()
メソッドを呼び出します。
opg> execEnv.getValues() ==> io-pool.num_threads_per_task=72 ==> analysis-pool.max_num_threads=72 ==> analysis-pool.weight=72 ==> analysis-pool.priority=MEDIUM ==> fast-track-analysis-pool.max_num_threads=72 ==> fast-track-analysis-pool.weight=1 ==> fast-track-analysis-pool.priority=HIGH
サブ環境を取得するには、getIoEnvironment()
、getAnalysisEnvironment()
およびgetFastAnalysisEnvironment()
メソッドを使用します。各サブ環境には、サブ環境の構成を取得するために独自のgetValues()
メソッドが用意されています。
opg> ioEnv = execEnv.getIoEnvironment() ==> IoEnvironment[pool=io-pool] opg> ioEnv.getValues() ==> num_threads_per_task=72 opg> analysisEnv = execEnv.getAnalysisEnvironment() ==> CpuEnvironment[pool=analysis-pool] opg> analysisEnv.getValues() ==> max_num_threads=72 ==> weight=72 ==> priority=MEDIUM opg> fastAnalysisEnv = execEnv.getFastAnalysisEnvironment() ==> CpuEnvironment[pool=fast-track-analysis-pool] opg> fastAnalysisEnv.getValues() ==> max_num_threads=72 ==> weight=1 ==> priority=HIGH
実行環境の変更および更新済環境でのタスクの発行
IoEnvironment
のsetNumThreadsPerTask()
メソッドを使用することにより、I/O環境のスレッドの数を変更できます。この値は即時更新され、更新後に発行されたタスクはすべて、更新された値を使用して実行されます。
opg> ioEnv.setNumThreadsPerTask(8) ==> 8 opg> g = session.readGraphWithProperties(...) ==> PgxGraph[name=graph,N=3,E=6,created=0]
環境を初期値にリセットするには、reset()
メソッドを呼び出します。
opg> ioEnv.reset() ==> null
CPU環境の場合、setWeight()、setPriority()およびsetMaxThreads()メソッドを使用してスレッドの重み、優先度および最大数を変更できます。
opg> analysisEnv.setWeight(50) ==> 50 opg> fastAnalysisEnv.setMaxThreads(1) ==> 1 opg> rank = analyst.pagerank(g) ==> VertexProperty[name=pagerank,type=double,graph=graph]
ExecutionEnvironment
に対してreset()
を呼び出すと、すべての環境を一度にリセットできます。
opg> execEnv.reset() ==> null
6.19.1 実行環境でのラムダ構文の使用
ラムダ構文を使用して、実行環境で使用するステップを結合できます。通常、この環境は次の方法で使用されます。
-
実行環境の設定
-
タスクの実行
-
実行環境のリセット
これらのステップを簡単にするために、これら3つのステップを結合するためのメソッドが用意されています。setメソッドごとに、更新された値をとるwith接頭辞および更新された値を使用して実行する必要があるラムダを使用するメソッドがあります。たとえば、setNumThreadsPerTask()の代わりに、次のように呼び出すことができるwithNumThreadsPerTask()と呼ばれるメソッドがあります。
-
JavaアプリケーションでJava 8ラムダを使用する場合:
import oracle.pgx.api.*; import oracle.pgx.api.executionenvironment.*; PgxGraph g = ioEnv.withNumThreadsPerTask(8, () -> session.readGraphWithPropertiesAsync(...));
-
インメモリー・アナリスト・シェルでGroovyのクロージャを使用する場合:
opg> g = ioEnv.withNumThreadsPerTask(8, { session.readGraphWithPropertiesAsync(...) } ) ==> PgxGraph[name=graph,N=3,E=6,created=0]
これらは両方とも、次の空き指定のシーケンスと等価です。
oldValue = ioEnv.getNumThreadsPerTask() ioEnv.setNumThreadsPerTask(currentValue) g = session.readGraphWithProperties(...) ioEnv.setNumThreadsPerTask( oldValue )