Elasticsearch 6.8.23集群分页查询结果不一致及Segment疑问
Elasticsearch集群问题排查
集群环境
我部署了一个包含2个节点、1个主分片(primary shard)和1个副本分片(replica shard)的Elasticsearch(版本6.8.23)集群,初始导入约1500条记录,集群健康状态为Green。
分片信息(执行POST /_cat/shards/<index-name>?v)
index shard prirep state docs store ip node index-6 0 p STARTED 1546 6.5mb ***.***.**.1 node-1 index-6 0 r STARTED 1546 6.5mb ***.***.**.2 node-2
段信息(执行POST /_cat/segments/<index-name>?v)
index shard prirep ip segment generation docs.count docs.deleted size size.memory committed searchable version compound index-6 0 p ***.***.**.1 _4 4 154 4 1.9mb 8372 true true 7.7.3 true index-6 0 p ***.***.**.1 _b 11 1303 78 3.5mb 38020 true true 7.7.3 false index-6 0 p ***.***.**.1 _c 12 82 0 661.7kb 10525 true true 7.7.3 true index-6 0 p ***.***.**.1 _d 13 6 0 367.4kb 4359 true true 7.7.3 true index-6 0 p ***.***.**.1 _e 14 1 0 4.3kb 1635 true true 7.7.3 true index-6 0 r ***.***.**.2 _6 6 173 7 2mb 8357 true true 7.7.3 true index-6 0 r ***.***.**.2 _b 11 26 1 48.1kb 7229 true true 7.7.3 true index-6 0 r ***.***.**.2 _c 12 994 67 2.8mb 30852 true true 7.7.3 false index-6 0 r ***.***.**.2 _d 13 264 7 565.7kb 7866 true true 7.7.3 true index-6 0 r ***.***.**.2 _e 14 82 0 661.7kb 10525 true true 7.7.3 true index-6 0 r ***.***.**.2 _f 15 6 0 367.4kb 4359 true true 7.7.3 true index-6 0 r ***.***.**.2 _g 16 1 0 4.3kb 1635 true true 7.7.3 true
注:部分segment的
compound字段值为false。
问题描述
多次执行POST /index-6/_search?from=0&size=10查询时,返回的结果集不一致,似乎来自不同节点或分片。现咨询以下两个技术问题:
- 为何分页查询会出现结果不一致的情况?
- 为何部分segment的compound字段值为false?
问题解答
1. 分页查询结果不一致的原因
- 请求路由策略:Elasticsearch默认采用轮询(round-robin)方式将查询请求分发到主分片和副本分片。你的集群有1个主分片和1个副本分片,每次查询可能被分配到node-1的主分片,或者node-2的副本分片。
- 无明确排序规则:默认情况下,查询未指定排序字段时,Elasticsearch会按文档在分片内的存储顺序(
_doc顺序)返回结果。主分片和副本分片的文档存储顺序可能因段合并、写入时序差异等原因不一致,导致相同分页参数返回不同结果。
解决方法:
- 添加明确的排序字段,比如基于业务唯一字段或
_id排序,确保不同分片返回的结果顺序统一; - 若不需要负载均衡,可在查询时指定
preference=primary强制从主分片查询,或设置固定的preference值(如用户ID),让同一用户的查询始终路由到同一分片。
2. 部分segment的compound字段为false的原因
Compound segment(复合段)是将段的所有数据文件(倒排索引、存储字段等)合并为单一文件,适合小体积段;非复合段(compound=false)则将不同类型的数据拆分到独立文件中,大段查询时性能更优。
Elasticsearch会自动根据段的大小和合并策略决定是否使用复合格式:
- 当段大小超过阈值(6.8版本默认
index.merge.policy.compound_size为10MB)时,合并后的段会以非复合形式存储; - 后台段合并操作(多个小片段合并为大段)会自动生成非复合段,因为拆分文件后,查询时可仅加载所需数据,提升查询效率。
你看到的compound=false的段均为体积相对较大的段,这是Elasticsearch的自动优化行为,属于正常现象,无需手动干预。
内容的提问来源于stack exchange,提问作者Lovepreet Singh
相关产品推荐
相关产品推荐

