ElasticSearch[3]-分布式中CRUD机制
分片路由
ES通过hash取模的算法来分配索引或创建一个文档该如何存储在哪一个分片中。
shard = hash(routing) % number_of_primary_shards
routing 值是一个任意字符串,它默认是 _id 但也可以自定义。routing 字符串通过哈希函数生成一个数字,然后除以主切片的数量得到一个余数(remainder),余数的范围永远是 0 到 number_of_primary_shards - 1 ,这个数字就是特定文档所在的分片。
这也是为什么之前所说的 主分片在的数量只能在索引创建时定义且不可修改。如果修改了那么所有的路由值将失效,文档讲无法找到。除非重构索引。
主分片与复制分片的交互
假设有以下三个node的集群模式:
请求可以发送到集群中的任意一个node上,每个node都有处理请求的能力,并且每个node都知道任意文档所在的node,所以也可以将请求转发到对应的node。
所以,基于以上的能力,可以把请求循环或者其他负载均衡的方式平均发送到所有的节点上。以实现负载。
CRUD文档
写操作(新增、修改、删除)必须在主分片上完成才能同步到相关的复制分片上。
- 客户端请求发送到node1
- node1 根据 _id确定文档属于shard0,转发请求到node3
- node3处理请求后转发到node1和node2上的复制分片,当所有复制分片报告成功,node3报告成功给node1(请求接受节点),node1报告给客户端
有很多可选的请求参数允许你更改这一过程:
- replication
默认replication=sync,即复制完成后才返回客户端报告,也可以修改为 async 这时客户端是无法确认是否完成复制的 - consistency
默认主分片在尝试写入时需要规定数量(quorum)或过半的分片(可以是主节点或复制节点)可用。这是防止数据被写入到错的网络分区。
int((primary + number_of_replicas) / 2) + 1
consistency 允许的值为 one (只有一个主分片), all (所有主分片和复制分片)或者默认的 quorum 或过半分片。 - timeout
检索文档
文档能够从主分片或任意一个复制分片被检索。
- 客户端给 node1 发送get请求。
- 节点使用文档的 _id 确定文档属于分片0 。分片0 对应的复制分片在三个节点上都有。此时,它转发请求到 node2 。
- node2 返回文档(document)给 node1 然后返回给客户端。
为了负载均衡,接受请求的node依然会循环把请求转发到其他分片上(即便当前节点已经存在该文档的分片)。
如果请求在复制分片中未查到文档,则会再转发到主分片所在的节点进行查询。这样就避免了出现所要查询的数据在主分片尚未来得及复制到复制分片而导致的一致性问题。