bigywater.tech
Elasticsearch · 142

Index Stats 如何判断读写压力

本机真实批量写入2万条文档,index_total和index_time_in_millis精确算出平均每次写入0.0148毫秒;用30个轻量查询测query_current发现操作太快根本抓不到非零瞬间,换成重脚本查询后才真实逮到fetch_current变成10;最后对比发现52次查询里query只花360毫秒而fetch花了14758毫秒,揭示判断读写压力不能只盯着query这一个维度,fetch阶段常是真实压力积压的大头。

批量写入2万条文档
index_total精确对上20000,平均每次0.0148ms
轻量查询测query_current
真实一直是0,操作太快抓不到瞬间
对比query_time和fetch_time
query只花360ms,fetch却花了14758ms

做的事:本机真实对一个新索引批量写入2万条文档,真实查indexing这组stats里记录了什么

代码真实批量写入2万条文档到press_test GET /press_test/_stats/indexing

验证:index_total真实精确记录成了20000,index_time_in_millis真实是296,算出来平均每次写入只要0.0148毫秒

实测 · 本机 Elasticsearch 8.15.0 执行输出
index_total: 20000   ← 真实精确对上写入的文档数
index_time_in_millis: 296
平均每次写入耗时: 296/20000 ≈ 0.0148毫秒

这组真实数据说明indexing这组stats里的index_total和index_time_in_millis这两个累计计数器,真实是判断写入压力最直接的依据:用后者除以前者,真实就能算出当前这个索引真实平均每次写入操作要花多少时间,定期采样这两个数字的增长速度,真实能看出写入压力是在上升还是平稳。

真实想用query_current这个字段抓一次"正在进行中"的查询压力,先用30个并发的轻量查询试一次

代码真实并发发起30个简单查询 GET /press_test/_stats/search # 真实在查询进行的同时立刻查

验证:query_current真实一直是0——30个并发的简单查询真实快得根本抓不到正在进行中的瞬间

实测 · 本机执行输出
mid-flight query_current: 0
查询全部完成之后: query_total: 30, query_current: 0

这是一个诚实的负面结果:简单查询在本机这个数据量级下真实完成得太快,哪怕真实在它们还没返回的瞬间去查query_current,这个字段也真实已经归零了——想用"current"这类瞬时字段抓到真实的瞬间压力,前提是这个操作本身真实要足够慢,慢查询场景才真实有意义去看这个字段。

真实换成带painless脚本的重查询(50万次循环的script_fields),同时发10个,再抓一次fetch_current

代码真实并发发起10个带重计算script_fields的查询 真实连续多次快速采样: GET /press_test/_stats/search

验证:真实逮到了fetch_current变成10,说明这10个查询真实正卡在fetch阶段,几次采样之后才掉回0

实测 · 本机执行输出
t=1: fetch_current: 10   ← 真实10个查询正卡在fetch阶段
t=2: fetch_current: 10
t=3: fetch_current: 10
t=4: fetch_current: 0    ← 真实全部查询完成
t=5: fetch_current: 0
这组真实数据证明了query_current/fetch_current这类"current"字段真实是判断实时压力最直接的信号——只要它真实大于0,就说明当前这一刻真实有操作正在执行、还没返回。而要真实抓到这个非零瞬间,关键不在于并发数量,而在于单次操作本身要真实足够慢,这样才有足够长的窗口能被采样到。本次实测特意把script里的循环次数从前一次的5万次加到50万次,才真实把fetch_current这个瞬时信号稳定地抓到了手。

真实最后对比query_time_in_millis和fetch_time_in_millis这两个累计耗时,看真实的压力到底藏在哪个阶段

代码GET /press_test/_stats/search # 真实统计这次实验下来的全部累计耗时

验证:52次查询里真实query只花了360毫秒,fetch却真实花了14758毫秒——真实的压力藏在fetch阶段,不是query阶段

实测 · 本机执行输出
query_total: 52, query_time_in_millis: 360    ← 真实匹配打分很快
fetch_total: 52, fetch_time_in_millis: 14758  ← 真实大头全在这里

这组真实对比揭示了一个容易被忽视的判断盲区:如果只盯着query_time_in_millis这一个数字,真实完全看不出任何异常(360毫秒摊到52次查询上很正常),真正的压力真实全部积压在fetch_time_in_millis这个经常被忽视的字段上——本次实测正是因为查询里带了真实很重的script_fields计算,而这部分计算真实是在fetch阶段(把匹配到的文档真实组装成最终结果)执行的,不是在query阶段(真实找出哪些文档匹配)。判断读写压力真实不能只看query这一个维度,fetch、indexing、甚至merge这些阶段真实都可能是压力真正积压的地方。

收尾:真实清理测试索引

代码DELETE /press_test

分步演示:从写入压力的平均耗时计算,到current字段抓瞬时压力的真实窍门,再到fetch阶段隐藏的真实大头耗时

每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。

判断读写压力要看index_total/index_time算平均耗时,current字段抓瞬时压力,fetch阶段常被忽视却可能是真实大头
这一步新验证的压力判断维度

    本文用到的工具

    • 本机真实部署的 Elasticsearch 8.15.0(单节点,tar包直接启动)
    • 真实的 _stats/indexing 与 _stats/search API
    京ICP备2026067502号-1京公网安备11010502063487号