4.7 グラフ・スナップショットのディスクへの格納

Javaまたはシェルを使用してグラフをメモリーに読み込んだ後、PageRankアルゴリズムの実行や頂点プロパティとしての値の保存など、グラフに変更を加えた場合は、このグラフのスナップショットをディスクに保存できます。

これは、新しいバージョンに移行するためにインメモリー・グラフ・サーバーを停止する必要がある場合や、他のなんらかの理由でサーバーを停止する必要がある場合など、グラフの状態をメモリーに保存する際に役立ちます。

(HTTP/RESTへのグラフの格納は現在サポートされていません)。

グラフの状態をメモリーに保存する場合、たとえば新しいバージョンに移行するためにインメモリー・グラフ・サーバーを停止する必要がある場合や、他のなんらかの理由でサーバーを停止する必要がある場合は、グラフのスナップショットをバイナリ形式のファイル(PGBファイルと呼ばれる)で保存できます。

一般的には、実行されたグラフ問合せおよび分析APIを保存し、インメモリー・グラフ・サーバーを再起動した後、APIを再ロードして再実行することをお薦めします。ただし、グラフの状態を保存する必要がある場合は、次の例のロジックを使用して、シェルからグラフ・スナップショットを保存できます。

3層デプロイメントでは、ファイルはサーバー側のファイル・システムに書き込まれます。また、書き込むファイルの場所がインメモリー・グラフ・サーバーで指定されていることを確認する必要があります。(Autonomous Databaseを使用したOracle Graphの3層デプロイメントで説明されているように、3層デプロイメントでは、PGXサーバー・ファイル・システムにアクセスするには、許可されている場所のリストを指定する必要があります。)

opg4j> var graph = session.createGraphBuilder().addVertex(1).addVertex(2).addVertex(3).addEdge(1,2).addEdge(2,3).addEdge(3, 1).build()
graph ==> PgxGraph[name=anonymous_graph_1,N=3,E=3,created=1581623669674]

opg4j> analyst.pagerank(graph)
$3 ==> VertexProperty[name=pagerank,type=double,graph=anonymous_graph_1]

// Now save the state of this graph
opg4j> graph.store(Format.PGB, "/scratch/PG/snapshot/snapshot.pgb")
$16 ==> {"edge_uris":[],"error_handling":{},"attributes":{},"format":"pgb","vertex_props":[{"type":"double","name":"pagerank","dimension":0}],"edge_props":[],"vertex_
id_type":"integer","vertex_uris":["/scratch/PG/snapshot/snapshot.pgb"],"loading":{}}

// reload from disk 
opg4j> var graphFromDisk = session.readGraphFile("/scratch/PG/snapshot/snapshot.pgb", Format.PGB)
graphFromDisk ==> PgxGraph[name=snapshot,N=3,E=3,created=1635791377443]

// previously computed properties are still part of the graph and can be queried
opg4j> graphFromDisk.queryPgql("SELECT x.pagerank MATCH (x)").print().close()
+--------------------+
| x.pagerank         |
+--------------------+
| 0.3333333333333333 |
| 0.3333333333333333 |
| 0.3333333333333333 |
+--------------------+

次の例は基本的に前の例と同じですが、パーティション化されたグラフを使用しています。まず、パーティション化されたグラフをグラフ・サーバー(PGX)にロードする必要があります。例については、GraphConfigBuilderの使用によるグラフ・サーバー(PGX)へのパーティション化されたグラフのロードを参照してください。

opg4j> analyst.pagerank(graph)
$8 ==> VertexProperty[name=pagerank,type=double,graph=bank_graph_partitioned]

// Now save the state of this graph
opg4j>  var storedPgbConfig = graph.store(ProviderFormat.PGB, "/scratch/PG/snapshot/snapshot_")
storedPgbConfig ==> {"vertex_id_strategy":"KEYS_AS_IDS","loading":{},"array_compaction_threshold":0.2,"time_with_timezone_format":["h[h]:m[m][:s[s]] a[ XXX]","[
yyyy-MM-dd'T']H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSSSSS]][XXX]"],"name":"bank_graph_partitioned","timestamp_with_timezone_format":
["yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSSSSS]][XXX]"],"edge_providers":[
{"loading":{"create_key_mapping":true},"destination_vertex_provider":"node","destination_column":3,"format":"pgb","time_format":["h[h]:m[m][:s[s][.SSS]] a[ XXX]
","[yyyy-MM-dd'T']H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSSSSS]][XXX]"],"key_type":"long","has_keys":true,"label":"transfer","source_
column":2,"storing":{"base_path":"/scratch/PG/snapshot/snapshot_transfer","edge_extension":"pgb"},"attributes":{},"timestamp_format":["yyyy-MM-dd'T'H[H]:m[m][:s
[s][.SSS[SSS]]][XXX]","yyyy-MM-dd H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSSSSS]][XXX]"],"time_with_timezone_format":["h[h]:m[m][:s[s]
] a[ XXX]","[yyyy-MM-dd'T']H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSSSSS]][XXX]"],"timestamp_with_timezone_format":["yyyy-MM-dd'T'H[H]
:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSSSSS]][XXX]"],"props":[{"drop_after_loading":false,
"type":"long","column":4,"name":"FROM_ACCT_ID","dimension":0},{"drop_after_loading":false,"type":"long","column":5,"name":"TO_ACCT_ID","dimension":0},{"drop_aft
er_loading":false,"type":"long","column":6,"name":"AMOUNT","dimension":0}],"header":false,"source_vertex_provider":"node","error_handling":{},"uris":["/scratch/
PG/snapshot/snapshot_transfer.pgb"],"key_column":1,"local_date_format":["yyyy-M[M]-d[d]","M[M]/d[d]/yyyy","d[d]-MMM-yyyy","d[d]-M[M]-yyyy","yyyy-MM-dd'T'H[H]:
m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSSSSS]][XXX]"],"name":"transfer"}],"local_date_format":["yyyy-M[M]-d[d]","M[M]/d[d]/yyyy","d[d]-MMM
-yyyy","d[d]-M[M]-yyyy","yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSSSSS]][XXX]"],"vertex_id_type":"long","optimized_for":
"READ","max_prefetched_rows":10000,"num_connections":2,"max_batch_size":10000,"error_handling":{"on_missing_vertex":"ERROR"},"scroll_time":"1m","time_format":[
"h[h]:m[m][:s[s][.SSS]] a[ XXX]","[yyyy-MM-dd'T']H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSSSSS]][XXX]"],"edge_id_strategy":"KEYS_AS_ID
S","attributes":{},"vertex_providers":[{"storing":{"vertex_extension":"pgb","base_path":"/scratch/PG/snapshot/snapshot_node"},"attributes":{},"loading":{"create
_key_mapping":true},"timestamp_format":["yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd'T'H[H]:m[m][:s
[s][.SSSSSS]][XXX]"],"time_with_timezone_format":["h[h]:m[m][:s[s]] a[ XXX]","[yyyy-MM-dd'T']H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd'T'H[H]:m[m][:s[s][.SS
SSSS]][XXX]"],"timestamp_with_timezone_format":["yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd'T'H[H]
:m[m][:s[s][.SSSSSS]][XXX]"],"props":[{"drop_after_loading":false,"type":"integer","column":2,"name":"ID","dimension":0},{"drop_after_loading":false,"type":
"double","column":3,"name":"pagerank","dimension":0}],"format":"pgb","time_format":["h[h]:m[m][:s[s][.SSS]] a[ XXX]","[yyyy-MM-dd'T']H[H]:m[m][:s[s][.SSS[SSS]]]
[XXX]","yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSSSSS]][XXX]"],"key_type":"long","header":false,"has_keys":true,"error_handling":{},"uris":["/scratch/PG/snapshot/snapsho
t_node.pgb"],"label":"node","key_column":1,"local_date_format":["yyyy-M[M]-d[d]","M[M]/d[d]/yyyy","d[d]-MMM-yyyy","d[d]-M[M]-yyyy","yyyy-MM-dd'T'H[H]:m[m][:s[s]
[.SSS[SSS]]][XXX]","yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSSSSS]][XXX]"],"name":"node"}],"timestamp_format":["yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-d
d H[H]:m[m][:s[s][.SSS[SSS]]][XXX]","yyyy-MM-dd'T'H[H]:m[m][:s[s][.SSSSSS]][XXX]"],"edge_id_type":"long"}

// Reload from disk 
opg4j> var graphFromDisk = session.readGraphWithProperties(storedPgbConfig)
graphFromDisk ==> PgxGraph[name=bank_graph_partitioned_3,N=1000,E=5001,created=1635790679596]

// Previously computed properties are still part of the graph and can be queried
opg4j> graphFromDisk.queryPgql("SELECT x.pagerank MATCH(x) LIMIT 5").print().close()
+-----------------------+
| x.pagerank            |
+-----------------------+
| 9.748675243734766E-4  |
| 0.004576976478097233  |
| 5.353395438612155E-4  |
| 0.0013043345794813302 |
| 0.001502117014779663  |
+-----------------------+

ノート:

パーティション化されたグラフの場合、複数のPGBファイル(グラフ内の頂点/エッジ・パーティションごとに1つ)が生成されます。