查找较慢的弹性搜索响应的原因

时间:2016-03-28 22:56:50

标签: php elasticsearch

我在电子商务网站上使用elasticsearch已经有一段时间了 - 不仅用于搜索,还用于检索产品数据(/ index / type / {id})以避免SQL查询。

通常这种方法非常有效,大多数请求在1ms到3ms之间得到解答。但有一些请求需要100ms-250ms - 仅用于/ index / type / {id}这样的GET请求,其中没有进行实际搜索,通常需要1-2ms。在我看来,如果这样的响应需要超过100毫秒,那肯定是错误的,因为服务器有很多RAM和一个快速的6核CPU,数据存储在速度非常快的SSD上,只有150'000个条目(Elasticsearch大约300MB)并且几乎没有负载。 Elasticsearch有5GB的RAM,并且Lucene有足够的备用RAM来一直缓存所有条目。请求通过具有专用交换机的本地网络进行。索引只有一个分片,我正在运行Elasticsearch 2.3。

我正在用PHP做请求。我已经尝试过使用Nginx作为Elasticsearch的反向代理,但这并没有解决任何问题 - 无论是否存在Nginx都会发生这种情况。

编辑:大约1%的时间发生缓慢请求(与请求总数相关)。我也可以通过在Elasticsearch中将1000个请求用PHP转换为/ index / type / {id}来重现它 - 总是1%会非常慢,即使使用相同的ID如/ index / type / 55(只要ID存在)。这也意味着没有“缓存效应” - 在第一次请求之后Elasticsearch应该将数据“准备好”,但无论我请求什么ID或者我一遍又一遍地请求相同的ID,慢速请求的数量都是相同的。

Edit2 :我看过Marvel&节点的节点统计数据Kibana,没有任何迹象表明那里有减速:使用了20-40%的JVM堆内存,几乎没有延迟(0.1ms到0.5ms之间)。它确认有足够的资源,我看不出任何缓慢请求的原因的相关性或提示。

经过大量测试后

这些现在是我明确的测试结果:

  • Elasticsearch的响应越大,请求发生的速度就越慢。许多小的回应比一次大回应有更大的机会不会特别慢。
  • 使用简单的GET请求轰炸Elasticsearch可以减少我并行运行更多请求时响应速度慢的可能性。
  • 当一次又一次地使用简单搜索一个关键字时,Elasticsearch在响应中告诉我它“花了”2-3ms,即使响应需要200ms直到我的应用程序收到它。但也在这里:响应越大,响应速度越慢的可能性越大。当我运行请求循环时,1KB响应永远不会慢,2.5KB在极少数情况下只有一点点慢(30ms),10KB响应总是有高达1%的慢速请求,最多200ms。

我已经考虑到它可能是一个网络“问题”,特别是当Elasticsearch认为它很快时,即使它很慢。但这将是一个奇怪的根本原因,因为我的设置非常标准(Debian Jessie)。此外,保持活动连接和TCP_NODELAY无助于改善此问题。

任何人都知道如何找到根本原因,以及可能发生的事情?

1 个答案:

答案 0 :(得分:1)

我终于找到了可测量缓慢响应的原因:它是网络驱动程序,甚至可能是网卡上的硬件实现。

当从节点本身运行测试时,慢响应消失了,我还注意到旧的服务器(8年前与仅2年的新服务器相比)在对它们运行测试时没有缓慢的响应,表示请求服务器有故障,而不是响应的ES服务器,但它也表明网络本身没问题,因为只有“新”服务器有这个问题。

我走下了TCP /网络设置的兔子洞,找到了ethtool,它显示了网络配置并允许更改它。我了解到有一种称为“卸载”的东西,其中许多网络操作被卸载到网卡(特别是将请求和响应分成段),并尝试使用以下命令禁用所有卸载:

ethtool -K eth1 tx off rx off sg off tso off ufo off gso off gro off lro off rxvlan off txvlan off rxhash off

之后我的请求 - 来自ES的1000次相同搜索速度与预期一样快 - 没有慢速请求了。我的网卡(运行e1000e驱动程序的SuperMicro X9SRL-F上的英特尔®82574L双端口GbE LAN)似乎在硬件中做了一些事情,这会减慢响应速度,或者阻止响应,或者其他什么。较旧的服务器正在运行tg3驱动程序 - 它们已启用卸载(根据ethtool),但它不会导致这些延迟响应。禁用卸载对CPU负载没有明显影响,这可能适用于任何现代CPU。

使用新设置,我可以将慢速页数减少,因为Elasticsearch响应速度较慢,为0.07%,之前约为1%。我还注意到使用Nginx作为Elasticsearch的反向代理导致了一些缓慢的响应,即使它们并不多 - 通常每150'000大约有3-5个响应超过50ms。如果没有Nginx,只需直接查询Elasticsearch,我现在就无法重现任何慢速请求,即使是大规模的。

更新11/2017

更新到Debian Stretch并使用内核4.9运行服务器后,所有剩余的“慢速请求”都消失了。所以这个问题似乎至少部分植根于较旧的Linux内核。