【问题标题】:Performance issues using neo4j rest http client使用 neo4j rest http 客户端的性能问题
【发布时间】:2016-02-24 09:57:17
【问题描述】:

在用 Apache http 客户端替换 neo4j-jdbc 客户端后遇到了这个问题。

在只运行 1k 个并发用户执行我们的查询时,我们似乎仍然存在问题。

这是我们使用客户端的方式: https://gist.github.com/IdanFridman/1989b600a0a032329a5e

这就是我们使用那个 rest-client 执行查询的方式:

https://gist.github.com/IdanFridman/22637f95ba696f498b6c

分析后,我们看到了上述糟糕的性能结果:

每个请求的平均延迟为 3 秒。

我们应该抛弃 neo4j 吗?我们对表演结果感到绝望

谢谢。

【问题讨论】:

  • 您可能有 1k 用户竞争整个 2 个并发连接 HttpClient 默认允许同一路由。这肯定会非常缓慢。有关补救措施,请参阅@FylmTM 答案

标签: performance neo4j connection cypher apache-httpclient-4.x


【解决方案1】:

那么,您想要更多并发请求吗?让我们探索一下我们可以在这里做什么。

查询

首先 - 检查查询是否执行得足够好。复制粘贴 Neo4j 浏览器,在前面加上 PROFILE 并浏览输出。

您的查询可能比您预期的要多得多。这会导致等待时间很长,因为 Neo4j 仍在执行查询。

客户

HttpClient 配置

您正在使用PoolingHttpClientConnectionManager。 来自文档:

PoolingHttpClientConnectionManager 维护每个路由的最大连接数限制。默认情况下,此实现将为每个给定路由创建不超过 2 个并发连接,并且总共不超过 20 个连接。

所以,我们应该增加限制。示例:

PoolingHttpClientConnectionManager cnnMgr = new PoolingHttpClientConnectionManager();
cnnMgr.setMaxTotal(500);
cnnMgr.setDefaultMaxPerRoute(100);

HttpRequest

尝试在请求中添加 keep-alive 标头。示例:

request.setHeader("Connection", "keep-alive");

那么,您应该尽快关闭您的回复。您不应该依赖这样一个事实,即当您用尽流内容时,连接已关闭。代码:

try(CloseableHttpResponse response = httpClient.execute(request)) {
    // do stuff with response here
    // close response when try-with-resource block ends
}

记住 - 您从服务器事务端点接收的内容流回客户端。

return createResultSet(new JsonObject(IOUtils.toString(response.getEntity().getContent())));

因此,在此代码示例中,我们一直等到检索到完整响应,然后才开始序列化。

在你的情况下,你正在寻找这样的东西:

String rawJsonResult = null;
try(CloseableHttpResponse response = httpClient.execute(request);) {
    rawJsonResult = IOUtils.toString(response.getEntity().getContent());
} catch (IOException e) {
    throw new RuntimeException(e);
}
return createResultSet(new JsonObject(rawJsonResult));

通过这样做,我们确保在任何序列化发生之前检索结果并关闭连接。这将为其他并发连接释放资源。

服务器

Neo4j 使用 Jetty 作为 Web 服务器。 Jetty 由 BlockingQueue 支持。这意味着有x 可以处理的并发HTTP 请求量。这个x 是队列大小。如果我们有超过x 数量的并发请求,那么队列中有一个空闲位置等待。

幸运的是,您可以configure 队列有多大。您对此房产感兴趣:

org.neo4j.server.webserver.maxthreads=200

注意:这里没有魔法。默认情况下,Neo4j 使用cpuCount * 4 数量的 Web 服务器线程。增加此数量可能会导致并发请求数量增加,但每个请求可能会变慢。

Linux

你应该check this。每个 TCP 连接都是一个单独的文件。通常,大多数 Linux 发行版的默认值是1024。你需要增加它。你可以试试40000

记住——这不仅适用于服务器,也适用于客户端。您不仅要接收连接,还需要打开它们。

一般说明

您不应该那么相信分析结果。我们在发出 HTTP 请求时等待是完全可以的。总的来说 - 这是沟通中最昂贵的部分。

此外,您应该确保您的客户端和服务器位于同一本地网络上。通过公共网络进行请求会显着降低性能。

最后一个 - 并发 HTTP 连接有上限。超过这个限制会使数据库几乎没有响应(类似于任何其他 Web 应用程序)。您可能需要考虑水平扩展(Neo4j 集群)才能发出更多并发请求。


祝你好运!

【讨论】:

  • 感谢您尝试更改并做出回应。顺便说一句,我们也使用 ssl。我的这也让我们变慢了?
  • @rayman 应该没那么糟糕。一般来说,如果不能访问环境,就很难讨论性能问题。性能改进都是关于“尝试”-“改进”-“再试一次。
  • 是的,我们已经做了好几天了。筋疲力尽。我会尝试您的改进并发布结果和结论(并标记您的答案!)。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多