【问题标题】:Performance with @MapResult in spring-data-neo4jspring-data-neo4j 中 @MapResult 的性能
【发布时间】:2013-03-25 06:41:07
【问题描述】:

我正在使用spring-data-neo4j 通过 REST api 访问独立的 Neo4J 服务器。在使用 @MapResult 通过 spring 存储库检索对象以转换检索到的对象列表时,观察到严重的性能问题。

首先,我在服务器日志 (http.log) 中观察到,当我们在检索到的 @MapResult 接口上开始迭代或调用 getter/setter 时,会在后台触发大量 REST 请求。在一种情况下,当 Neo4J 服务器在同一台机器上运行时,它在迭代和访问 5 个@MapResult 对象列表时触发了 1900 多个休息请求,耗时超过 6 秒。

我将问题简化为获取如下所示的单个简单关系。我可以在 Neo4J 服务器日志中看到,当我调用 MyMapResultInterface.getRoute() 时,会触发 9 个 http 请求来获取这个单个对象。 这些数量的 http 请求是预期/设计的吗?还是我遗漏了什么?关于@MapResult 的用法及其含义的文档非常少。

关系模型:

@RelationshipEntity(type="ROUTE")
@TypeAlias("Route")
public class Route {

    @GraphId 
    private Long id;

    @StartNode
    private Location startAt;

    @EndNode
    private Location endAt;

    private String routeName;
    private String city;
    private long distance;
    private Date createdOn;
}

当我调用 MyMapResultInterface.getRoute() 时在 http.log 中看到的日志:

GET /db/data/relationship/28 HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/relationship/28 HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/relationship/28 HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/relationship/28 HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/relationship/28 HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/relationship/28 HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/node/13/properties HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/relationship/28 HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2
GET /db/data/node/25/properties HTTP/1.1" 200 0 "-" "neo4j-rest-graphdb/1.8.RC2

上面可以看到许多重复的 GETs。只是一种解释,看起来/db/data/relationship/28GETs 的数量等于对象 Route 中的字段总数,并且有两个 GET 请求 /db/data/node/{nodeId}/properties 可能是 @StartNode@EndNode 字段。

编辑: 根据我的观察,我注意到这不仅是@MapResult 的问题,也是来自存储库方法的简单映射结果的问题,下面的示例

Iterable<Route> routes = routeRepository.getAvailableRoutesForUser(user.getId());

即使这样也会向 neo4j 服务器触发大量 http rest 请求。

更新:

正如 Michael Hunger 在回答中所建议的那样,这两种方法可以提高 Neo4j REST api 的性能。但是,这会导致非常大的复杂密码查询和难以管理且难以维护的代码。

因此,最终在评估了所有方法之后,我们决定取消 Neo4j REST 接口并开始使用 Neo4j Embedded。 而且 Neo4j 嵌入式不适用于 Heroku,我们不得不取消 Heroku .我们将应用程序迁移到 Amazon AWS。

我们希望 Neo4j 早日拿出生产环境中性能可以接受的远程访问通道。

【问题讨论】:

    标签: performance rest neo4j cypher spring-data-neo4j


    【解决方案1】:

    好点,一般来说 SDN 的对象表示尚未针对 Neo4j 服务器 REST 交互进行优化。这将在使用 Neo4j 的二进制协议和密码的下一个主要版本中发生变化。

    你能测试一下从 Cypher 和

    中返回你感兴趣的信息吗?
    1. 直接从Result&lt;Map&lt;String,Object&gt;&gt; 读取作为方法返回类型和
    2. 来自仅公开这些原始类型的MapResult

    【讨论】:

    • 谢谢迈克尔。将使用您建议的方法进行测试。
    • 这些方法会导致复杂且难以维护的密码查询。所以我们决定使用 Neo4j 嵌入式而不是 REST。这让我们放弃了 Heroku,转而使用亚马逊 AWS。更新了问题以包含此更新。
    • @Gopi,使用嵌入式实例可以加快速度,但它仍然会在内部处理那么多请求,对吧?即使用嵌入式实例只会掩盖加载子图的大量请求的问题。
    • @Ryan 我认为是的。但它不应该影响性能,因为那些是内存调用。最后,这个逻辑一定要在某个地方执行吧?
    猜你喜欢
    • 1970-01-01
    • 2015-06-11
    • 1970-01-01
    • 2015-05-31
    • 1970-01-01
    • 2017-10-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多