ElasticSearch - 分片路由

默认路由


有咩有想过,当写入一条新 document 的时候, 这条消息会被写到哪个 shard 呢 ?

默认的,es 会根据这个 document 的 id 作为 _routing 进行 hash 来选择 shard。

shard_num = hash(_routing) % num_primary_shards

自定义路由


自定义可以使用 routing 参数指定路由值。

POST twitter/_doc?routing=kimchy
{
"user" : "kimchy",
"post_date" : "2009-11-15T14:12:12",
"message" : "trying out Elasticsearch"
}

_routing mapping 可以被定义为 required,这样每个 index 请求都必须提供 routing 值。

index.routing_partition_size


按照上面的公式,只有 routing 一个值的话, 相同 routing hash 的 document 将会被写到一个 shard。那还能否写到多个 shard 呢 ?
答案是可以的。
es 有一个 routing partition 的概念,通过 index.routing_partition_size 设置,该值默认是 1,只能在创建 index 的时候设置。

此时, 分片选择的计算方法则变成了:

shard_num = (hash(_routing) + hash(_id) % routing_partition_size) % num_primary_shards

意思是,首先通过 routing 选取一个 partition,再通过 _id 选取这个 partition 中的 shard。
要启用这个特性,需要设置 index.routing_partition_size 大于 1 而且小于 index.number_of_shards

不过要注意当启用该特性时:

  1. join field 关系的 mappings 不能被创建。
  2. index 所有的 mappings 的 _routing 需要是 required

参考


_routing field | Elasticsearch Reference [6.2] | Elastic
index.routing_partition_size
Index API | Elasticsearch Reference