参考 《实践篇(四):Apache jena SPARQL endpoint及推理》(方法不完全一样),搭建了一个知识图谱,在fuseki的web页面上传从结构化数据构建而来的本体实体后,能够正常使用,但是有几个问题:
- 我默认使用
OWLFBRuleReasoner
推理机,开启后查询速度太慢,慢到只能被迫关闭推理机的程度; - 知识图谱的结构化数据源定时刷新,相应的知识图谱也应该定时刷新,这需要代码化的更新fuseki的本体和实体的方法;
- 知识图谱保存在服务器的内存里,如何保存到磁盘中?
本文是针对问题1的。
问题描述
OWLFBRuleReasoner
推理机开启后查询速度太慢,三元组数量少的情况下尚能使用,当三元组数量增加至约800万时,一个简单的查询耗时超过10分钟仍未完成,甚至报错OutOfMemory。
解决方案
解决方案1
项目实际上不需要推理机的情况下,修改run/configuration/fuseki-conf.ttl 关闭推理机功能。
解决方案2
如果项目实际上只需要数量很少的特定推理规则,可以自行定义,避免引入冗余的规则。
参考:jena fuseki 自定义推导规则(OWLFBRuleReasoner推理机)
解决方案3
按照实际需求选用以下推理机,选择满足要求的最轻量的推理机(详见官方文档:配置Fuseki):
- 通用规则推理器:http://jena.hpl.hp.com/2003/GenericRuleReasoner
- 传递推理器:http://jena.hpl.hp.com/2003/TransitiveReasoner
- RDFS 规则推理器:http://jena.hpl.hp.com/2003/RDFSExptRuleReasoner
- 完整OWL推理器:http://jena.hpl.hp.com/2003/OWLFBRuleReasoner
- 迷你OWL推理机:http://jena.hpl.hp.com/2003/OWLMiniFBRuleReasoner
- 微型OWL推理机:http://jena.hpl.hp.com/2003/OWLMicroFBRuleReasoner
我采用解决方案3,将推理机从OWLFBRuleReasoner替换为OWLMicroFBRuleReasoner,查询同样数量约800万的三元组时,查询能够顺利返回结果,耗时从 >10min 缩短为 21ms。
后续使用中三元组数量增加到超过5000万,开启推理机后查询太慢,内存消耗太大,无法使用。无奈之下,在sparql语句中手动实现近似的推理效果。
更新:
问题仍然存在:
采用解决方案3,顺利在jena中部署大量三元组并稳定运行一段时间后。我在本体中增加了更复杂的概念层级,在实体文件中增加了更多的三元组数量。在使用OWLMicroFBRuleReasoner推理查询时,会报错java heap space,关闭推理机/使用TransitiveReasoner后能够顺利查询,但是丢失了本体中的概念层级关系。
接下来考虑:
1.增加jvm内存量
在fuseki-server内修改 JVM_ARGS=${JVM_ARGS:--Xmx4G}
为JVM_ARGS=${JVM_ARGS:--Xmx6G}
。
第一次查询很慢(259s),后续查询为毫秒级(大概100~200ms波动),只要内存够大,这个办法还是管用的。
运行相同的查询语句5次,记下平均耗时,调整内存大小,观察内存和耗时的对应关系:
8G - 196.6ms
10G - xxx ms
(8G + tdb存储) - 311.4ms
2.具体分析报错的原因是三元组的数量太大,还是本体中的推理规则太复杂
① 以本体文件不变为前提,大幅减少三元组的数量后进行简单查询(含推理),第一次查询耗时24s,后续的查询均为毫秒级;
② 保持三元组数量不变,降低本体的复杂程度,进行查询,毫秒级查询速度。
故并以上问题非单纯的本体复杂/实体的三元组过多导致,而是两者共同作用下导致。