在某业务场景中,实例日常的处理能力在 1100/s,CPU 使用率在 50% 左右。
当请求突增长到 1500/s 时,几分钟之内,延时从 150ms 变得几乎都超时、请求堆积,CPU 使用率达到 100%,所有请求几乎完全不可用。
请求从 1100/s 增加到 1500/s,QPS 也就增加了 40%~50%(甚至更少),为何延时、 CPU 使用率没呈比例放大,而是接近崩溃?
理想条件下,在实例原本处理能力范围内的请求应该成功,只是新增的那部分请求失败,为何全部请求都几乎失败?
核心影响因素是:实例内部队列堆积和线程过多。
示例:
假设处理能力是 1300/s,接收的请求却是 1500/s,那么每秒就堆积了 200 个请求。
实例默认队列大小为 1000 个,在该示例中,5s 就可以将实例队列堆满,此时实例会启用 CPU core*1.5(上限)的线程数来执行查询请求,CPU 使用率立马就提升。
由于 CPU 负载很高、线程很多、存在线程争用,此时单个请求的处理延时会高于平时耗时的数倍,进一步降低了集群处理能力。
从实例内部队列中拿出请求后,如果是 search 相关的请求,需要先判断已经在队列里等待的时间,超过一定时间(默认10s),则失败返回,而不是继续执行。
作出以上处理的判断原因有以下两条:
支持动态更新 search 队列中的超时时间。命令如下:
PUT _cluster/settings { "persistent": { "thread_pool.search.queue_wait_timeout":"30s" } }
如果您在更新可控延迟队列超时参数的过程中遇到难以解决的问题,可以通过提交工单进行咨询。详情请参见技术支持。