我一直在为电子商务网站使用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之间和没有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不会改善此问题.
任何人都知道如何找到根本原因,以及可能发生的事情?
最佳答案 我终于找到了可测量的慢响应的原因:它是网络驱动程序,甚至可能是网卡上的硬件实现.
当从节点本身运行测试时,慢响应消失了,我还注意到旧的服务器(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月11日
在更新到Debian Stretch并使用内核4.9运行服务器之后,所有剩余的“慢速请求”都消失了.所以这个问题似乎至少部分植根于较旧的Linux内核.