看,灰机...

profile返回结果耗时短,但slowlog中显示耗时长,可能是什么原因呢?

Elasticsearch | 作者 wangxinrong | 发布于2020年09月06日 | 阅读数:2255

最近我在做压测时,在请求中加了"profile": true参数,记录返回结果
并且开启slowlog记录所有请求的记录。
这个查询很简单,正常情况应该就1ms或者几ms的响应时间。
 
在slowlog中偶尔会发现took_millis 时间为几十或者上百ms的请求,但是查了这个请求对应的返回结果,在kibana的search profile中分析,显示出来总的查询用时只有0.1ms。
那么这个几十ms究竟用在哪边了呢?
已邀请:

pony_maggie - 公众号:犀牛饲养员的技术笔记

赞同来自:

查询分为query和fetch两步,profile显示的只是query的耗时。
另外,网络I/O的时间profile也不会统计。

wangxinrong

赞同来自:

我最近做了这样的压测
1.设置slowlog阈值为0ms,记录所有请求。
2.在压测脚本端记录请求的用时,查询里添加profile:true参数,记录所有返回值,并写到es里做统计。
3.取同一个分片里的160万个id做为查询条件,文档中的user_id和document id保持一致。查询时带routing参数。每20万条放一个文件里,同时跑8个python脚本来做压测。
4.查询时连接一台协调节点查,因为数据都来自一个分片,实际会到固定到一台数据节点上查,同一个协调节点同一个数据节点,避免其他干扰因素。
 
结果大概是这样:
1.用户端脚本这边,假定超过50ms的记录有1000条,那么在slowlog里能看到的记录有100-200条,也就是slowlog占10%左右。
2.slowlog中fetch和query用时长的比例大概在1:1到2:1左右。
3.其中query用时长的请求,在kibana search profile中统计的结果,大部分是create_weight用时长。
4.剩余的80-90%请求,因为没有详细的日志,只能看到其中有一部分是返回值中的took时间长,整个查询时间也长,比如took中是52ms,用户端脚本中记录54ms,大约差2ms的网络用时。但是有部分属于took中是1ms,脚本记录54ms,这中间剩下的时间不知道用在哪了。
 
情况基本上是我描述的这样,大部分时间似乎没有花在数据节点的查询上,那就可能是耗在了协调节点,但这部分并没有日志统计,不太好分析原因,不知道有什么好的思路查问题呢?

byx313 - BLOG:https://www.jianshu.com/u/43fd06f9589c

赞同来自:

1、gc?
2、磁盘波动也会造成影响,例如page cache的数据被清洗以后,从磁盘加载数据
3、数据在从data node返回到requestor node的耗时不会记录,是否是网络层面?
 
另外,如果都是只是几ms的查询,是否查询结果是被cache在节点中的,然后发生了cache失效以后重新从磁盘加载?

wangxinrong

赞同来自:

1.gc不太可能,我看监控上gc次数很少,而且这个错误分布很平均,如果是gc应该是某些gc的时间点会有一波时间长。
 
2.我是在专门用于测试的集群上做的查询,没有数据写入,只有上面提到的最简单的查询。应该不会有太多资源占用pagecache。并且这个查询本身很简单,即使没有缓存平时也能在几ms返回。
 
3.应该能排除网络原因,即使我用一台节点配置es,并且脚本跑在这台节点上,也有很多的查询时间长,但在slowlog中数量明显少于这个数的情况。
 
差不多各种配置我都试了下,都存在这种情况,比如:
在ES5和ES7默认配置下测试
设置不同的索引store.type,调整search线程数,或者是processor数
用get、query、filter方式查询
把测试速度调低,每0.1秒发一次查询
只有一台节点做集群,正常的集群配置,增加大量的协调节点分担查询负载的配置
 
现在我有个疑问,就是我试了不同版本,不同服务器,不同的参数配置(默认和其他性能调优参数都试过),都存在这种情况,是否ES本身的查询机制,就只能做到比如一个正常应该10ms以内的查询,查10万次里面,就有几百次是超过30ms或者50ms的情况呢?
如果是的话,有没有设置能避免出现这种情况?做到接近每次查询都能在10ms以内?

要回复问题请先登录注册