使用以下公式将文档路由到索引中的特定分片:
shard_num = hash(_routing) % num_primary_shards
用于 _routing 的默认值是文档的_id或文档的_parent ID(如果存在)。
可以通过为每个文档指定自定义路由值来实现自定义路由模式。 例如:
curl -XPUT 'localhost:9200/my_index/my_type/1?routing=user1&refresh=true&pretty' -H 'Content-Type: application/json' -d' # 1
{
"title": "This is a document"
}
'
curl -XGET 'localhost:9200/my_index/my_type/1?routing=user1&pretty' # 2
| 1 | 此文档使用 user1 作为其 routing value(路由值),而不是其 ID。 | | 2 | 在 getting(获取), deleting(删除)或 updating(更新)文档时需要提供相同的路由值。 |
该 _routing字段的值可以在查询中访问 :
curl -XGET 'localhost:9200/my_index/_search?pretty' -H 'Content-Type: application/json' -d' # 1
{
"query": {
"terms": {
"_routing": [ "user1" ]
}
}
}
'
| 1 | 在_routing字段上查询(也可以参见 ids query) |
自定义路由可以减少搜索的影响。 搜索请求不必分散到索引中的所有分片,而是将该请求发送到与特定路由值(或值)匹配的分片 :
curl -XGET 'localhost:9200/my_index/_search?routing=user1,user2&pretty' -H 'Content-Type: application/json' -d' # 1
{
"query": {
"match": {
"title": "document"
}
}
}
'
| 1 | 该搜索请求仅会在与user1和user2路由值相关联的分片上执行。 |
当使用自定义路由时,重要的是在 indexing(索引), getting(获取), deleting(删除)或 updating(更新)文档时提供路由值。
忘记路由值可能导致文档被索引在多个分片上。 作为保护措施,可以将 _routing 字段配置为使所有CRUD操作都需要指定路由值 :
curl -XPUT 'localhost:9200/my_index2?pretty' -H 'Content-Type: application/json' -d'
{
"mappings": {
"my_type": {
"_routing": {
"required": true # 1
}
}
}
}
'
curl -XPUT 'localhost:9200/my_index2/my_type/1?pretty' -H 'Content-Type: application/json' -d' # 2
{
"text": "No routing value provided"
}
'
| 1 | my_type 文档需要路由。 | | 2 | 此索引请求会引发一个 routing_missing_exception。 |
在索引指定自定义 _routing 的文档时,_id 的唯一性不能保证在索引中的所有分片。
事实上,如果使用不同的 _routing 值进行索引,那么具有相同 _id 的文档可能会在不同的分片上出现。
由用户确定 ID 在索引中是唯一的。
可以配置索引,使得自定义路由值将转到分片的子集,而不是单个分片。这有助于减轻最终产生不平衡群集的风险,同时还可以减少搜索的影响。
这是通过在索引创建时提供索引级别设置 _index.routing_partition_size _来完成的。随着分区大小的增加,数据的分布越均匀,必须以每个请求搜索更多的分片为代价。
当存在此设置时,计算分片的公式为:
shard_num = (hash(_routing) + hash(_id) % routing_partition_size) % num_primary_shards
也就是说,_routing 字段用于计算索引中的一组分片,然后使用 _id 来选择该组内的分片。
要启用此功能,index.routing_partition_size _应具有大于1且小于 index.number_of_shards _的值。
一旦启用,分区索引将具有以下限制 :