ES索引的后一公里,减少后的延迟
我经常被问到这样的问题:ES大能撑多少QPS ? 确实这比证明我爸是我爸的问题更难解释清楚,不过我通常会给出两个选择;1)你是否希望尽量高QPS而不需要管大latency甚至是总体latency升的很高? 2)你是否希望大的latency 尽量的低,甚至不允许发生大于XXX的latency?因此这个回答需要你对你需要实现的业务熟悉。
大促在即,近几个索引被盯上了,因为出现了类似99.9% 百分位延迟很大的问题,大家都知道,在电商大并发的系统里,任何的延迟抖动后可能都会导致非常恐怖的崩塌效应,因此近两周都在仔细地琢磨这个问题,想尽力去解决。
话不多说,出正题,当前我们的索引遇到了下面的问题:
- 索引A,百万级,用terms + Time range + aggs, 偶尔延迟抖动很厉害,大延迟去到1s
- 索引B,亿级别,只对id 做terms 查询,平均延迟几ms,但是99.9% 百分位延迟有500ms+,重点调优对象
- 这几个索引的indxing rate 在几百上千不等,在优化这几个索引期间,用定时任务做force merge,但是发现做force merge时总体延迟非常高,需要分析为什么会这样。
问题一:range, range 还是range 惹的祸
个问题,由于terms 只会过滤出非常少量的结果,因此我猜测aggs 是非常稳定的,首先排除,大嫌疑肯定就是这个Time range 了,因此解决办法也非常迅速,因为terms 结果集很少,那么就直接把Time 的range 放一个script在内存算好了, 结果当然是,延迟抖动没有了! 之前的文章也曾经介绍过,对于不做数学运算,不做聚合的数字类型应该用keyword 来建索引,但是像类似时间这种类型,其实本质上还是用了long来存,所以对它做range时,之前说的那些Elasticsearch 5.x 源码分析(12)对类似枚举数据的搜索异常慢的一种猜测 问题都还是会有,本质都是用了Lucene 新的 Block K-d Tree 的数据结构引起的,因此如果你做的range结果集非常大的话就还是有问题,避免的方式无非就是减少这些bucket的数量,比如采用秒级时间戳落盘,而不是毫秒,这样查询速度提升还是很明显的。
那你应该会问了,新版本ES不是修了这个issue了么,是的,在新的Lucene 里这个查询被一个IndexOrDocValuesQuery ("Points + Doc values") 包了一层,如果Lucene的新solution 还不清楚的再次翻一下上面的这个连接,下面我们从性能的角度再看这个问题。
相关文章