SPARQL-proxy

提供:TogoWiki

(版間での差分)
移動: 案内, 検索
(SPARQLパース関連)
(SPARQLパース関連)
205行: 205行:
</pre>
</pre>
* サブクエリに FROM 行を入れるとパースエラー
* サブクエリに FROM 行を入れるとパースエラー
-
* 結果が変わる(場合がある?)
 
-
** [http://sparql-support.dbcls.jp/?query=PREFIX%20rdf%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%3E%0APREFIX%20rdfs%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0APREFIX%20dct%3A%20%3Chttp%3A%2F%2Fpurl.org%2Fdc%2Fterms%2F%3E%0APREFIX%20jpo%3A%20%3Chttp%3A%2F%2Frdf.jpostdb.org%2Fontology%2Fjpost.owl%23%3E%0APREFIX%20obo%3A%20%3Chttp%3A%2F%2Fpurl.obolibrary.org%2Fobo%2F%3E%0APREFIX%20ncit%3A%20%3Chttp%3A%2F%2Fncicb.nci.nih.gov%2Fxml%2Fowl%2FEVS%2FThesaurus.owl%23%3E%0APREFIX%20unimod%3A%20%3Chttp%3A%2F%2Fwww.unimod.org%2Fobo%2Funimod.obo%23%3E%0APREFIX%20uniprot%3A%20%3Chttp%3A%2F%2Fpurl.uniprot.org%2Fcore%2F%3E%0APREFIX%20tax%3A%20%3Chttp%3A%2F%2Fpurl.bioontology.org%2Fontology%2FNCBITAXON%2F%3E%0APREFIX%20owl%3A%20%3Chttp%3A%2F%2Fwww.geneontology.org%2Fformats%2FoboInOwl%23%3E%0APREFIX%20skos%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23%3E%0APREFIX%20sio%3A%20%3Chttp%3A%2F%2Fsemanticscience.org%2Fresource%2F%3E%0APREFIX%20%3A%20%3Chttp%3A%2F%2Frdf.jpostdb.org%2Fentry%2F%3E%0ASELECT%20DISTINCT%20%3Fpeptide_id%20%3Fdataset_id%20%3Faccession%20%3Fmnemonic%20%3Fsequence%20%3Ffull_name%0AWHERE%20%7B%0A%20%20%7B%20%0A%20%20%20%20SELECT%20DISTINCT%20%3Fprotein%20%3Fdataset%0A%20%20%20%20WHERE%20%7B%0A%20%20%20%20%20%20%7B%20%0A%20%20%20%20%20%20%20%20SELECT%20DISTINCT%20%3Fdataset%0A%20%20%20%20%20%20%20%20WHERE%20%7B%0A%20%20%20%20%20%20%20%20%20%20VALUES%20%3Fdataset%20%7B%20%3ADS349_10%20%7D%0A%20%20%20%20%20%20%20%20%20%20%3Fdataset%20a%20jpo%3ADataset%20.%0A%20%20%20%20%20%20%20%20%20%20%3Fproject%20jpo%3AhasDataset%20%3Fdataset%20.%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%3Fdataset%20jpo%3AhasProtein%20%3Fdb_protein%20.%0A%20%20%20%20%20%20%3Fdb_protein%20jpo%3AhasDatabaseSequence%20%3Fprotein%20.%0A%20%20%20%20%7D%0A%20%20%7D%0A%20%20%0A%20%20%3Fprotein%20%5Ejpo%3AhasDatabaseSequence%2Frdfs%3Alabel%20%3Faccession%20.%0A%20%20%3Fprotein%20a%20uniprot%3AProtein%20%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20uniprot%3Amnemonic%20%3Fmnemonic%20.%0A%20%20%3Fprotein%20(uniprot%3ArecommendedName%7Cuniprot%3AsubmittedName)%2Funiprot%3AfullName%20%3Ffull_name%20.%0A%20%20%0A%20%20%3Fdataset%20dct%3Aidentifier%20%3Fdataset_id%20%3B%0A%20%20%20%20%20%20%20%20%20%20%20jpo%3AhasProtein%20%3Fdb_protein%20.%0A%20%20%3Fdb_protein%20jpo%3AhasDatabaseSequence%20%3Fprotein%20%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20jpo%3AhasPeptideEvidence%2Fjpo%3AhasPeptide%20%3Fpeptide%20.%0A%20%20%3Fpeptide%20dct%3Aidentifier%20%3Fpeptide_id%3B%0A%20%20%20%20%20%20%20%20%20%20%20jpo%3AhasSequence%20%5B%20a%20obo%3AMS_1001344%20%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rdf%3Avalue%20%3Fsequence%20%5D%20.%0A%7D%0AORDER%20BY%20ASC(%3Fsequence)%20%0ALIMIT%205%0A&endpoint=http://db-dev.jpostdb.org/sparql virtuoso直] と [http://sparql-support.dbcls.jp/?query=PREFIX%20rdf%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F1999%2F02%2F22-rdf-syntax-ns%23%3E%0APREFIX%20rdfs%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F2000%2F01%2Frdf-schema%23%3E%0APREFIX%20dct%3A%20%3Chttp%3A%2F%2Fpurl.org%2Fdc%2Fterms%2F%3E%0APREFIX%20jpo%3A%20%3Chttp%3A%2F%2Frdf.jpostdb.org%2Fontology%2Fjpost.owl%23%3E%0APREFIX%20obo%3A%20%3Chttp%3A%2F%2Fpurl.obolibrary.org%2Fobo%2F%3E%0APREFIX%20ncit%3A%20%3Chttp%3A%2F%2Fncicb.nci.nih.gov%2Fxml%2Fowl%2FEVS%2FThesaurus.owl%23%3E%0APREFIX%20unimod%3A%20%3Chttp%3A%2F%2Fwww.unimod.org%2Fobo%2Funimod.obo%23%3E%0APREFIX%20uniprot%3A%20%3Chttp%3A%2F%2Fpurl.uniprot.org%2Fcore%2F%3E%0APREFIX%20tax%3A%20%3Chttp%3A%2F%2Fpurl.bioontology.org%2Fontology%2FNCBITAXON%2F%3E%0APREFIX%20owl%3A%20%3Chttp%3A%2F%2Fwww.geneontology.org%2Fformats%2FoboInOwl%23%3E%0APREFIX%20skos%3A%20%3Chttp%3A%2F%2Fwww.w3.org%2F2004%2F02%2Fskos%2Fcore%23%3E%0APREFIX%20sio%3A%20%3Chttp%3A%2F%2Fsemanticscience.org%2Fresource%2F%3E%0APREFIX%20%3A%20%3Chttp%3A%2F%2Frdf.jpostdb.org%2Fentry%2F%3E%0ASELECT%20DISTINCT%20%3Fpeptide_id%20%3Fdataset_id%20%3Faccession%20%3Fmnemonic%20%3Fsequence%20%3Ffull_name%0AWHERE%20%7B%0A%20%20%7B%20%0A%20%20%20%20SELECT%20DISTINCT%20%3Fprotein%20%3Fdataset%0A%20%20%20%20WHERE%20%7B%0A%20%20%20%20%20%20%7B%20%0A%20%20%20%20%20%20%20%20SELECT%20DISTINCT%20%3Fdataset%0A%20%20%20%20%20%20%20%20WHERE%20%7B%0A%20%20%20%20%20%20%20%20%20%20VALUES%20%3Fdataset%20%7B%20%3ADS349_10%20%7D%0A%20%20%20%20%20%20%20%20%20%20%3Fdataset%20a%20jpo%3ADataset%20.%0A%20%20%20%20%20%20%20%20%20%20%3Fproject%20jpo%3AhasDataset%20%3Fdataset%20.%0A%20%20%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%7D%0A%20%20%20%20%20%20%3Fdataset%20jpo%3AhasProtein%20%3Fdb_protein%20.%0A%20%20%20%20%20%20%3Fdb_protein%20jpo%3AhasDatabaseSequence%20%3Fprotein%20.%0A%20%20%20%20%7D%0A%20%20%7D%0A%20%20%0A%20%20%3Fprotein%20%5Ejpo%3AhasDatabaseSequence%2Frdfs%3Alabel%20%3Faccession%20.%0A%20%20%3Fprotein%20a%20uniprot%3AProtein%20%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20uniprot%3Amnemonic%20%3Fmnemonic%20.%0A%20%20%3Fprotein%20(uniprot%3ArecommendedName%7Cuniprot%3AsubmittedName)%2Funiprot%3AfullName%20%3Ffull_name%20.%0A%20%20%0A%20%20%3Fdataset%20dct%3Aidentifier%20%3Fdataset_id%20%3B%0A%20%20%20%20%20%20%20%20%20%20%20jpo%3AhasProtein%20%3Fdb_protein%20.%0A%20%20%3Fdb_protein%20jpo%3AhasDatabaseSequence%20%3Fprotein%20%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20jpo%3AhasPeptideEvidence%2Fjpo%3AhasPeptide%20%3Fpeptide%20.%0A%20%20%3Fpeptide%20dct%3Aidentifier%20%3Fpeptide_id%3B%0A%20%20%20%20%20%20%20%20%20%20%20jpo%3AhasSequence%20%5B%20a%20obo%3AMS_1001344%20%3B%0A%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20%20rdf%3Avalue%20%3Fsequence%20%5D%20.%0A%7D%0AORDER%20BY%20ASC(%3Fsequence)%20%0ALIMIT%205%0A&endpoint=http://db-dev.jpostdb.org/proxy/sparql proxy経由]
 
-
** いろんなフィルタパターンでクエリを自動生成してるので、綺麗ではない入れ子になったクエリだけど、結果の一個目が出なく成ってた
 
-
*** キャッシュ消したら同じになった
 

2020年1月20日 (月) 05:37時点における版

SPARQL-proxy は、クライアントと SPARQL エンドポイントの間で動作するミドルウェアで、 山中さんが SPARQLthon で作成されたオリジナルを改訂したものです。

目次

主な機能

  • SPARQL クエリをパースし、更新系のクエリを実行できないようにする
  • SPARQL クエリをジョブスケジューリングしてからトリプルストアに投げる(負荷集中の低減)
  • ジョブのタイムアウトを指定できる
  • 同時に実行するジョブの数を指定できる
  • 管理画面からジョブを確認したり削除したりできる
  • SPARQL 検索結果をキャッシュして2度目からトリプルストアを使わずに結果を返す(レスポンスの向上)
  • キャッシュは memory, file, redis, memcached を選択して利用できる
  • キャッシュを圧縮してサイズを抑えることができる
  • クエリのログを取得できる

実験的な機能

  • 大量な結果が返る SPARQL クエリを LIMIT/OFFSET を自動的につけて分割実行する

最近の追加機能

  • Virtuoso 独自の拡張「DEFINE sql:select-option "order"」などを許容するように変更
    • ただし、SELECT などで sql:hogehoge とか option() などを使っている場合には対応していない
  • 180323 ver.
    • [ ] を使ったクエリは SPARQL パーザーが _:b0 形式のブランクに書き換えるが、ブランクにクエリを超えて連番つけるので、これまでは [ ] を使うクエリでキャッシュが効かなかった。パーザーを毎回リセットすることで、キャッシュが効くようになりました

レポジトリ

インストール

node.js の安定版をインストール(展開して bin/node, bin/npm を ~/local/bin などにリンクする)

$ wget --no-check-certificate https://nodejs.org/dist/v6.10.0/node-v6.10.0-linux-x64.tar.xz

sparql-proxy の現状版をダウンロードしてインストール

$ git clone https://github.com/dbcls/sparql-proxy.git
$ cd sparql-proxy
$ npm install

一部の依存ライブラリが GCC 4.8 以降の新しいものを必要とするので注意。

起動

$ cat startup.sh
#!/bin/sh

PREFIX=/opt/proxy

export PATH="$PREFIX/bin:$PREFIX/local/bin:$PATH"

# REDIS_URL=localhost:6379 \
# MEMCACHE_SERVERS=localhost:11211,localhost:11212 \
# JOB_TIMEOUT=300000 \
# DURATION_TO_KEEP_OLD_JOBS=60000 \
# COMPRESSOR=snappy \

(
cd $PREFIX/git/sparql-proxy

QUERY_LOG_PATH=$PREFIX/log/proxy.log \
CACHE_STORE=file \
CACHE_STORE_PATH=$PREFIX/cache \
MAX_CONCURRENCY=3 \
TRUST_PROXY=true \
PORT=3000 \
SPARQL_BACKEND=http://dev.togogenome.org/sparql \
ADMIN_USER=admin \
ADMIN_PASSWORD=hogehoge \
$PREFIX/bin/npm start 2>&1 >> $PREFIX/log/server.log &
)

これで http://localhost:3000/ を開くと SPARQL を実行する画面が表示される。

foreverでdaemon化

$ npm install -g forever
$ PORT=3000 SPARQL_BACKEND=http://aaa.bbb.ccc/sparql forever start -c "npm start" /path_to_sparql-proxy_dir
$ forever list     # forever 稼働中リスト
$ forever stop NNN   # list で確認したuidを用いて停止

/opt/proxy/git/sparql-proxy にインストールし、npmやforeverが/opt/proxy/local/binにある場合

% cat startup.sh
#!/bin/sh

PREFIX=/opt/proxy

(
cd $PREFIX/git/sparql-proxy

QUERY_LOG_PATH=$PREFIX/log/proxy.log \
CACHE_STORE=file \
CACHE_STORE_PATH=$PREFIX/cache \
MAX_CONCURRENCY=3 \
TRUST_PROXY=true \
PORT=14990 \
SPARQL_BACKEND=http://example.org/sparql-backend \
ADMIN_USER=admin \
ADMIN_PASSWORD=togo \
$PREFIX/local/bin/forever --workingDir $PREFIX/git/sparql-proxy $PREFIX/local/bin/npm start
)
  • Defaultでは 10,000 binidngs まで
    • 環境変数 MAX_LIMIT で設定

デプロイ

これまでどおりの URL たとえば http://example.org/sparql を sparql-proxy を使ったものに差し替えたい場合、 sparql-proxy を localhost:3000 などで起動しておいて、

server {
    listen       80;
    server_name  example.org

    location /sparql {
        add_header Access-Control-Allow-Origin *;
        add_header Access-Control-Allow-Headers X-Requested-With;
        proxy_pass http://localhost:3000/sparql;
        proxy_redirect default;
    }
}

のようにすれば OK。

もし sparql-proxy のトップページや /admin を localhost:3000 ではなく外からもアクセスできるように、 同じドメイン 80 番ポートのサブパス、たとえば /proxy で公開する形でホストしたい場合は、 http://example.org/proxy/ でトップページを、http://example.org/proxy/sparql でエンドポイントを、 http://example.org/proxy/admin/ で管理画面を表示することになるが、 管理画面の更新が WebSockets で行われていることと、管理者ログインのクッキーへの対応ため、 下記のような書き換えが必要。

    location ~ ^/proxy/(.*)$ {
      proxy_pass http://localhost:3000/$1$is_args$args;
      proxy_redirect / /proxy/;
      proxy_cookie_path / /proxy/;
      proxy_http_version 1.1;
      proxy_set_header Upgrade $http_upgrade;
      proxy_set_header Connection "upgrade";
    }

以上、いずれも Nginx の場合の設定例。

タイムアウト設定(nginxデフォルトは60秒)

proxy_read_timeout 3m;

SPARQLパース関連

  • Sparqlパース機能はもっと単純にならないか?
  • proxy 経由したときだけ遅くなるクエリがある
    • かなり重いクエリが下記のエラー
      • (node:15438) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 10): TypeError: Cannot read property 'map' of undefined
    • virtuoso で空白ノードをアンダーバーコロン形式 (例 '_:blank')や変数に入れた後で、OPTIONAL join を行うと遅くなる場合がある。[ ] 形式だと問題ない
      • _:b1, _:b2, _:b3 と数が多いほど遅くなる
    • SPARQL-proxy の SPARQL パーザーは [ ] 形式を '_:b' 形式に書き換えて実効するので、結果、遅くなる
  // virtuoso で問題ない

  ?s hoge:p [ a ?type ;
              rdf:value ? value ] .
  OPTIONAL { ?s hoge:p2 ? o .}

  ===========パーザーが書き換え============

  // virtuoso で遅い

  ?s hoge:p _:b1 .
  _:b1 rdf:type ?type .
  _:b1 rdf:value ?value .
  OPTIONAL { ?s hoge:p2 ? o .}
  • 解決法:可能なら、OPTIONAL join を先にする
DEFINE sql:select-option "order"

  OPTIONAL { ?s hoge:p2 ? o .}
  ?s hoge:p [ a ?type ;
              rdf:value ? value ] .
  • 空白ノード、プロパティ・パス関連でパースエラー
    • 主語を省略しつつ、空白ノード省略でプロパティ・パス (/,*,+ など) を使うとエラー
    • 主語か空白ノードの省略をやめると通る
  s  p  o ;
     p  [  p/p  o  ] .
  • サブクエリに FROM 行を入れるとパースエラー
個人用ツール