ヘッダーをスキップ
Oracle® Big Data Spatial and Graphユーザーズ・ガイドおよびリファレンス
リリース1.1
E70114-01
  目次へ移動
目次

前
次
 

5 インメモリー分析の使用

この章では、インメモリー分析を使用する例について説明します(プロパティ・グラフ・インメモリー分析とも呼ばれ、Javadoc、コマンドライン、パスの説明、エラー・メッセージなどではPGXと省略されます)。主なトピックは次のとおりです。

5.1 グラフのメモリーへの読込み

このトピックでは、シェル・インタフェースを使用したメモリーへの対話によるグラフの読込みの例について説明します。主な手順は次のとおりです。

  1. インメモリー分析サーバー・インスタンスへの接続

  2. シェル・ヘルプの使用(必要時)

  3. 構成ファイルでのグラフ・メタデータの指定

  4. グラフ・データのメモリーへの読込み

5.1.1 インメモリー分析サーバー・インスタンスへの接続

インメモリー分析シェルを開始する手順:

  1. プロパティ・グラフのサポートがインストールされているシステムで端末セッションを開始します。
  2. ローカル(埋込み)・インメモリー分析インスタンスを開始するか、リモート・インメモリー分析インスタンスに接続します
    • ローカル・(埋込み)インスタンス開始のJavaの例:
      import java.util.Map;
      import java.util.HashMap;
      import oracle.pgx.api.*;
      import oracle.pgx.config.PgxConfig.Field;
       
      String url = Pgx.EMBEDDED_URL; // local JVM
      ServerInstance instance = Pgx.getInstance(url);
      instance.startEngine(); // will use default configuration
      PgxSession session = instance.createSession("test");
    • リモート・インスタンスへの接続のJavaの例:
      import java.util.Map;
      import java.util.HashMap;
      import oracle.pgx.api.*;
      import oracle.pgx.config.PgxConfig.Field;
       
      String url = "http://my-server.com:8080/pgx" // replace with base URL of your setup
      ServerInstance instance = Pgx.getInstance(url);
      PgxSession session = instance.createSession("test");
  3. シェルでは、次のコマンドを入力しますが、開始コマンド、または必要なインスタンスのタイプへの接続コマンドのいずれか一方を選択します。
    cd $PGX_HOME
    ./bin/pgx --help
    ./bin/pgx --version
     
    # start embedded shell
    ./bin/pgx
     
    # start remote shell
    ./bin/pgx --base_url http://my-server.com:8080/pgx

    埋込みシェルの場合、出力は次のようになります。

    10:43:46,666 [main] INFO Ctrl$2 - >>> PGX engine running.
    pgx>
  4. オプションで、事前定義されている変数も表示します。
    pgx> instance
    ==> PGX Server Instance running on embedded mode
    pgx> session
    ==> PGX session pgxShell registered at PGX Server Instance running on embedded mode
    pgx> analyst
    ==> Analyst for PGX session pgxShell registered at PGX Server Instance running on embedded mode
    pgx>

    その他のトピックの例では、インスタンスおよびセッション変数は、ここで示すとおり設定されるとみなされます。

インメモリー分析ソフトウェアが正しくインストールされている場合、エンジン実行ログ・メッセージとインメモリー分析シェル・プロンプト(pgx>)が表示されます。

変数instancesession、およびanalystが使用可能です。

このトピックの前の例では、pgxコマンドでリモートURLを指定していないため、シェルがローカル・インスタンスを開始します。

5.1.2 シェル・ヘルプの使用

インメモリー分析シェルには、:helpコマンドを使用してアクセスできるヘルプ・システムが用意されています。

5.1.3 構成ファイルでのグラフ・メタデータの指定

/opt/oracle/oracle-spatial-graph/property_graph/examples/pgx/graphs/のインストール・ディレクトリにグラフの例が含まれています。ここでは、インメモリー分析がグラフを読み取る方法を説明する構成ファイルを使用します。

pgx> 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型のエッジ・プロパティで構成されていることを示します。

これは隣接するリスト形式のグラフ・データです。

pgx> 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

図5-1は、データから作成されたプロパティ・グラフを示します。

図5-1 sample.adjデータからレンダリングされたプロパティ・グラフ

「図5-1 sample.adjデータからレンダリングされたプロパティ・グラフ」の説明が続きます
「図5-1 sample.adjデータからレンダリングされたプロパティ・グラフ」の説明

5.1.4 グラフ・データのメモリーへの読込み

グラフをメモリーに読み込むには、次の情報を渡す必要があります。

  • グラフのメタデータを指定するグラフ構成ファイルへのパス

  • グラフへの参照に使用できる一意の英数字名

    同じ名前で別のグラフをすでにロードしている場合は、エラーが発生します。

例: シェルを使用したグラフの読取り

pgx> graph = session.readGraphWithProperties("/opt/oracle/oracle-spatial-graph/property_graph/examples/pgx/graphs/sample.adj.json", "sample");
==> PGX Graph named sample bound to PGX session pgxShell ...
pgx> graph.getNumVertices()
==> 4

例: Javaを使用したグラフの読取り

import oracle.pgx.api.*;
 
PgxGraph graph = session.readGraphWithProperties("/opt/oracle/oracle-spatial-graph/property_graph/examples/pgx/graphs/sample.adj.json");

次のトピックでは、プロパティ・グラフをメモリーに読み込むその他の例について説明します。

5.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"
  }],
  "load_edge_label": true,
  "edge_props": [{
    "name": "label",
    "type": "string"
  }, {
    "name": "weight",
    "type": "float"
  }]
}
EOF

次のコマンドを使用すると、プロパティ・グラフconnectionsがメモリーに読み込まれます。

pgx> session.readGraphWithProperties("/tmp/my_graph_hbase.json", "connections")
==> PGX Graph named connections ...

大きいサイズのグラフを扱う場合は、IOワーカー、分析対象のワーカー数、タスクのタイムアウトなどのパラメータを調整する必要があります。これらのパラメータは、次のディレクトリ(インストールのホームが/opt/oracle/oracle-spatial-graphの場合)で検索および変更できます。

/opt/oracle/oracle-spatial-graph/property_graph/pgx/conf

5.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"
  }],
  "load_edge_label": true,
  "edge_props": [{
    "name": "label",
    "type": "string"
  }, {
    "name": "weight",
    "type": "float"
  }]
}

次に、構成ファイルをメモリーに読み込みます。次の例では、スニペットがファイルをメモリーに読み込み、方向のないグラフ(名称U)を元のデータから生成し、三角形の数をカウントします。

pgx> g = session.readGraphWithProperties("/tmp/my_graph_nosql.json", "connections")
pgx> analyst.countTriangles(g, false)
==> 8

5.1.4.3 ローカル・ファイル・システムに格納されているグラフのメモリーへの読込み

次のコマンドでは、構成ファイルでのグラフ・メタデータの指定の構成ファイルおよびmy-graphという名前を使用します。

pgx> g = session.readGraphWithProperties("/opt/oracle/oracle-spatial-graph/property_graph/examples/pgx/graphs/sample.adj.json", "my-graph")

5.2 カスタム・グラフ・データの読取り

ユーザー独自のカスタム・グラフ・データを読み取ることができます。この例では、グラフを作成し、それを変更して正しく読み取る方法を表示します。このグラフでは隣接するリスト形式を使用しますが、インメモリー分析では、複数のグラフ形式をサポートしています。

主な手順は次のとおりです。

  1. 単純なグラフ・ファイルの作成

  2. 頂点プロパティの追加

  3. 頂点識別子としての文字列の使用

  4. エッジ・プロパティの追加

5.2.1 単純なグラフ・ファイルの作成

この例では、頂点またはエッジ・プロパティのない、単純な小さいグラフを隣接するリストに作成します。それぞれの線には、頂点(ノード) ID、およびそのエッジ点を送信する頂点IDが含まれます。

1 2
2 3 4
3 4
4 2

このリストでは、単一スペースで個々のトークンを区切ります。インメモリー分析ではその他のセパレータもサポートしており、グラフ構成ファイルで指定できます。

図5-2は、4つの頂点と5つのエッジのあるプロパティ・グラフとしてレンダリングされたデータを示します。頂点2から頂点4へのエッジは両方向であることを示しています。

図5-2 単純なカスタム・プロパティ・グラフ

「図5-2 単純なカスタム・プロパティ・グラフ」の説明が続きます
「図5-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();

5.2.2 頂点プロパティの追加

単純なグラフ・ファイルの作成のグラフは、頂点プロパティまたはエッジ・プロパティを使用しない頂点とエッジで構成されています。頂点プロパティは、それぞれの線の元の頂点IDに続いて配置されます。double頂点(ノード)プロパティがグラフに追加されると、グラフ・データは次のようになります。

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();

5.2.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)はサポートされていません。

5.2.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();

5.3 グラフ・データのディスクへの格納

グラフはJavaまたはシェルを使用してメモリーに読み込んだ後、別の形式でディスクに格納できます。格納したグラフ・データは、後でインメモリー分析への入力として使用できます。

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

オプションは次のとおりです。

5.3.1 頂点プロパティへの分析結果の格納

この例では、グラフをメモリーに読み込み、Pagerankアルゴリズムを使用して分析します。この分析では、PageRank値を格納する新しい頂点プロパティが作成されます。

シェルを使用したPageRankの実行

pgx> g = session.readGraphWithProperties("/opt/oracle/oracle-spatial-graph/property_graph/examples/pgx/graphs/sample.adj.json", "my-graph")
==> ...
pgx> 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);

5.3.2 エッジリスト形式でのグラフのディスクへの格納

この例では、グラフ、Pagerank分析の結果、および元のエッジ・プロパティすべてをエッジリスト形式でディスクに格納します。

グラフを格納するには、次を指定する必要があります。

  • グラフの形式

  • ファイルが格納されるパス

  • 格納されるプロパティ。VertexProperty.ALLまたはEdgeProperty.ALLを指定するとすべてのプロパティが格納され、VertexProperty.NONEまたはEdgePropery.NONEを指定すると、どのプロパティも格納されません。個々のプロパティを指定するには、格納するVertexPropertyまたはEdgePropertyオブジェクトを渡します。

  • 既存のファイルを同じ名前で上書きするかどうかを示すフラグ

次の例では、/tmp/sample_pagerank.elist.json構成ファイルでグラフ・データを/tmp/sample_pagerank.elistに格納します。戻り値はファイルに格納されているグラフ構成です。これは再度、グラフの読取りに使用できます。

シェルを使用したグラフの格納

pgx> config = g.store(Format.EDGE_LIST, "/tmp/sample_pagerank.elist", [rank], EdgeProperty.ALL, false)
==> {"node_props":[{"name":"session-12kta9mj-vertex-prop-double-2","type":"double"}],"error_handling":{},"node_id_type":"integer","uri":"/tmp/g.edge","loading":{},"edge_props":[{"name":"cost","type":"double"}],"format":"edge_list"}

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);

5.4 組込みアルゴリズムの実行

インメモリー分析には、一連の組込みアルゴリズムが含まれており、Java APIとして使用できます。このセクションでは、Triangle CountingおよびPagerank分析を使用したインメモリー分析の使用方法について説明します。

5.4.1 インメモリー分析について

インメモリー分析には、一連の組込みアルゴリズムが含まれており、Java APIとして使用できます。APIについて詳しくは、oracle.pgx.api.algorithmsパッケージの製品(デフォルトの/opt/oracle/oracle-spatial-graph/property_graph/doc/pgx)に同梱されているJavadocに記載されています。特に、サポートされているインメモリー分析のリストについては、BuiltinAlgorithmsインタフェースのメソッド・サマリーを参照してください。

たとえば、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 extends Comparable<ID>> VertexProperty<ID, Double> pagerank(PgxGraph graph, double e, double d, int max);

一方、Pagerankのインメモリー分析APIは次のとおりです。


5.4.2 Triangle Countingアルゴリズムの実行

Triangle Countingの場合、countTriangles()sortByDegreeブール・パラメータを使用して、グラフを最初に角度でソートする(true)かソートしない(false)かを制御します。trueの場合、さらに多くのメモリーが使用されますが、アルゴリズムの実行は高速になります。ただし、グラフが非常に大きい場合、この最適化をオフにしてメモリー不足を回避する必要があります。

シェルを使用したTriangle Countingの実行

pgx> analyst.countTriangles(graph, true)
==> 1

Javaを使用したTriangle Countingの実行

import oracle.pgx.api.*;
 
Analyst analyst = session.createAnalyst();
long triangles = analyst.countTriangles(graph, true);

このアルゴリズムでは、サンプル・グラフ内の1つの三角形を検出します。

ヒント:

インメモリー分析シェルを使用する場合、ロギング・レベルを変更すると、実行中のログ出力の量を増加できます。:h :loglevelを指定した:loglevelコマンドの実行に関する情報を参照してください。

5.4.3 Pagerankアルゴリズムの実行

Pagerankは、グラフ内のそれぞれの頂点(ノード)について、01の間のランク値を計算し、その値をdoubleプロパティに格納します。このため、アルゴリズムによって、出力に対してタイプdouble頂点プロパティが作成されます。

インメモリー分析では、頂点プロパティとエッジ・プロパティの2つのタイプがあります。

  • 永続プロパティ: データ・ソースからグラフとともにロードされ固定されたディスク上のデータのインメモリー・コピーであるため、永続となるプロパティ。永続プロパティは読取り専用のため変更できず、セッション間で共有されます。

  • 一時プロパティ: 一時プロパティには値が書き込めるため、セッションでプライベートに使用されます。一時プロパティは、PgxGraphcreateVertexPropertyおよびcreateEdgeProperty()を呼び出して作成できます。

この例では、Pagerank値が最も高い上位3つの頂点を取得します。タイプdoubleの一時頂点プロパティを使用して、計算したPagerank値を保持します。Pagerankアルゴリズムでは、最大誤差0.001、減衰係数0.85、および最大反復数100を使用します。

シェルを使用したPageRankの実行

pgx> rank = analyst.pagerank(graph, 0.001, 0.85, 100);
==> ...
pgx> 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());
}

5.5 サブグラフの作成

サブグラフはロードしたグラフに基づいて作成できます。フィルタ式を使用するか、2部グラフの左側の集合を指定する頂点(ノード)に基づく2部サブグラフを作成できます。

グラフのメモリーへの読込みについては、「グラフ・データのメモリーへの読込み」を参照してください。

5.5.1 フィルタ式について

フィルタ式は、各エッジで評価される式です。式によって、結果(この場合はサブグラフ)に含まれるようにエッジを完成させる述部を定義できます。

4つの頂点(ノード)と4つのエッジで構成される図5-1のグラフを検討します。フィルタ式src.prop == 10と一致するエッジについては、元の頂点のpropプロパティが10になります。図5-3に示すフィルタ式と一致する2つのエッジ。

図5-3 src.prop == 10と一致するエッジ

「図5-3 src.prop == 10と一致するエッジ」の説明が続きます
「図5-3 src.prop == 10と一致するエッジ」の説明

図5-4はフィルタを適用した結果のグラフを示します。フィルタは頂点333に対応するエッジ、およびその頂点自体を除外します。

図5-4 簡易フィルタで作成されたグラフ

「図5-4 簡易フィルタで作成されたグラフ」の説明が続きます
「図5-4 簡易フィルタで作成されたグラフ」の説明

フィルタ式を使用すると、単一の頂点または頂点集合の選択が難しくなります。たとえば、プロパティ値10の頂点のみは選択できません。これは、頂点を照合するには、10がソース・プロパティ値と宛先プロパティ値のいずれかであるエッジを照合する必要があるためです。ただし、エッジを一致させるときは、ソースの頂点、宛先の頂点、およびその結果のエッジ自体が自動的に含まれます。

5.5.2 簡易フィルタを使用したサブグラフの作成

次の例は、フィルタ式についてで説明したサブグラフの作成を示します。

シェルを使用したサブグラフの作成

subgraph = graph.filter(new VertexFilter("vertex.prop == 10"))

Javaを使用したサブグラフの作成

import oracle.pgx.api.*;
import oracle.pgx.api.filter.*;

PgxGraph graph = session.readGraphWithProperties(...);
PgxGraph subgraph = graph.filter(new VertexFilter("vertex.prop == 10"));

5.5.3 複合フィルタを使用したサブグラフの作成

この例では、少し複雑なフィルタを使用しています。ここでは、識別子の送信エッジの数(ソースsrcまたは宛先dst)を計算するoutDegree関数を使用します。次のフィルタ式は、costプロパティ値が50を超え、outDegreeが1を超える宛先の頂点(ノード)のエッジと一致します。

dst.outDegree() > 1 && edge.cost > 50

図5-5では、サンプル・グラフのエッジの1つがこのフィルタ式と一致します。

図5-5 outDegreeフィルタと一致するエッジ

「図5-5 outDegreeフィルタと一致するエッジ」の説明が続きます
「図5-5 outDegreeフィルタと一致するエッジ」の説明

図5-6はフィルタを適用した結果のグラフを示します。フィルタは頂点99と1908に対応するエッジを除外するため、その頂点も除外します。

図5-6 outDegreeフィルタで作成されたグラフ

「図5-6 outDegreeフィルタで作成されたグラフ」の説明が続きます
「図5-6 outDegreeフィルタで作成されたグラフ」の説明

5.5.4 頂点集合を使用した2部サブグラフの作成

2部サブグラフは、左側に使用される頂点(ノード)集合を指定して作成できます。2部サブグラフには、左側の頂点集合と右側の頂点集合の間にのみエッジがあります。左側の2つのノード間など、これらの集合内にエッジはありません。インメモリー分析では、入射および出射エッジが削除されたために分離された頂点は、2部サブグラフの一部ではありません。

次の図は、2部サブグラフを示します。プロパティは示していません。

次の例では、図5-1で作成した単一のグラフから2部サブグラフを作成します。左側の頂点集合を作成し、それに頂点を入力します。

シェルを使用した2部サブグラフ作成

pgx> s = graph.createVertexSet()
==> ...
pgx> s.addAll([graph.getVertex(333), graph.getVertex(99)])
==> ...
pgx> s.size()
==> 2
pgx> 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にはその他のエッジがないため、これも削除されています。

5.6 Jettyへのデプロイ

インメモリー分析は、Eclipse Jetty、Apache Tomcat、またはOracle WebLogicにデプロイできます。この例では、Webアプリケーションとしてインメモリー分析をEclipse Jettyにデプロイする方法を示しています。

  1. インメモリー分析Webアプリケーション・アーカイブ・(WAR)ファイルをJetty webappsディレクトリにコピーします。

    cd $PGX_HOME
    cp $PGX_HOME/webapp/pgx-webapp-1.0.0-for-cdh5.2.1.war $JETTY_HOME/webapps/pgx.war
    
  2. ユーザー名とパスワードのある場所を示すセキュリティ・レルムをJetty内に設定します。ファイルから資格証明を読み取る最も基本的なセキュリティ・レルムを追加するには、このスニペットを$JETTY_HOME/etc/jetty.xmlに追加します。

    <Call name="addBean">
      <Arg>
        <New class="org.eclipse.jetty.security.HashLoginService">
          <Set name="name">PGX-Realm</Set>
          <Set name="config">
            etc/realm.properties
          </Set>
          <Set name="refreshInterval">0</Set>
        </New>
      </Arg>
    </Call>
    

    このスニペットは、サポートされている最も単純なインメモリー・ログイン・サービス、HashLoginServiceを使用するようにJettyに指示します。このサービスでは、ユーザー名、パスワード、およびロールが格納されている構成ファイルを使用します。

  3. 次の形式で、ユーザーを$JETTY_HOME/etc/realm.propertiesに追加します。

    username: password, role
    

    たとえば、この行ではユーザーSCOTTをパスワードTIGERおよびUSERロールで追加します。

    scott: tiger, USER
    
  4. ポート8080が未使用であることを確認し、Jettyを開始します。

    cd $JETTY_HOME
    java -jar start.jar
    
  5. インストール用の適切な資格証明を使用して、Jettyが稼働していることを確認します。

    cd $PGX_HOME
    ./bin/pgx --base_url http://scott:tiger@localhost:8080/pgx
    
  6. (オプション)インメモリー分析構成ファイルを変更します。

    インメモリー分析エンジンの構成ファイル(pgx.conf)およびロギング・パラメータ(log4j.xml)は、WEB-INF/classesのWARファイル内にあります。サーバーを再起動して変更を有効にします。

関連項目:

構成および使用方法に関するJettyドキュメントは、次を参照してください

http://eclipse.org/jetty/documentation/

5.6.1 認証メカニズムについて

インメモリー分析のWebデプロイメントでは、デフォルトでBASIC Authを使用します。本番のデプロイメントでは、より安全な認証メカニズムに変更する必要があります。

認証メカニズムを変更するには、Webアプリケーション・アーカイブ(WAR)ファイルでweb.xmlデプロイメント記述子のsecurity-constraint要素を変更します。

5.7 Apache Tomcatへのデプロイ

インメモリー分析は、Eclipse Jetty、Apache Tomcat、またはOracle WebLogicにデプロイできます。この例では、Webアプリケーションとしてインメモリー分析をApache Tomcatにデプロイする方法を示しています。

インメモリー分析には、セキュリティ・レルムを必要とする有効なBASIC Authが提供されています。Tomcatでは、様々な種類のレルムをサポートしています。この例では、最も単純なMemoryRealmを構成します。その他の種類については、Tomcatレルムの設定方法を参照してください。

  1. インメモリー分析WARファイルをwebappsディレクトリにコピーします。次に例を示します。
    cd $PGX_HOME
    cp $PGX_HOME/webapp/pgx-webapp-1.0.0-for-cdh5.2.1.war $CATALINA_HOME/webapps/pgx.war
    
  2. エディタで$CATALINA_HOME/conf/server.xmlを開き、次のレルムのクラス宣言を<Engine>要素に追加します。
    <Realm className="org.apache.catalina.realm.MemoryRealm" />
    
  3. エディタでCATALINA_HOME/conf/tomcat-users.xmlを開き、USERロールのユーザーを定義します。この例では、scottおよびtigerを適切なユーザー名とパスワードに置き換えます。
    <role rolename="USER" />
    <user username="scott" password="tiger" roles="USER" />
    
  4. ポート8080が未使用であることを確認します。
  5. Tomcatを開始します。
    cd $CATALINA_HOME
    ./bin/startup.sh
    
  6. Tomcatが動作していることを確認します。
    cd $PGX_HOME
    ./bin/pgx --base_url http://scott:tiger@localhost:8080/pgx
    

注意:

Oracleでは、BASIC Authはテスト用としてのみ推奨します。その他すべてのデプロイメント・タイプについては、より強力な認証メカニズムを使用します。

関連項目:

Tomcatのドキュメントは、次を参照してください

http://tomcat.apache.org/tomcat-7.0-doc/

5.8 Oracle WebLogic Serverへのデプロイ

インメモリー分析は、Eclipse Jetty、Apache Tomcat、またはOracle WebLogic Serverにデプロイできます。この例では、Webアプリケーションとしてインメモリー分析をOracle WebLogic Serverにデプロイする方法を示しています。

5.8.1 Oracle WebLogic Serverのデプロイ

Oracle WebLogic Serverの最新バージョンをダウンロードし、インストールするには、次を参照してください

http://www.oracle.com/technetwork/middleware/weblogic/documentation/index.html

5.8.2 インメモリー分析のデプロイ

Oracle WebLogicにインメモリー分析をデプロイするには、次のようなコマンドを使用します。ユーザーの管理資格証明とWARファイルをこの例に示す値に入力します。

cd $MW_HOME/user_projects/domains/mydomain
. bin/setDomainEnv.sh
java weblogic.Deployer -adminurl http://localhost:7001 -username username -password password -deploy -upload $PGX_HOME/lib/server/pgx-webapp-0.9.0.war

スクリプトが正常に実行されると、次のようなメッセージが表示されます。

Target state: deploy completed on Server myserver

5.8.3 サーバーが動作していることの確認

サーバーに接続できることを確認します。

$PGX_HOME/bin/pgx --base_url scott:tiger123@localhost:7001/pgx

5.9 インメモリー分析サーバーへの接続

プロパティ・グラフのインメモリー分析がHadoopクラスタ、またはEclipse Jetty、Apache Tomcat、Oracle WebLogicのいずれかのWebアプリケーションとしてHadoopのないクライアント・システムにインストールした後は、インメモリー分析サーバーに接続できます。

5.9.1 インメモリー分析シェルによる接続

インメモリー分析インスタンスへの最も単純な接続方法は、サーバーのベースURLを指定することです。次のベースURLでは、SCOTTユーザーをポート8080でリスニングするローカル・インスタンスに接続できます。

http://scott:tiger@localhost:8080/pgx

このベースURLでインメモリー分析シェルを開始するには、--base_urlコマンドライン引数を使用します

cd $PGX_HOME
./bin/pgx --base_url http://scott:tiger@localhost:8080/pgx

同じ方法でリモート・インスタンスに接続できます。ただし、インメモリー分析では現在、Control APIのリモート・サポートは提供されていません。

5.9.1.1 HTTPリクエストのロギングについて

インメモリー分析シェルでは、デフォルトでデバッグ・メッセージをすべて非表示にします。どのHTTPリクエストが実行されたかを確認するには、この例に示すように、oracle.pgxのログ・レベルをDEBUGに設定します。

pgx> :loglevel oracle.pgx DEBUG
===> log level of oracle.pgx logger set to DEBUG
pgx> session.readGraphWithProperties("sample_http.adj.json", "sample")
10:24:25,056 [main] DEBUG RemoteUtils - Requesting POST http://scott:tiger@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:tiger@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"}}

この例のグラフURIは、インメモリー分析サーバーがHTTPまたはHDFSを使用してアクセスできるファイルを指し示している必要があります。

5.9.2 Javaによる接続

Javaを使用してインメモリー分析を初期化する場合、ベースURLを指定できます。この例は次のようになります。インメモリー分析サーバーへのURLがgetInMemAnalyst 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());

5.9.3 HTTPリクエストによる接続

インメモリー分析シェルでは、HTTPリクエストを使用してインメモリー分析サーバーと通信します。同じHTTPエンドポイントを直接使用、またはユーザーのクライアント・ライブラリへの書込みに使用できます。

この例では、HTTPを使用してcreate sessionを呼び出します。

HTTP POST 'http://scott:tiger@localhost:8080/pgx/core/session' with payload '{"source":"shell"}'
Response: {"sessionId":"session-shell-42v3b9n7"}

create sessionのコールによって、セッション識別子が返されます。ほとんどのHTTPコールはインメモリー分析UUIDを返し、リクエストの結果を保持しているリソースを識別します。インメモリー分析リクエストの数が多いと、完了するまで時間がかかりますが、結果へのハンドルはすぐに取得できます。このハンドルを使用して、HTTP GETを特殊なエンドポイントに呼び出すと、リクエストの結果(リクエストが完了していない場合はブロック)が得られます。

インメモリー分析とHTTPの相互作用のほとんどはこの例のようになります。

// any request, with some payload
HTTP POST 'http://scott:tiger@localhost:8080/pgx/core/session/session-shell-42v3b9n7/graph' with payload '{"graphName":"sample","graphConfig":{"edge_props":[{"type":"double","name":"cost"}],"format":"adj_list","separator":" ","node_props":[{"type":"integer","name":"prop"}],"uri":"http://path.to.some.server/pgx/sample.adj"}}'
Response: {"futureId":"15fc72e9-42e9-4527-9a31-bd20eb0adafb"}

// get the result using the In-Memory Analytics future UUID.
HTTP GET 'http://scott:tiger@localhost:8080/pgx/future/session/session-shell-42v3b9n7/result/15fc72e9-42e9-4527-9a31-bd20eb0adafb'
Response: {"stats":{"loadingTimeMillis":0,"estimatedMemoryMegabytes":0,"numNodes":4,"numEdges":4},"graphName":"sample","nodeProperties":{"prop":"integer"},"edgeProperties":{"cost":"double"}}

5.10 HDFSでのデータの読取りおよび格納

インメモリー分析では、Hadoop Distributed File System (HDFS)をサポートしています。この例では、インメモリー分析APIによってHDFSのグラフ・データを読み取り、アクセスする方法を示しています。

グラフ構成ファイルはクライアント側で解析されます。グラフ・データと構成ファイルはHDFSに格納されます。Hadoopクライアントはインメモリー分析と同じコンピュータにインストールする必要があります。『Oracle Big Data Applianceソフトウェア・ユーザーズ・ガイド』を参照してください。

注意:

パラレル・インメモリー分析エンジンは、Hadoopクラスタの1つのノードのメモリーでのみ実行されます。

5.10.1 HDFSからのデータのロード

この例では、sample.adjグラフ・データとその構成ファイルをHDFSにコピーし、それをメモリーにロードします。

  1. グラフ・データをHDFSにコピーします。

    cd $PGX_HOME
    hadoop fs -mkdir -p /user/pgx
    hadoop fs -copyFromLocal examples/graphs/sample.adj /user/pgx
    
  2. グラフ構成ファイルのuriフィールドを、HDFSリソースを指し示すように編集します。

    {
      "uri": "hdfs:/user/pgx/sample.adj", 
      "format": "adj_list",
      "node_props": [{ 
        "name": "prop", 
        "type": "integer" 
      }],
      "edge_props": [{ 
        "name": "cost", 
        "type": "double" 
      }],
      "separator": " "
    }
    
  3. 構成ファイルをHDFSにコピーします。

    cd $PGX_HOME
    hadoop fs -copyFromLocal examples/graphs/sample.adj.json /user/pgx
    
  4. 次の例に示すように、HDFSからサンプル・グラフをインメモリー分析にロードします。

シェルを使用したHDFSからのグラフのロード

g = session.readGraphWithProperties("hdfs:/user/pgx/sample.adj.json");
===> {
  "graphName" : "G",
  "nodeProperties" : {
    "prop" : "integer"
  },
  "edgeProperties" : {
    "cost" : "double"
  },
  "stats" : {
    "loadingTimeMillis" : 628,
    "estimatedMemoryMegabytes" : 0,
    "numNodes" : 4,
    "numEdges" : 4
  }
}

Javaを使用したHDFSからのグラフのロード

import oracle.pgx.api.*;
PgxGraph g = session.readGraphWithProperties("hdfs:/user/pgx/sample.adj.json");

5.10.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

5.10.3 HadoopでのJavaアプリケーションのコンパイルおよび実行

前の例のHdfsExample 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().fromHdfs("/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());
  }
}

これらのコマンドは、HdfsExampleクラスをコンパイルします。

cd $PGX_HOME
mkdir classes
javac -cp ../lib/* HdfsDemo.java -d classes

このコマンドはHdfsExampleクラスを実行します。

java -cp ../lib/*:conf:classes:$HADOOP_CONF_DIR HdfsDemo

5.11 YARNアプリケーションとしてのインメモリー分析の実行

この例では、Hadoop NextGen MapReduce (YARN)スケジューリングにより、Hadoopクラスタ上でインメモリー分析サーバーを開始、停止および監視する方法について説明します。

5.11.1 インメモリー分析サービスの開始および停止

YARNアプリケーションとしてインメモリー分析を開始する前に、インメモリー分析YARNクライアントを構成する必要があります。

5.11.1.1 インメモリー分析YARNクライアントの構成

インメモリー分析ディストリビューションには、$PGX_HOME/conf/yarn.confのYARNクライアント構成ファイルのサンプルが含まれています。

必要なフィールドがすべて設定されていることを確認します。指定したパスがHDFSにあり、zookeeper_connect_stringがCDHクラスタで実行中のZooKeeperポートを指し示している必要があります。

5.11.1.2 新規インメモリー分析サービスの開始

新規インメモリー分析サービスをHadoopクラスタで開始するには、次のコマンドを使用します。

yarn jar $PGX_HOME/yarn/pgx-yarn-1.0.0-for-cdh5.2.1.jar

$PGX_HOME/conf/yarn.conf以外のYARNクライアント構成ファイルを使用するには、ファイル・パスを指定します。

yarn jar $PGX_HOME/yarn/pgx-yarn-1.0.0-for-cdh5.2.1.jar /path/to/different/yarn.conf

サービスが開始されると、インメモリー分析サービスが起動されているHadoopノードのホスト名とポートが表示されます。

5.11.1.3 長期実行インメモリー分析サービスについて

インメモリー分析YARNアプリケーションは、指定した時間後にタイムアウトするようにデフォルトで構成されています。pgx_server_timeout_secs0に設定してタイムアウトを無効にすると、インメモリー分析サーバーはユーザーまたはHadoopによって明示的に停止されるまで継続して実行されます。

5.11.1.4 インメモリー分析サービスの停止

実行中のインメモリー分析サービスを停止する手順:

yarn application -kill appId

この構文では、appIdがサービス開始時に表示されるアプリケーションIDです。

終了したインメモリー分析サービスのログを検証する手順:

yarn logs -applicationId appId

5.11.2 インメモリー分析サービスへの接続

YARNでのインメモリー分析サービスには、任意のインメモリー分析サーバーへの接続と同じ方法で接続できます。たとえば、シェル・インタフェースでインメモリー分析サービスに接続するには、次のようなコマンドを使用します。

$PGX_HOME/bin/pgx --base_url username:password@hostname:port

この構文では、usernameおよびpasswordがYARN構成で指定されているものと一致します。

5.11.3 インメモリー分析サービスの監視

インメモリー分析サービスを監視するには、リソース・マネージャWeb UIで対応するYARNアプリケーションをクリックします。デフォルトでは、Web UIは次の場所にあります

http://resource-manager-hostname:8088/cluster