You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Elasticsearch路由功能异常:官方示例下错误路由仍返回文档

Elasticsearch路由设置不符合预期问题

我创建了包含2个分片且设置路由为必填的索引:

PUT my-index-000001
{
  "settings":
  {
    "index.number_of_shards": 2
  },
  "mappings": {
    "_routing": {
      "required": true 
    }
  }
}

按照官方文档示例执行索引和查询操作:

PUT my-index-000001/_doc/1?routing=user1&refresh=true 
{
  "title": "This is a document"
}

GET my-index-000001/_doc/1?routing=user1 

上述操作正常,但将路由值改为user2时,仍能获取到该文档,这不符合预期——文档是通过user1路由索引到对应分片的,使用不同路由不应返回该文档:

GET my-index-000001/_doc/1?routing=user2

Result:
{
  "_index": "my-index-000001",
  "_id": "1",
  "_version": 1,
  "_seq_no": 0,
  "_primary_term": 1,
  "_routing": "user1",
  "found": true,
  "_source": {
    "title": "This is a document"
  }
}

搜索操作也存在同样问题(预期user2路由下不会出现该文档):

GET my-index-000001/_search?routing=user2
{
  "query":
  {
    "match_all": {}
  }
}

Result:
{
  "took": 0,
  "timed_out": false,
  "_shards": {
    "total": 1,
    "successful": 1,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": "my-index-000001",
        "_id": "1",
        "_score": 1,
        "_routing": "user1",
        "_source": {
          "title": "This is a document"
        }
      }
    ]
  }
}

请问我哪里操作有误?


问题原因

这是因为**user1和user2经过哈希计算后命中了同一个分片**。Elasticsearch的路由机制是对路由值做哈希,再对分片数取模来确定目标分片。当两个不同路由值的哈希取模结果相同时,就会指向同一个分片,此时用user2路由查询也能找到该分片上的user1路由文档。

验证方法

你可以用以下代码模拟Elasticsearch的路由哈希逻辑,验证两个路由值是否命中同一分片:

import hashlib

def get_shard_id(routing_value, num_shards):
    hash_val = hashlib.md5(routing_value.encode()).hexdigest()
    return int(hash_val, 16) % num_shards

print(get_shard_id("user1", 2))
print(get_shard_id("user2", 2))

如果两者输出结果一致,就说明它们指向同一个分片。

解决办法

  1. 增加分片数量:更多分片能降低不同路由值命中同一分片的概率,但分片数量不宜过多,会增加集群运维开销。
  2. 查询时过滤路由字段:在搜索请求中显式过滤_routing字段,确保只返回对应路由的文档:
GET my-index-000001/_search?routing=user2
{
  "query": {
    "bool": {
      "must": [
        {"match_all": {}},
        {"term": {"_routing": "user2"}}
      ]
    }
  }
}

这样即使路由命中同一分片,也会过滤掉不属于当前路由的文档。
3. 自定义路由映射规则:如果业务需要严格的路由隔离,可以在客户端层面自定义路由到分片的映射逻辑,确保不同路由值对应不同分片。

内容的提问来源于stack exchange,提问作者user18154574

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 22:00:23