ElasticSearch的文档路由
因为ElasticSearch是一个分布式系统,当将一个文档存储到ES上,该文档实际是被存储到某一个主分片中。
默认的分片路由
例如创建一个名字为blog,分片数=2,副本数=0的索引:
此时向其中存入一个文档:
PUT blog/_doc/a
{
"title":"a"
}
可以使用GET _cat/shards/blog?v
查看各分片中的数据:
(在只有一个文档的时候可以知道文档被存入了哪个分片)
此时再存入一个文档:
PUT blog/_doc/b
{
"title":"b"
}
此时再次执行GET _cat/shards/blog?v
(有时候反应较慢,需要等一会),可以发现两个分片中都有了数据:
ElasticSearch中默认的分配分片的规则(也就是默认的路由机制),是通过对文档的routing值(默认的routing值为文档的id)进行hash运算后模上分片的数量来得到当前文档的分片位置。
默认的路由方式可以达到负载均衡的目的,让数据尽量平均地分配在不同分片上。但是这也使得在进行查询的时候,无法确定文档的位置,而将请求广播到所有分片执行,并且使用默认的路由模式在修改分片的数量后,原有路由会不符合当前的规则(因为分片数发生了改变,模后的值也变化了)。
自定义routing值
开发者自定义routing值,也就是在创建以及查询、删除的url后带上routing=xx:
创建/更新:
PUT blog/_doc/c?routing=word
{
"title":"c"
}
查询:
如果继续使用GET blog/_doc/c
,会发现查询失败
必须使用GET blog/_doc/c?routing=word
,指定routing的值来查询
删除:
删除也同样必须带上routing的值:DELETE blog/_doc/c?routing=word
自定义路由的应用场景
比如在处理用户数据的时候,可以将用户的id作为routing,保证同一个用户的数据保存在同一个分片中,在检索的时候就可以使用id作为routing,从一个分片中获取全部的数据。