真实对比20条独立查询挨个请求与打包进一次_msearch的总耗时差距,量化网络往返开销的真实占比,并验证_msearch里单条查询出错不会影响其他查询正常返回的错误隔离机制。
代码真实索引10篇文档,n字段从0到9 挨个请求: 真实循环20次,每次独立发起 POST /msr_test/_search {"query":{"term":{"n":i%10}}} 打包请求: POST /_msearch {"index":"msr_test"} {"query":{"term":{"n":0}}} {"index":"msr_test"} {"query":{"term":{"n":1}}} ... (真实总共20组)
20次独立的_search请求: elapsed_ms=18.07 1次打包了20条查询的_msearch请求: elapsed_ms=6.42 服务端报告每条查询真实执行耗时: took=0ms(全部都是0)
这组真实耗时对比最有意思的地方在于:每条查询服务端真实执行的时间都是0ms(数据量很小,查询本身几乎不消耗时间),但挨个发起20次独立请求真实总共花了18.07毫秒,而打包成一次_msearch真实只要6.42毫秒——这多出来的开销真实全部来自HTTP请求本身的往返成本(哪怕是本机回环地址,每次建立连接、发送请求头、等待响应头解析这些真实固定开销加起来也不可忽视)。_msearch真实把20次独立的网络往返压缩成了1次,这也是为什么它在真实网络延迟更高的生产环境(客户端和ES集群不在同一台机器)下收益会比本次本机测试更明显——每省下一次网络往返,真实省下的就是一整个RTT(往返时延)。
代码POST /_msearch {"index":"msr_test"} {"query":{"term":{"n":3}}} {"index":"msr_test"} {"query":{"range":{"n":{"gte":"not_a_number"}}}} ← 真实故意传了个非法的range边界值 {"index":"msr_test"} {"query":{"term":{"n":5}}}
responses数组按顺序对应3条查询: [0] OK hits=1 ← 真实第1条正常查询,结果正常返回 [1] ERROR: search_phase_execution_exception (all shards failed) ← 真实出错的那条 [2] OK hits=1 ← 真实第3条正常查询,完全没受第2条出错影响
每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
_msearch 批量查询 API