SPARQLthon19/TripleLoad

提供:TogoWiki

移動: 案内, 検索

Virtuosoでトリプルをロードする方法をまとめます。

目次

ロード前の設定/事前知識

設定ファイルの変更(ロードに関連する箇所)

設定ファイル(virtuosoインストールディレクトリ/var/lib/virtuoso/db/virtuoso.ini)を修正する。

  • ロードするRDFのディレクトリの追加

ロードコマンド(TTLP_MT, RDF_LOAD_RDFXML_MT, ld_dir_all)で指定するディレクトリを追記する。
尚、デフォルトの"."はDBディレクトリなので、"virtuosoインストールディレクトリ/var/lib/virtuoso/db"の下にRDFを置くならこの設定の追加は不要

[Parameters]
DirsAllowed                   = ., /home/my_name/store/virtuoso/share/virtuoso/vad, /home/my_name/rdf  //ロードするファイルのディレクトリを追記
  • メモリの設定

大量のデータ(数G以上)をロードする際には、バッファサイズ(メモリ使用量)の設定が必要になる場合がある。設定値について詳しくはメモリ量の設定を参照

[Database]
;MaxCheckpointRemap             = 2000 //コメントアウトして無効化

[Parameters]
;NumberOfBuffers          = 10000 //デフォルトのメモリ量を無効化して大きな値を設定
;MaxDirtyBuffers          = 6000
NumberOfBuffers          = 800000 //環境にあわせて設定
MaxDirtyBuffers          = 600000 //環境にあわせて設定
MaxCheckpointRemap       = 240000 //環境にあわせて設定
UnremapQuota             = 0

log_enable()について

log_enable()コマンドは、トランザクションログのモードを変更する際に用いられ、ロードの挙動に大きく関わる。
解説
仕様

手元にデータ(RDF)があり、新規でトリプルをロードするorデータの入れ替えを行う場合には(現状ではこういった運用が多いと思う)、ロードをやり直せば良くトランザクションによる復旧は必要ないため、こういうケースではlog_enable(2,1)が適している。
後述のロードコマンドのうち、ld_dir, ld_dir_allについては、ログモードは(2)で実行される。DB.DBA.TTLP_MTとDB.DBA.RDF_LOAD_RDFXML_MTについては、ログモードはデフォルト値が使用されるので、明示的に指定する必要がある。
尚、log_enable()で設定したモードはisqlのセッション内で有効なので、isqlを切断すると次回接続時にはデフォルト値log_enable(1)に戻る。

graphについて

Virtuosoではインストール時にgraph名を指定する。SPARQLではFROM句にgraph名を指定して検索範囲を絞ることもできるため、まずはRDBのテーブルに相当する概念と考えるとよい。
graph名はURIであれば任意の値を指定できる。
どの単位でgraphを分割するかによってSPARQLの記述が若干変わってくる場合あり、分割単位の判断については悩ましい部分があるが、データを削除する際にgraph単位で削除できるコマンドがあるため、よく分からなければ削除するデータの固まりを一つのgraphとして分けておけば良い。

ロード用コマンド

どのコマンドを使用するか

1,2個のファイルのTTLやRDF/XMLをロードする場合には"DB.DBA.TTLP_MT"や"DB.DBA.RDF_LOAD_RDFXML_MT"でも良いが、ファイルの個数が多い場合にはディレクトリ内のファイルを一括でロードできる"ld_dir_all"を使った方が向いている。

TTLのロード(DB.DBA.TTLP_MT)

1個のTTLをロードする。
DB.DBA.TTLP_MT (in strg any, in base varchar, [in graph varchar], [in flags integer], [in log_mode integer], [in threads integer], [in transactional integer]); 仕様
だいたい次のような書式で使用する。 DB.DBA.TTLP_MT (file_to_string_output('ファイルパス', , 'インポートしたいグラフ名');

SQL> log_enable(2,1);
SQL> DB.DBA.TTLP_MT (file_to_string_output('/home/my_name/rdf/test.ttl'), '', 'http://example.com/graph/graph_name');
//フラグ(81 = 64 + 16 + 1)を立てて、TURTLE syntax違反を緩和する
SQL> DB.DBA.TTLP_MT (file_to_string_output('/home/my_name/rdf/test.ttl'), '', 'http://example.com/graph/graph_name',81);

RDF/XMLのロード(DB.DBA.RDF_LOAD_RDFXML_MT)

1個のRDF/XMLをロードする。
DB.DBA.RDF_LOAD_RDFXML_MT (in strg varchar, in base varchar, in graph varchar, [in log_mode integer], [in threads integer], [in transactional integer]);仕様
だいたい次のような書式で使用する。 DB.DBA.TTLP_MT (file_to_string_output('ファイルパス', , 'インポートしたいグラフ名');

SQL> log_enable(2,1);
SQL> DB.DBA.RDF_LOAD_RDFXML_MT (file_to_string_output('/home/my_name/rdf/test.rdf'), '', 'http://example.com/graph/graph_name');

ディレクトリの一括ロード(ld_dir_all)

あるディレクトリにあるRDFファイルをまとめてロードする。
ld_dirは指定したディレクトリの直下のファイルしかロードしない。再帰的に辿ってサブディレクトリのファイルもロードする場合にはld_dir_allを使う
ld_dir_all (in dir_path varchar, in file_mask varchar, in target_graph varchar); 仕様
だいたい次のような書式で使用する。 ld_dir_all (file_to_string_output('ファイルパス', 'マッチする条件', 'インポートしたいグラフ名');

SQL> ld_dir_all ('/home/my_name/rdf/dir_name', '*.ttl', 'http://myhost/mygraph'); //ロードディレクトリの登録
SQL> ld_dir_all ('/home/my_name/rdf/dir_name2', '*.ttl', 'http://myhost/mygraph2'); //複数のグラフまたは複数のディレクトリを指定する場合は何度も登録する
SQL> rdf_loader_run(); //ロード実行

進捗の確認

ld_dir, ld_dir_allを使って複数ファイルを一括ロードする場合、進捗やエラー状態が確認できる。
ロードを始めたら別のisqlを立ち上げて、DB.DBA.LOAD_LISTテーブルの中身をSELECT文で確認する。

SQL> SELECT * FROM DB.DBA.LOAD_LIST;//ロード対象のファイル一覧
SQL> SELECT COUNT(*) FROM DB.DBA.LOAD_LIST where ll_state = 0; //未ロードのファイル一覧。0:未着手、1:ロード中、2:ロード済み
SQL> SELECT * FROM DB.DBA.LOAD_LIST WHERE ll_error IS NOT NULL; //syntax等でロードエラーが出たファイルの一覧

削除後に再度登録する場合の注意

一度ロードしたデータをCLEAR GRAPH(後述)等で削除し、再度ld_dir, ld_dir_allでロードをしようした場合、ロードがすぐ終わってしまい実際にデータが入っていない場合がある。
これはロードのstatusを記録したDB.DBA.LOAD_LISTテーブルにロード済みファイル情報が残っているためで、「それは以前ロードしたから、ロードする必要がない」と判断されるためである。
この場合は以下のコマンドでロードの記録を削除した後、再度ロードコマンドを実行する。

SQL> DELETE FROM DB.DBA.LOAD_LIST WHERE ll_graph = 'http://myhost/mygraph2'; //特定のgraphのロードファイルの記録を削除
SQL> DELETE FROM DB.DBA.LOAD_LIST; //全てのロードファイルの記録を削除


データの一括削除

グラフの削除

グラフ名を指定してグラフ内の全トリプルを一括削除できる。
削除処理はロード以上に時間がかかるため、ロードデータの大半を入れ替える場合には| 全データの削除の方が良い。
注)トリプル数の多いグラフの削除の前にはlog_enableを(2,1)または(3,1)で設定しないとメモリが肥大化してサーバに影響がでる事があるので必ず指定する。

SQL> log_enable(2,1);
SQL> SPARQL CLEAR GRAPH <http://myhost/mygraph>;
  • 削除後はグラフ指定でクエリを叩いて結果が0件であることを確認する。
SQL> SPARQL SELECT COUNT(*) FROM <http://myhost/mygraph> WHERE { ?s ?p ?o};
callret-0
INTEGER
_______________________________________________________________________________

0

全データの削除

グラフのトリプルサイズが大きいとグラフ指定での削除は長く重たい処理になるので、エンドポイント内の大半のデータを入れ替える場合にはDBファイルを削除してVirtuosoをインストール初期状態に戻した上でロードし直す方が効率が良い。
注)ユーザパスワードやストアドプロシージャ等をデフォルトから変更した場合には、再度設定が必要になるので変更内容を控えておく。

Virtuosoの停止

SQL> shutdown();

DBファイルの削除

"virtuosoインストールディレクトリ/var/lib/virtuoso/db"の下にデフォルトでは以下のファイルが生成されているので、iniファイル以外を残して削除する(logファイルもお好みで残しても良い)。

$ ls
virtuoso-temp.db virtuoso.db virtuoso.ini virtuoso.lck virtuoso.log virtuoso.pxa virtuoso.trx
$ ls | grep -v virtuoso.ini | xargs rm
$ ls
virtuoso.ini

この状態でVirtuosoを立ち上げると、インストール直後の状態と同じになる。

Tips

メモリ量の設定

大きなRDF(数G以上)をロードする場合にはバッファサイズ(メモリ使用量)の設定値を上げる必要がある。
デフォルトのメモリ使用量はとても小さい値になっているため、データ量に見合った設定に変更する必要がある。
Virtuosoはロード時に全データをメモリ上に構築し、ロードが進んでバッファサイズが足りなくなると、ハードディスクの読み書きが発生しはじめるため、著しくロードのスピードが遅くなる(ほとんど進まなくなる)。
これを防ぐためには、バッファサイズを大きく設定するか、またはディスクI/Oが発生してもあまり速度が落ちないように高速なディスク(SSD)を使うことでも軽減できる(SSD環境でのロードは検証中)。

Virtuosoのドキュメントや設定ファイル(virtuoso.ini)にはバッファサイズをRAMの2/3〜3/5の量を設定するようにと記載されているが、1サーバ上に複数Virtuosoを稼働させることもあるため、この通り設定できない場合もある。
では、必要なバッファサイズをどう計算するかというと、少なくともttl形式のRDFファイル(ロードする全ファイルの合計)サイズを超える事はないようなので、Bufferを8.5Kで計算して、ファイルサイズ/8.5K = NumberOfBuffers にすれば、メモリ不足の問題ない。
しかし、これでは大きめに設定してしまうことになる場合があるため、まずは少なめ(例えば8G)と小さめのメモリ設定にしてロードを実行してみて、何%データが終わったあたりでロードスピードが落ち始めるかを見極めて、ロード10%程度で低下するようであれば、10倍のバッファサイズを指定するという調整をして進める。

/mw/SPARQLthon19/TripleLoad」より作成