※ 2020/08/22 追記
本記事の第二弾AWSサーバレスでSPARQLエンドポイントを構築(Java+Apache Jena編)の公開によりタイトルを変更しました。AWS環境でサーバレスSPARQLエンドポイントを構築したい方は、第二弾のほうがお勧めです。
個人的にSPARQLエンドポイントを作るときに、運用やメンテナンスが楽になればということで、AWSのマネージドサービスを活用できないかと検討してみました。
AWSというとAmazon Neptuneがありますが、最小構成でも年間10万近くかかるようなので、AWS Lambda を使ったサーバレス構成で低コストでメンテナンスフリーなSPARQLエンドポイントの構築に挑戦してみました。
結論から言うと、ちゃんと動きましたが、期待してたよりもうまくいきませんでした。
一応今回使ったコードは以下で公開していますが、利用される場合は以下を最後まで読まれることをお勧めします。
https://github.com/uedayou/quadstore-server-on-aws-serverless
環境
Lambda と API Gateway はAWS SAMでデプロイするようにしました。
サーバレス環境の設定をあらかじめ指定しておけるのでデプロイが楽ですし、ある程度の設定もコード上で細かく変更できていいですね。
SPARQLエンドポイントサーバ自体のコードは、node-quadstore と levelDB を使いました。
あらかじめRDFファイルを使ってlevelDBファイルを生成しておき、それを利用してSPARQLクエリで検索結果を得るような形です。
cd quadstore-server-on-aws-serverless/quadstore-server-lambda
npm install
npm run build:db -- ../sample/isillod.ttl
パフォーマンス
この環境でどれくらい使えるか、トリプル数と以下の3つのクエリ毎の検索時間を計ってみました。
Lambdaのメモリは1024MB、タイムアウトは30秒(API Gatewayが30秒でタイムアウトするため)で設定しています。
データセットは「図書館及び関連組織のための国際標準識別子(ISIL)」試行版LODを使いました。
上記サイトでは Turtleファイルを分割して公開しています。これらを1つずつ追加して作成したDBファイル毎に計測しています。
(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) |
---|---|---|---|
21,788 | 0.192 秒 | 2.85 秒 | 5.20 秒 |
42,585 | 0.186 秒 | 4.35 秒 | 7.53 秒 |
63,448 | 0.193 秒 | 5.58 秒 | 11.08 秒 |
84,587 | 0.181 秒 | 9.74 秒 | 14.02 秒 |
104,826 | 0.163 秒 | 11.47 秒 | 16.19 秒 |
124,718 | 0.225 秒 | 14.19 秒 | 21.83 秒 |
144,669 | 0.244 秒 | 12.64 秒 | 12.11 秒 |
160,491 | 0.220 秒 | 12.91 秒 | 12.91 秒 |
若干ゆれがありますが、概ねトリプル数の増加とともに検索時間が増えてますが、(2)、(3) はその増え方がかなり大きく、トリプル数取得するだけで10秒もかかるのはどうかと思いました。API Gatewayの仕様で30秒でタイムアウトするので、これ以上のトリプル数だと結果が得られずタイムアウトする可能性が高いです。
どうやら全スキャンがかかるようなクエリの実行のより多くの時間がかかっているっぽい感じがします。例えば、(1) に order by
追加するだけで極端に時間がかかるようになりました。ちなみに、Lambdaはメモリサイズを増やすとCPUの性能もアップするらしいですが、最大の3008MBにしても大きな差はなかったです。
個人的な用途でいろいろ目をつぶるにしても、10万トリプルぐらいが限界かなと思います。
まとめ
- (個人的には)SPARQLエンドポイント構築は簡単になった
- ちゃんとSPARQLで検索ができる
- トリプル数とクエリによっては実行が遅い、最悪タイムアウトする
- トリプル数が少ないデータセットなら一応運用は可能
今回使っているRDFストアnode-quadstoreの開発中のブランチを見てみるとSPARQLクエリ実行の高速化も現在対応しているっぽい?ので、将来的に結構使えるものになるかもしれません。ちょっとこの方法を試すには時期が早かったのかも...
今後この方法とは違う方法でも、AWSサーバレスでSPARQLエンドポイント構築挑戦してみたいと思います。