【发布时间】:2015-10-29 13:13:35
【问题描述】:
我正在使用带有 Cassandra 后端存储的 Titan 数据库(版本 1.0.0)。我的数据库非常大(数百万个顶点和边)。我正在使用弹性搜索进行索引。它做得非常好,我相对容易快速地接收到数千个 (~40000) 顶点作为我的查询的答案。但是我遇到了性能问题,然后我尝试迭代 thou 个顶点并检索保存在顶点属性上的基本数据。我大概花了将近 1 分钟!!!
使用 Java 8 的并行流显着提高了性能,但还不够(10 秒而不是 1 分钟)。
考虑到我有一千个具有位置属性和时间戳的顶点。我只想检索查询区域内具有位置(Geoshape)的顶点并收集不同的时间戳。
这是我使用 Java 8 并行流的 Java 代码的一部分:
TitanTransaction tt = titanWraper.getNewTransaction();
PropertyKey timestampKey = tt.getPropertyKey(TIME_STAMP);
TitanGraphQuery graphQuery = tt.query().has(LOCATION, Geo.WITHIN, cLocation);
Spliterator<TitanVertex> locationsSpl = graphQuery.vertices().spliterator();
Set<String> locationTimestamps = StreamSupport.stream(locationsSpl, true)
.map(locVertex -> {//map location vertices to timestamp String
String timestamp = locVertex.valueOrNull(timestampKey);
//this iteration takes about 10 sec to iterate over 40000 vertices
return timestamp;
})
.distinct()
.collect(Collectors.toSet());
使用标准 java 迭代的相同代码:
TitanTransaction tt = titanWraper.getNewTransaction();
PropertyKey timestampKey = tt.getPropertyKey(TIME_STAMP);
TitanGraphQuery graphQuery = tt.query().has(LOCATION, Geo.WITHIN, cLocation);
Set<String> locationTimestamps = new HashSet<>();
for(TitanVertex locVertex : (Iterable<TitanVertex>) graphQuery.vertices()) {
String timestamp = locVertex.valueOrNull(timestampKey);
locationTimestamps.add(timestamp);
//this iteration takes about 45 sec to iterate over 40000 vertices
}
这个表现让我很失望。如果结果是大约 100 万个顶点,那就更糟了。我试图了解这个问题的原因。我希望这应该花费我更少的 1 秒来迭代 thou 个顶点。
【问题讨论】:
-
性能与执行它的机器上的资源相关...如果您想提高处理时间,请尝试使用多线程处理一批顶点(例如10000个顶点)
-
Java 8 的并行流由多线程处理。
-
好的!我还在Java7中!谢谢(你的)信息!所以很难做得更好:40000 个顶点的 10 秒还不错:这不是问题!也许您必须审查您的流程以获得更少的顶点!您可以使用构造函数(int initialCapacity,float loadFactor)设置集合的大小,您将获得一些时间而不是扩展集合!