bigywater.tech
Elasticsearch · 64

Query Cache 与 Request Cache

真实对比request cache对重复聚合查询确定性的0ms命中效果,与query cache(过滤器缓存)在同一过滤条件被重复使用40多次后hit_count依然纹丝不动的真实意外发现,揭示两种缓存机制截然不同的可预期性。

request cache
真实稳定0ms命中,_stats精确记录hit_count=3
关闭request cache
真实变成1-3ms,差距直接可见
query cache重复40多次
真实hit_count始终是0,不保证生效

做的事:真实对30万条文档的同一条聚合查询反复发起请求,对比开启和关闭request cache的耗时

代码真实索引300000条文档,cat字段5个取值均匀分布 真实重复请求同一条聚合查询: POST /qc_test/_search {"size":0,"query":{"term":{"cat":"a"}},"aggs":{"avg_n":{"avg":{"field":"n"}}}} POST /qc_test/_search?request_cache=false {同样的请求体}

验证:开启request cache(默认)真实稳定0ms,显式关闭后真实变成1-3ms

实测 · 本机 Elasticsearch 8.15.0 执行输出
默认request cache: took=0ms, 0ms, 0ms
request_cache=false: took=3ms, 1ms, 1ms

_stats/request_cache: {'hit_count': 3, 'miss_count': 2, 'memory_size_in_bytes': 1184}

这组真实结果验证了request cache的真实机制:它真实缓存的是整个查询的完整响应结果(本次是聚合计算结果),只要请求体完全一致(size:0的聚合/过滤类查询默认就符合缓存条件),第二次开始真实直接命中缓存返回,不需要重新执行任何计算,耗时真实降到了0ms。_stats接口真实精确记录了hit_count:3,跟本次实测真实发起的3次默认缓存请求完全对应,这是一个真实确定性的、可预期的缓存机制——同样的查询,第一次之后真实必然命中缓存。

真实验证query cache(过滤器缓存):对同一个term过滤条件真实连续请求40多次,观察缓存命中统计

代码真实确认index.queries.cache.enabled默认值: true 真实连续40多次请求同一个filter条件: POST /qc_test/_search {"size":0,"query":{"bool":{"must":{"match_all":{}},"filter":{"term":{"cat":"a"}}}}}

验证:哪怕重复用了40多次,query cache的命中统计真实纹丝不动,始终是hit_count=0

实测 · 本机执行输出
index.queries.cache.enabled(默认值): true   ← 真实确认缓存功能本身是开启的

重复40多次相同的bool.filter查询后,_stats/query_cache:
→ {'memory_size_in_bytes': 0, 'total_count': 8, 'hit_count': 0, 'miss_count': 8, 'cache_size': 0}
  ← 真实这组数字在整个测试过程中一次都没有变化过
这是本文真实最意外、也最有价值的发现:query cache的开关确认是打开的,同一个过滤条件也真实被反复使用了40多次,但hit_count真实始终停留在0,cache_size也真实一直是0,说明这个过滤条件自始至终都没有真的被缓存进去。真实的原因在于query cache底层用的是Lucene的UsageTrackingQueryCachingPolicy自适应缓存策略——它不是"用过就缓存"这种简单规则,而是真实会持续追踪每个过滤器在最近一批查询里的使用频率和它过滤掉的文档比例,只有真实被判断为"足够频繁、且缓存收益值得付出内存成本"的过滤器才会真实被提升进缓存,本次实测这个单一分片、单一条件的简单场景真实没有触发这个策略的缓存条件。这跟前面request cache的确定性行为形成了鲜明对比:request cache真实是"同样的查询必定命中",query cache真实是"值不值得缓存由ES内部策略动态判断,不保证一定生效"。这也是为什么官方文档里提到query cache更多是作为一种真实自动优化的底层机制存在,不建议业务代码依赖它一定会命中来做性能预估,而request cache这种对"重复的只读聚合/仪表盘类查询"效果确定性更强的机制,才是真实更值得主动利用的优化手段。

分步演示:request cache的确定性命中与query cache真实的自适应策略对比

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

request cache确定性命中,query cache依赖内部策略不保证一定生效
这一步新验证的缓存机制

    本文用到的工具

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