Rust+OxigraphでサーバレスSPARQLエンドポイント構築
これまで、AWS LambdaとAPI Gateway上でSPARQLエンドポイントを動かす試みをいくつか行ってきました。
今回は、Rust製のOxigraphを使って、AWSサーバレス上で動くプログラムを作ってみました。
ここでは、oxigraph-sparql-api-serverlessを紹介します。
SPARQLとは?
SPARQLはRDF用のクエリ言語です。SPARQLクエリで検索できるエンドポイントは、DBpediaやWikidataなど、すでにさまざまなものが公開されています。
詳しくは以下を参照してください。
使い方
oxigraph-sparql-api-serverlessは、AWS Lambda関数部分をRustで実装しています。Dockerを使って Amazon Linux 2上でビルドし、AWS SAM CLIでAWSにデプロイします。
ビルド
SPARQLエンドポイントで検索したいRDFファイルをTurtle形式で準備してください。
dump.ttl
にリネームして rdf/
ディレクトリに上書きします。
以下のDockerコマンドでRustプログラムをビルドします。
$ cd oxigraph-sparql-api-serverless/
$ docker image build -t oxigraph-build -f Dockerfile.build .
$ docker container run --rm -v $PWD:/code -v $HOME/.cargo/registry:/root/.cargo/registry -v $HOME/.cargo/git:/root/.cargo/git oxigraph-build
ビルドが完了すると lambda.zip
が生成されます。
デプロイ
AWS SDKやAWS SAM CLIのインストール、設定後以下を実行するとデプロイできます。
$ sam package --template-file template.yaml --output-template-file packaged.yaml --s3-bucket {デプロイ用S3バケット}
$ sam deploy --template-file packaged.yaml --stack-name {スタック名} --capabilities CAPABILITY_IAM
デプロイ後に表示されるURL(例えば:https://${ID}.execute-api.${Region}.amazonaws.com/Prod/
)をコピーして以下のようにアクセスすれば、SPARQLエンドポイントとして動作します。
https://${ID}.execute-api.${Region}.amazonaws.com/Prod/sparql?query={URLエンコードされたSPARQLクエリ}&format={json(デフォルト) か xml}
パフォーマンス
検索速度
過去作成した、Node.js/Quadstore版、Java/Apache Jena版と同様に検索速度を計測しました。
上記2記事では、「図書館及び関連組織のための国際標準識別子(ISIL)」試行版LODで公開されていた2020年版のRDFファイル(計160491トリプル)と以下の3種類のSPARQLクエリを使いました。
今回も同じ条件で行いました。
(1) トリプルを100件取得
select * where {?s ?p ?o} limit 100
(2) 全トリプル数を取得
select (count(*) as ?count) where {?s ?p ?o}
(3) filter
を使って文字列の絞り込み
prefix schema: <http://schema.org/>
prefix org: <http://www.w3.org/ns/org#>
prefix dbpedia: <http://dbpedia.org/ontology/>
select * where {
?uri dbpedia:originalName ?name;
org:hasSite/org:siteAddress/schema:addressRegion ?pref.
filter( regex(?pref, "東京") )
}
limit 10
結果は以下の通りとなりました。
実装別 | (1) | (2) | (3) |
---|---|---|---|
Rust/Oxigraph | 88ms | 279ms | 80ms |
Node.js/Quadstore | 220ms | 12910ms | 12910ms |
Java/Apache Jena | 141ms | 579ms | 104ms |
Node.js/Quadstore と Java/Apache Jena の結果も比較のためにのせました。すべてにおいてRust/Oxigraph が最も早い結果となりました。
初回起動時間
AWS Lambda には所謂コールドスタートと呼ばれる、最初にプログラムを実行するときに初期化に時間がかかることがあるという問題があります。
Rust/Oxigraph と Node.js/Quadstore、Java/Apache Jena の3つでAWS Lambda で実行したときの初期所要時間(Init Duration)を調べました。
実装別 | 初期所要時間 | メモリサイズ |
---|---|---|
Rust/Oxigraph | 81.96 ms | 1024MB |
Node.js/Quadstore | 383.82 ms | 1024MB |
Java/Apache Jena | 3690.75 ms | 2048MB |
※ 初期所要時間は一定ではなく、場合によってはこれよりももっと時間がかかるときがあります。
ここでも Rust/Oxigraph が最も早いという結果になりました。
まとめ
これまでは、Java/Apache Jena版がコールドスタート問題に目をつぶれば一番安定したパフォーマンスが期待できましたが、Rust/Oxigraph版はコールドスタート問題もほぼ無視できるレベルで早く、15万トリプルレベルであれば検索速度も安定しているようなので十分使えると思いました。
ただ、100万トリプル以上のRDFファイルでも試したところ、フルスキャンがかかりそうなクエリ(例えば、filter
とかorder by
とか)の検索速度はRust/Oxigraph版(10秒以上)よりもJava/Apache Jena版(1秒未満)が早かったので、場合によっては Java/Apache Jena版 のほうが有利な場合がありそうです。
Oxigraph は2021年3月時点ではまだバージョンが若く、最適化はまだこれからとのことなので、今後に大きく期待が持てそうです。
Rust/Oxigraph版の検索は以下で試すことができます。
Author And Source
この問題について(Rust+OxigraphでサーバレスSPARQLエンドポイント構築), 我々は、より多くの情報をここで見つけました https://zenn.dev/uedayou/articles/06f744ac1c4737著者帰属:元の著者の情報は、元のURLに含まれています。著作権は原作者に属する。
Collection and Share based on the CC protocol