簡體   English   中英

Neo4j Java API:最寬路徑算法性能問題

[英]Neo4j Java API: widest path algorithm performance issues

我使用的是neo4j-enterprise版本2.1.2,並且確實具有一個包含229626個節點和1667834個關系的圖形。 圖模型描述了哪個人認識具有給定時間戳記的關系的另一個人(包括每個人的標識符)。

我試圖使用Neo4j Java Core API(嵌入式模式)的現有dijkstra實現來定義最寬路徑問題的算法。 不幸的是,它執行得非常慢。 但是首先讓我向您展示當前實施的一些細節:

  1. 使用自定義CostEvaluator和PathExpander定義算法

     PathFinder<WeightedPath> finder = GraphAlgoFactory .dijkstra(new TimestampPathExpander(RelationType.KNOWS, Direction.BOTH, 1401746400, depth), new RelationshipCostEvaluator()); 

    數字“ 1401746400”表示時間戳。 應檢查每個小於或等於它的關系。 我還介紹了一種深度,以最大程度地減少路徑長度和搜索開銷。

  2. TimestampPathExpander

      @Override public Iterable<Relationship> expand(Path path, BranchState<String> state) { List<Relationship> results = new ArrayList<Relationship>(); if(path.length() >= depth) { return results; } for (Relationship r : path.endNode().getRelationships(relationshipType, direction)) { // Traverse only relations for the given timestamp long relationTime = (long) r.getProperty("timestamp"); if (relationTime <= timestamp) { results.add(r); } } return results; } 

    擴展器確實很簡單。 只需查看關系時間戳並將節點添加到結果列表即可。 如果生成的路徑已達到最大深度,則不會向其添加任何其他節點。

  3. 自定義費用評估器

     @Override public Double getCost(Relationship relationship, Direction direction) { double measure = significance.edgeStrength(relationship); return measure > 0 ? Double.MAX_VALUE - measure : 0; } 

該度量用作容量值,並根據包括起點和終點以及兩者之間關系的度量來計算。 因為dijkstra無法處理負邊緣權重,所以我只是從大量(Double.Max_value)中減去該度量,從而實現將較大的值解釋為“更便宜”。 返回零是不應該碰到的特殊情況。

這是我預熱緩存的方式:

    for ( Node n : GlobalGraphOperations.at(db).getAllNodes() ) {
        n.getPropertyKeys();
        for ( Relationship relationship : n.getRelationships() ) {
            Node start = relationship.getStartNode();
        }
    }

我還將使用軟緩存和以下graph.db屬性,以及在節點標識符以及關系的開始和結束位置上的索引:

neostore.nodestore.db.mapped_memory=3G
neostore.relationshipstore.db.mapped_memory=2G
neostore.propertystore.db.mapped_memory=100M
neostore.propertystore.db.strings.mapped_memory=500M
neostore.propertystore.db.arrays.mapped_memory=100M

neostore.propertystore.db.index.keys.mapped_memory=500M
neostore.propertystore.db.index.mapped_memory=500M

use_memory_mapped_buffers=true

以下是始終與預熱緩存一起執行的一些性能指標:

Cache warmup...    |   Cache warmup...
1742 ms            |   30056 ms
1106 ms            |   22696 ms
970 ms             |   24406 ms
849 ms             |   22842 ms
Angela Merkel      |   Angela Merkel
0.3                |   0.3
CDU                |   Wladimir Putin

大約3秒鍾,僅需跳一跳。 差不多了 有一些我不知道的技巧可以改善這些結果嗎? 也許我做錯了什么? 希望有人可以幫忙。

問候。

您的系統設置是什么?

看來您的mmio配置太高了,占用了您所有的堆,所以沒有為Neo4j的算法留下堆嗎? 您總共有多少記憶? 我認為對於您的圖來說,節點的10M和關系的50M綽綽有余。 您的熱身還應該訪問時間戳記/成本屬性,以便加載它們。

neostore.nodestore.db.mapped_memory=10M
neostore.relationshipstore.db.mapped_memory=100M
neostore.propertystore.db.mapped_memory=200M
neostore.propertystore.db.strings.mapped_memory=100M
neostore.propertystore.db.arrays.mapped_memory=0M

# remove both
neostore.propertystore.db.index.keys.mapped_memory=500M
neostore.propertystore.db.index.mapped_memory=500M

您還可以共享此方法的代碼嗎? significance.edgeStrength(relationship); 我不知道您的0成本是否會對算法產生不利影響,因為較小的成本將導致考慮更多路徑,並且如果成本不變(全部+0),那么它們將被平均加權...

如果您的長度小於限制,我只會構造一個ArrayList,否則只需返回Collections.emptyList();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM