← 返回题目列表

Elasticsearch 的 routing 是什么?什么时候需要自定义 routing?

高频 中等 第 7 / 30 题 更新于 2026/07/29
ElasticsearchRouting分片查询优化

简化版

Routing 决定文档写入哪个主分片,默认根据 _id 哈希路由。自定义 routing 可以把同一租户、同一用户或同一业务键的数据放到固定分片,减少查询扇出;但也可能造成热点分片和数据倾斜。

详细版

ES 默认路由大致可理解为:

shard = hash(_routing) % number_of_primary_shards

默认 _routing 通常来自 _id。如果查询带 routing,ES 可以只查相关分片,而不是所有分片。例如多租户系统用 tenantId routing,可以让某租户查询只打到一个分片。面试要强调取舍:routing 能减少扇出,但 key 分布不均会导致热点;主分片数确定后也影响扩容和迁移。

完整版教学

一、routing 决定文档落在哪个主分片

一个索引有多个 primary shard。写入文档时,协调节点需要决定这条文档属于哪个分片。

默认情况下,ES 根据 routing 值做哈希取模。可以简化理解为:

target_shard = hash(_routing) % primary_shard_count

如果没有显式提供 routing,通常使用文档 _id 作为 routing。

记忆钩子:routing 是分片地址,不是查询过滤条件。

二、默认 routing 的好处是均匀

_id 哈希的好处是简单、通用,文档通常比较均匀地分散到多个主分片。

doc1 -> shard0
doc2 -> shard2
doc3 -> shard1
doc4 -> shard0

均匀分布能避免单个分片过热,也让写入和存储压力更平均。

但默认 routing 的缺点是:按业务键查询时,ES 不知道目标数据在哪个分片,可能需要查询所有分片。

三、自定义 routing 可以减少查询扇出

多租户系统中,很多查询都带 tenantId。如果写入时用 tenantId 作为 routing,查询时也带同样 routing,就能直接定位分片。

PUT /orders/_doc/1001?routing=tenant_8
{
  "tenantId": "tenant_8",
  "amount": 99
}

查询:

GET /orders/_search?routing=tenant_8
{
  "query": {
    "term": { "tenantId": "tenant_8" }
  }
}

如果索引有 12 个分片,不带 routing 可能查 12 个分片;带 routing 可能只查 1 个分片。延迟和资源消耗都会降低。

四、自定义 routing 最大风险是热点和倾斜

如果某个租户特别大,用 tenantId routing 会把该租户数据全部压到一个分片上。

routing key 分布结果风险
大量 key 均匀分片较均衡效果好
少数大 key某些分片巨大热点和倾斜
单一 key全部落一片基本失去分片意义

例如 1000 个小租户和 1 个超级租户,超级租户可能让某个分片磁盘、CPU、查询延迟都远高于其他分片。

解决方式包括大租户单独索引、routing key 加盐、按时间拆索引等。

五、routing 必须写查一致

自定义 routing 的一个坑是写入用了 routing,查询、更新、删除时忘记带相同 routing。

DELETE /orders/_doc/1001?routing=tenant_8

如果删除时不带 routing,ES 可能按 _id 默认路由去另一个分片找文档,结果找不到。查询如果不带 routing,虽然可能仍能搜到,但会退化成全分片搜索。

所以一旦使用自定义 routing,应用层要把 routing 当成文档定位协议的一部分。

六、routing 和主分片数规划有关

主分片数在索引创建后通常不能随意改变。routing 的哈希取模依赖主分片数量,所以早期规划很重要。

如果主分片太少,未来大 key 很容易打满;主分片太多,又会增加集群管理、查询扇出和小分片开销。

primary shard count = 6
routing key hash -> 0..5

自定义 routing 前要估算租户数、数据量分布、查询模式和未来增长。它是架构决策,不是单个查询参数。

七、常见误区与追问

  • 误区:routing 是用来过滤数据的。 routing 只是决定分片位置,真正过滤仍靠 query。
  • 误区:自定义 routing 一定提升性能。 key 分布不均会导致热点分片,性能可能更差。
  • 误区:写入带 routing,查询可以随便不带。 不带会增加分片扇出,更新删除还可能找不到目标文档。
  • 追问:多租户为什么适合 routing? 同租户查询集中,routing 能减少分片扇出。
  • 追问:大租户怎么避免热点? 大租户独立索引、routing 加盐、按时间拆分或重新规划索引。
  • 追问:routing 和主分片数有什么关系? routing 哈希映射到主分片,主分片数影响数据分布和未来扩展。

八、加强记忆

routing 记成“文档的分片地址”。默认按 _id 哈希,追求均匀;自定义 routing 用业务键减少查询扇出,适合多租户、用户维度查询。但 routing key 必须分布均匀,写查删要带同一个 routing,否则会热点、查全分片或找不到文档。