【问题标题】:Titan Database: performance issue to iterate over thousands vertices in java codeTitan 数据库:在 Java 代码中迭代数千个顶点的性能问题
【发布时间】: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)设置集合的大小,您将获得一些时间而不是扩展集合!

标签: java cassandra titan


【解决方案1】:

相同的查询,但使用 gremlin 遍历而不是图形查询具有更好的性能和更短的代码:

TitanTransaction tt = graph.newTransaction();
Set<String> locationTimestamps = tt.traversal().V().has(LOCATION, P.within(cLocation))
    .dedup(TIME_STAMP)
    .values(TIME_STAMP)
    .toSet();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-28
    • 1970-01-01
    相关资源
    最近更新 更多