GraphDB 查询无声地失败(OutOfMemoryError)
GraphDB queries fail silently (OutOfMemoryError)
我正在处理一个非常庞大的存储库(即 ~16M 语句)。我正在尝试获取图表中所有不同 class 成员模式的列表。这是查询:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
select distinct (group_concat(?t) as ?fo)
where {
?s rdf:type ?t.
}
group by (?s)
order by ?fo
当然这样的查询确实要return结果。奇怪的是,有时我会得到我需要的结果,有时查询 return 没有结果。
为什么会发生这种情况,我该如何避免?
PS:
监控查询,我注意到当我没有数据时,查询状态停留在:
IN_HAS_NEXT
0 operations
直到结论。
更新:
Here是描述问题的主要日志。 GraphDB workbench 中的输出是:
No results. Query took 1m 53s, minutes ago.
没有提到错误。很奇怪。正如 Gilles-Antoine Nys 指出的那样,这是内存和 Java 的 GC 的问题。总的来说,我认为 workbench 应该在这种情况下明确显示错误消息。
首先,您的查询无法为您提供可由类型定义的 class...为了表现力,我重新开始在您的 select
中添加 ?s
。这样您就可以轻松回答您的问题了。
这是最简单的查询:
select ?s (group_concat(?t) as ?fo)
where {
?s rdf:type ?t.
} group by (?s)
(order by(?fo)
如果对你重要可以加)。
其次,IN_HAS_NEXT
只是您在监视器中暂停查询时的一种状态。与错误无关。
最后,验证您的 query-timeout
参数。它的默认值设置为 0。
更新:
实际上您的日志文件中有两个错误。问题是您的 JVM 对您的内存进行垃圾收集的时间太长(超过 98% 的内存仍在使用中)。
一个解决方案是增加您的 GC 开销限制,因此可以处理您的庞大数据集。
正如其他评论所说,错误是由 OME 引起的。在下一个即将发布的 GraphDB 8.6 版本中,开发人员实现了所有聚合和不同的内存效率更高的实现。在 public 发布之前,只有几个选项可供测试:
- 通过编写稍微更优化的查询版本来减少消耗的内存量,该版本仅显示本地名称:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
select ?s_local (group_concat(?t_local) as ?fo)
where {
?s rdf:type ?t.
BIND (REPLACE(STR(?t), "^(.*)(/|#)([^#/]*)$", "") as ?t_local)
BIND (REPLACE(STR(?s), "^(.*)(/|#)([^#/]*)$", "") as ?s_local)
} group by (?s_local)
order by (?fo)
增加用于执行所有聚合计算的可用 RAM。您可以通过传递更高的 -Xmx
参数值或为 graphdb.properties 中的 graphdb.page.cache.size
设置最小数字来增加它,例如:graphdb.page.cache.size=100M
。缓存控制存储在内存页面中的数量,这对于您的查询和存储库大小不会有太大影响。
用-Dgraphdb.engine.function.concat.max-length=4096
限制组串的最大长度。该限制不会使查询成功执行,但会指示问题是否是主题太多太长的字符串。
GraphDB Free 的问题是:它会根据调用 workbench 增加堆大小。例如,如果您查询或只是刷新 workbench,您会看到堆大小增加。现在即使你有大量的内存,随着堆大小的不断增加,连续查询更多的查询也会产生 OOM。解决方案可能是在每次增加堆大小的调用中查找 GraphDB 存储的临时数据。
我正在处理一个非常庞大的存储库(即 ~16M 语句)。我正在尝试获取图表中所有不同 class 成员模式的列表。这是查询:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#>
select distinct (group_concat(?t) as ?fo)
where {
?s rdf:type ?t.
}
group by (?s)
order by ?fo
当然这样的查询确实要return结果。奇怪的是,有时我会得到我需要的结果,有时查询 return 没有结果。
为什么会发生这种情况,我该如何避免?
PS: 监控查询,我注意到当我没有数据时,查询状态停留在:
IN_HAS_NEXT
0 operations
直到结论。
更新:
Here是描述问题的主要日志。 GraphDB workbench 中的输出是:
No results. Query took 1m 53s, minutes ago.
没有提到错误。很奇怪。正如 Gilles-Antoine Nys 指出的那样,这是内存和 Java 的 GC 的问题。总的来说,我认为 workbench 应该在这种情况下明确显示错误消息。
首先,您的查询无法为您提供可由类型定义的 class...为了表现力,我重新开始在您的 select
中添加 ?s
。这样您就可以轻松回答您的问题了。
这是最简单的查询:
select ?s (group_concat(?t) as ?fo)
where {
?s rdf:type ?t.
} group by (?s)
(order by(?fo)
如果对你重要可以加)。
其次,IN_HAS_NEXT
只是您在监视器中暂停查询时的一种状态。与错误无关。
最后,验证您的 query-timeout
参数。它的默认值设置为 0。
更新:
实际上您的日志文件中有两个错误。问题是您的 JVM 对您的内存进行垃圾收集的时间太长(超过 98% 的内存仍在使用中)。
一个解决方案是增加您的 GC 开销限制,因此可以处理您的庞大数据集。
正如其他评论所说,错误是由 OME 引起的。在下一个即将发布的 GraphDB 8.6 版本中,开发人员实现了所有聚合和不同的内存效率更高的实现。在 public 发布之前,只有几个选项可供测试:
- 通过编写稍微更优化的查询版本来减少消耗的内存量,该版本仅显示本地名称:
PREFIX rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> select ?s_local (group_concat(?t_local) as ?fo) where { ?s rdf:type ?t. BIND (REPLACE(STR(?t), "^(.*)(/|#)([^#/]*)$", "") as ?t_local) BIND (REPLACE(STR(?s), "^(.*)(/|#)([^#/]*)$", "") as ?s_local) } group by (?s_local) order by (?fo)
增加用于执行所有聚合计算的可用 RAM。您可以通过传递更高的
-Xmx
参数值或为 graphdb.properties 中的graphdb.page.cache.size
设置最小数字来增加它,例如:graphdb.page.cache.size=100M
。缓存控制存储在内存页面中的数量,这对于您的查询和存储库大小不会有太大影响。用
-Dgraphdb.engine.function.concat.max-length=4096
限制组串的最大长度。该限制不会使查询成功执行,但会指示问题是否是主题太多太长的字符串。
GraphDB Free 的问题是:它会根据调用 workbench 增加堆大小。例如,如果您查询或只是刷新 workbench,您会看到堆大小增加。现在即使你有大量的内存,随着堆大小的不断增加,连续查询更多的查询也会产生 OOM。解决方案可能是在每次增加堆大小的调用中查找 GraphDB 存储的临时数据。