Fusekiを使ったSPARQL Endpoint構築方法

FusekiはSPARQL Endpointを構築するためのオープンソースのソフトウェアで、Apache Jenaプロジェクトによって提供されています。SPARQL1.1に対応しており、RDFストアの永続化(DB化)にも対応しています。この記事では、複数のデータセットをもつSPARQL EndpointをLinuxサーバ上に作成した際に、われわれが採用した方法を解説します。Fusekiの使い方について、詳しくは公式の解説をご覧ください。

なお、この公式の解説はFusekiに関する一般的な記述だけで、環境に合わせた具体的な実装方法は書かれていません。ここでは当サイトでの実装方法をご紹介します。この方式以外の実装方法もいろいろあると思います。特にセキュリティの確保については、認証を導入するなど、別のやり方も考えられます。ここでご紹介するものは、あくまでも一事例として参考にしていただきたいです。

前準備

FusekiはJavaとRubyを使用します。インストールされていない場合は、以下のようにインストールしてください。

Javaのインストール

1) インストールされているかどうかの確認

# java -version

2) インストール可能なパッケージ一覧の表示

# yum list \*java-1\* | grep open

3) インストール

# yum install java-1.6.0-openjdk.x86_64
# yum install java-1.6.0-openjdk-devel.x86_64

Rubyのインストール

1) インストールされているかどうかの確認

# rpm -q ruby

2) インストール

# yum install ruby ruby-devel rdoc irb

Fusekiのインストール

1) ダウンロード

ダウンロードサイト(http://www.apache.org/dist/jena/binaries/)から最新の配布版をダウンロードします。2013年3月時点では0.2.6が最新版で、以下をダウンロードしました。

jena-fuseki-0.2.6-distribution.zip

この圧縮ファイルを解凍し、中にあるフォルダ(jena-fuseki-0.2.6-distribution)をfusekiに改名します。

2) 配備

fusekiフォルダを/usr/lib/fusekiの位置にコピーします。

# cp -R fuseki /usr/lib/fuseki

実行権限を設定します。

# cd /usr/lib/fuseki
# chmod +x fuseki-server s-*

3) Fuseki Serverの起動

# ./fuseki-server --update --mem /ds

以下のように表示されれば、Fuseki Serverのインストールは成功です。

12:41:50 INFO  Server               :: Dataset: in-memory
12:41:50 INFO  Config               :: Home Directory: /usr/lib/fuseki
12:41:51 INFO  Server               :: Dataset path = /ds
12:41:51 INFO  Server               :: Fuseki 0.2.6 2013-02-20T12:04:26+0000
12:41:51 INFO  Server               :: Started 2013/03/21 12:41:51 JST on port 3030

Fuseki Serverはアプリケーションとして立ち上がります。終了にはCTRL+Cを使います。

Apacheとの連携

1) FusekiのサービスURIと外部からのアクセスURI

Fusekiは以下の4つのURIを使ってサービスを提供します。

http://*host*/*dataset*/query:3030     -- the SPARQL query endpoint.
http://*host*/*dataset*/update:3030    -- the SPARQL Update language endpoint.
http://*host*/*dataset*/data:3030      -- the SPARQL Graph Store Protocol endpoint.
http://*host*/*dataset*/upload:3030    -- the file upload endpoint.

queryは読み取り専用ですが、update, data, uploadはデータ変更を伴います。また使用ポートは3030で通常の80ポートと異なっています。そこで、ここではApacheのRewriteRuleを使って、update, data, uploadについては外部からのアクセスを禁止し、queryについてはProxyPassを使って、以下のような外部向けURL(ポート80を使用)を上記のqueryサービスURIにマップすることにします。

http://*host*/*endpoint*/*dataset*/query

ここで *endpoint* は、SPARQL Endpoint用に用意した添え字です。ドキュメントルート直下のフォルダ名以外のものであれば何でも構いません。当サイトでは lod (linked open data) という名前を利用しており、当サイトのsampleデータセット向けのEndpoint URLは以下のようになっています。

http://satolab.tiu.ac.jp/lod/sample/query

2) Apache設定の追加

上で述べたApacheの設定を、Apacheの個別設定フォルダに fuseki.conf という設定ファイルを追加することで行います。

# vi /etc/httpd/conf.d/fuseki.conf

fuseki.confの内容

1
2
3
4
5
6
RewriteEngine On
RewriteRule ^/lod/[^/]+/update - [F]
RewriteRule ^/lod/[^/]+/upload - [F]
RewriteRule ^/lod/[^/]+/data - [F]
 
ProxyPass /lod/ http://localhost:3030/

ここで、2~4行と6行目の /lod/ は、上で述べたSPARQL Endpoint用の添え字です。2~4行のRewriteRule は、update, upload, dataのサービスがリクエストされたとき、「403 Forbidden」を表示する設定です。6行目のProxyPassは、それ以外(つまりqueryのとき)、localhostの3030ポートにリクエストを転送する設定です。

ファイアウォールでポート3030は外部に対して開かれていないものとすれば、上記の設定でquery以外の外部からのアクセスは禁止され、セキュリティが確保されるはずです。ただし、サーバ環境によってはこれでも安全とはいいきれませんので注意が必要です。

3) httpdの再起動

/etc/rc.d/init.d/httpd restart

4) 設定結果の確認

当サイトの場合、以下のURLでFusekiサーバにアクセスできます。

http://satolab.tiu.ac.jp/lod/

Fuseki画面

ブラウザで上のURLにアクセスすると、左のFuseki画面が表示されます。本来であれば、この画面のControl Panelをクリックして開かれるコントロールパネルページで、「Select」ボタンを押せば、そのデータセットにデータを投入できる画面が開くはずですが、「The requested URL /$/datasets was not found on this server.」というエラーになってしまいました。これはFusekiがリンクに絶対パスを使用しているため、上記のProxyPass設定が働かなくなるためです。

このFuseki画面の「SPARQL query form」をクリックすると、一般のSPARQL検索ページが開きます。その入力欄に、試しに下のSELECT文を入力して、Outputを「Text」にして、「Get Results」ボタンを押してみて下さい。検索結果表が表示されれば、成功です。なお、Outputを「XML」にすると「/xml-to-html.xsl」が見つからないというエラーになってしまいました。これも上と同じ理由と思われます。

サブフォルダを使わずに、バーチャルホストで実装すれば正常に動きますので、これらのエラーはサブフォルダを使ったProxyPassの利用が原因と思われます。この画面やSPARQLerページは、SPARQL Endpointの実装には、直接関係ありませんから、気にしないで先に進むことにします。

 

SELECT *
FROM <http://satolab.tiu.ac.jp/ld/sample/sparql>
WHERE {
    SERVICE <http://satolab.tiu.ac.jp/ld/sample/sparql> {
        ?s ?p ?o .
    }
}
LIMIT 10

注:SERVICEを使うとき、2行目のFROM句はなくても良いはずですが、SPARQLerではこれがないとエラーになってしまいます。このFROM句のURLはLOADメッセージに対応したものであれば、何でも構いません。

TDBの利用

本格的なEndpointを構築するためには、RDFデータを永続的に格納できるRDFストアが必要です。FusekiにはTDBというデータベースシステムが同梱されていますので、これを利用することにします。

1) DBフォルダの作成

当サイトでは、sample, purl, w3, xmlnsという4つのデータセットに分けて、SPARQL Endpointを作成しています。これらのDBファイルを格納するために以下のようにフォルダを作成しました。

# cd /usr/lib/fuseki
# mkdir DB
# mkdir DB/sample
# mkdir DB/purl
# mkdir DB/w3
# mkdir DB/xmlns

2) TDB設定ファイルの作成

fusekiフォルダにあるconfig-tdb.ttlをコピーして、内容を書き加えて、tdb_all.ttlという設定ファイルを作成します。

# cp config-tdb.ttl tdb_all.ttl
# vi tdb_all.ttl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
# Licensed under the terms of http://www.apache.org/licenses/LICENSE-2.0
 
## This is made by sato based on config-tdb.config.
 
## Example of a TDB dataset published using Fuseki: persistent storage.
 
@prefix :        <#> .
@prefix fuseki:  <http://jena.apache.org/fuseki#> .
@prefix rdf:     <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
@prefix rdfs:   <http://www.w3.org/2000/01/rdf-schema#> .
@prefix tdb:     <http://jena.hpl.hp.com/2008/tdb#> .
@prefix ja:      <http://jena.hpl.hp.com/2005/11/Assembler#> .
 
[] rdf:type fuseki:Server ;
    # Timeout - server-wide default: milliseconds.
    # Format 1: "1000" -- 1 second timeout
    # Format 2: "10000,60000" -- 10s timeout to first result, then 60s timeout to for rest of query.
    # See java doc for ARQ.queryTimeout
    # ja:context [ ja:cxtName "arq:queryTimeout" ;  ja:cxtValue "10000" ] ;
    # ja:loadClass "your.code.Class" ;
 
    fuseki:services (
          <#service_tdb_sample>
          <#service_tdb_purl>
          <#service_tdb_w3>
          <#service_tdb_xmlns>
    ) .
 
# TDB
[] ja:loadClass "com.hp.hpl.jena.tdb.TDB" .
tdb:DatasetTDB  rdfs:subClassOf  ja:RDFDataset .
tdb:GraphTDB    rdfs:subClassOf  ja:Model .
 
## ---------------------------------------------------------------
## Updatable TDB dataset with all services enabled.
 
<#service_tdb_sample> rdf:type fuseki:Service ;    rdfs:label                      "TDB Service (RW)" ;
    fuseki:name                     "sample" ;    fuseki:serviceQuery             "query" ;
    fuseki:serviceQuery             "sparql" ;
    # fuseki:serviceUpdate            "update" ;
    # fuseki:serviceUpload            "upload" ;
    fuseki:serviceReadWriteGraphStore      "data" ;
    # A separate read-only graph store endpoint:
    fuseki:serviceReadGraphStore       "get" ;
    fuseki:dataset           <#tdb_dataset_sample> ;    .
 
<#tdb_dataset_sample> rdf:type      tdb:DatasetTDB ;    tdb:location "DB/sample" ;##     # Query timeout on this dataset (milliseconds)
##     ja:context [ ja:cxtName "arq:queryTimeout" ;  ja:cxtValue "1000" ] ;
    tdb:unionDefaultGraph true ;
    .
 
## 以下、<#service_tdb_purl>、<#service_tdb_w3>、<#service_tdb_xmlns>について同様

config-tdb.ttlからの変更点は、以下の2点です。

  1. 23~26行: データセットに対応したサービスURIに置きかえる。
  2. 37行目以下: サービスURI毎にその定義(<#service_tdb_sample>では37~48行)と、それに対応するデータセットURIの定義(<#tdb_dataset_sample>では50~55行)を書く。

当サイトの場合、<#service_tdb_purl>、<#service_tdb_w3>、<#service_tdb_xmlns>について、37~55行と同様のものが続きます。異なるのは、37行目の<#service_tdb_sample>、39行目の”sample”、47行目と50行目の<#tdb_dataset_sample>、51行目の”DB/sample”の計5ヶ所のsampleがpurl等に変わるだけです。クエリタイムアウト時間の設定などもここでできますので、必要に応じて設定します。なお、ここでは42~43行に#をつけてコメントアウトし、updateとuploadを無効にしています。当面これらを使う予定はないですので、セキュリティを高めるための配慮です。

Fuseki Serverの起動

TDB設定ファイルを使って、Fuseki Serverを起動するには、以下のようにします。

# ./fuseki-server --config=tdb_all.ttl

データの入力

RDFストアへのデータ投入は、コマンドモードのSOH(SPARQL Over HTTP)を使用します。SOHはFuseki Serverが実行中でないと利用できませんので、別Window(SSHでアクセスしているなら、別のSSH画面)を立ち上げて、そこでデータ投入を行います。この作業は一般ユーザ権限で行うことができます。

$ ./s-put http://localhost:3030/sample/data http://satolab.tiu.ac.jp/g/datacube_sample_2013 /var/www/html/ld/rdf/datacube_sample_2013.ttl

s-putはRDFファイルからデータを投入するもので、以下の構文です。

s-put http://localhost:3030/<データセット名>/data <グラフURI> <RDFファイルのパス>

ここで<データセット名>は、TDB設定ファイルのfuseki:nameと同じものです。なお、ここでは対応するDBのフォルダ名にもこれと同じものを使っています。一方、<グラフURI>は、1つのRDFファイルの内容に対応するグラフを識別するためのURIで、任意の名前を使うことができます。これはSPARQL文のGRAPHのURIになります。なお、s-putでは同じ<グラフURI>のデータを投入すると、前のものが消されて置き換えになるようです。

正しくデータが入力されたかどうかは、s-getを使って確認できます。

$ ./s-get http://localhost:3030/sample/data http://satolab.tiu.ac.jp/g/datacube_sample_2013

この構文は以下の通りです。

s-get http://localhost:3030/<データセット名>/data <グラフURI>

同様にして、他のデータセットのデータも投入します。

Endpointの動作確認

以上でEndpointの作成は完了です。SPARQL EndpointのURLは、このサイトの場合は以下のようになります。

http://satolab.tiu.ac.jp/lod/sample/query

一般的には、次の通りです。

http://<サイトのURL>/<Endpoint向け添え字>/<データセット名>/query

Fuseki以外のSPARQLブラウザを使って、動作を確認します。例えば、Navigate RDFの場合、エンドポイントの「_未登録のエンドポイント_」で、上のURLを指定し、以下のSPARQL文を実行すれば、確認できます。

1
2
3
4
5
SELECT *
WHERE {
    ?s ?p ?o .
}
LIMIT 10

バックグラウンド実行

1) バックグラウンド実行の指定

Fuseki Serverはアプリケーションとして実行しますので、フォアグラウンドで実行しているとログアウトもできません。バックグラウンドで実行する方が良いでしょう。バックグラウンドで実行するには、起動コマンドの最後に&を付けます。

# ./fuseki-server --config=tdb_all.ttl &

このときプロセスIDが表示されますので、これを記録しておくと良いでしょう。なお、Fuseki Serverは起動時にログを表示しますので、プロンプトが表示されません。Enterを押せばプロンプトが表示されます。

2) プロセスIDの確認とFuseki Serverプロセスの終了

後になってプロセスIDを確認するには、以下のようにします。

$ ps -A f

これで現在実行中のすべてのプロセスの階層が表示され、同時に、各プロセスのIDと起動コマンドが表示されます。ここで起動コマンドが「java -Xmx1200M -jar /usr/lib/fuseki/fuseki-server.jar …」となっているものが、Fuseki Serverのプロセスです。

プロセスを終了させるには、以下のようにします。

kill <プロセスID>

SOHの活用

上ではs-putとs-getを使いましたが、他にも以下の例のようなものが使えます。詳しくは、SOHの解説ページをご参照ください。

# PUT a file
s-put http://localhost:3030/ds/data default D.nt
 
# GET a file
s-get http://localhost:3030/ds/data default
 
# PUT a file to a named graph
s-put http://localhost:3030/ds/data http://example/graph D.nt
 
# Query
s-query --service http://localhost:3030/ds/query 'SELECT * {?s ?p ?o}'
 
# Update
s-update --service http://localhost:3030/ds/update --file=update.ru

最大使用メモリの拡張

Fuseki Serverはデフォルトでは最大1.2GBのメモリを使用する設定になっています。fuseki-serverファイルの59行目を以下のように変更すれば、これを3GBに拡張することができます。

JVM_ARGS=${JVM_ARGS:--Xmx3000M}

About 佐藤 英人

東京国際大学名誉教授。 若い頃、経済企画庁(現内閣府、経済産業省)の統計課、国民所得部で統計の実務を経験。 その後、大学で統計データベース、知識ベース、オブジェクト指向等の研究・教育に従事。 著書:統計データベースの設計と開発 - データモデルと知識ベースの応用(オーム社)、オブジェクト指向が分かる本(オーム社)など。

コメントを残す

Name and email are required. Your email address will not be published.

キャプチャ * Time limit is exhausted. Please reload CAPTCHA.