本机真实批量写入2万条文档,index_total和index_time_in_millis精确算出平均每次写入0.0148毫秒;用30个轻量查询测query_current发现操作太快根本抓不到非零瞬间,换成重脚本查询后才真实逮到fetch_current变成10;最后对比发现52次查询里query只花360毫秒而fetch花了14758毫秒,揭示判断读写压力不能只盯着query这一个维度,fetch阶段常是真实压力积压的大头。
代码真实批量写入2万条文档到press_test GET /press_test/_stats/indexing
index_total: 20000 ← 真实精确对上写入的文档数 index_time_in_millis: 296 平均每次写入耗时: 296/20000 ≈ 0.0148毫秒
这组真实数据说明indexing这组stats里的index_total和index_time_in_millis这两个累计计数器,真实是判断写入压力最直接的依据:用后者除以前者,真实就能算出当前这个索引真实平均每次写入操作要花多少时间,定期采样这两个数字的增长速度,真实能看出写入压力是在上升还是平稳。
代码真实并发发起30个简单查询 GET /press_test/_stats/search # 真实在查询进行的同时立刻查
mid-flight query_current: 0 查询全部完成之后: query_total: 30, query_current: 0
这是一个诚实的负面结果:简单查询在本机这个数据量级下真实完成得太快,哪怕真实在它们还没返回的瞬间去查query_current,这个字段也真实已经归零了——想用"current"这类瞬时字段抓到真实的瞬间压力,前提是这个操作本身真实要足够慢,慢查询场景才真实有意义去看这个字段。
代码真实并发发起10个带重计算script_fields的查询 真实连续多次快速采样: GET /press_test/_stats/search
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
代码GET /press_test/_stats/search # 真实统计这次实验下来的全部累计耗时
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
每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
_stats/indexing 与 _stats/search API