文档路由到分片
当新建一个文档时,会存储在主分片,而对于存储在哪一个主分片的选择不是随机。
分配依据如下算法:
shard = hash(routing) % number_of_primary_shards
routing为默认_id或者自定义。
shard值范围在0~number_of_primary_shards之间。
因此,主分片的数量在创建索引时就指定且不能修改,否则修改后,之前存储的分片文档会丢失。
对于常用的api(get 、 index 、 delete 、 bulk 、 update 、 mget)
都会接收routing值,用于寻找文档到索引的映射。
主分片和复制分片的通信
相同的分片不会放在一个节点上,每个节点都有能力处理任意请求,都知道任意文档的存储位置,所以请求也可以被转发到需要文档的节点。
当然为了负载均衡,请求最好是循环通过所有节点。
主分片和复制分片的文档操作
对于文档的写操作如(新建,索引,删除)必须在主分片上完成,然后才复制到相关的分片。
执行顺序:
- 客户端向NODE1发送请求
- NODE1根据_id确定文档属于哪个分片。然后转发
- 请求转发到NODE3,处理完成后转发请求到NODE1和NODE2这两个复制节点,当所有节点都处理完成并报告,由NODE3报告成功到请求节点NODE1,再由NODE1通知客户端。
请求参数设置
参数 | 默认值 | 描述 |
---|---|---|
replication | sync | sync表示主分片等复制分片响应后才返回,async朱分片执行后即返回 |
consistency | int( (primary + number_of_replicas) / 2 ) + 1 | 默认主分片在尝试写入时需要规定数量或过半的分片 |
timeout | 1分钟 | 分片副本不足时等待副本的时间 |
检索文档
文档能够从主分片或任意一个复制分片被检索
- 客户端给 Node 1 发送get请求。
- 节点使用文档的 _id 确定文档属于分片 0 。分片 0 对应的复制分片在三个节点上都
有。此时,它转发请求到 Node 2 。 - Node 2 返回endangered给 Node 1 然后返回给客户端。
局部更新文档
- 客户端给 Node 1 发送更新请求。
- 它转发请求到主分片所在节点 Node 3 。
- Node 3 从主分片检索出文档,修改 _source 字段的JSON,然后在主分片上重建索引。
如果有其他进程修改了文档,它以 retry_on_conflict 设置的次数重复步骤3,都未成功
则放弃。 - 如果 Node 3 成功更新文档,它同时转发文档的新版本到 Node 1 和 Node 2 上的复制节点
以重建索引。当所有复制节点报告成功, Node 3 返回成功给请求节点,然后返回给客户
端。
当主分片转发更改给复制分片时,并不是转发更新请求,而是转发整个文档的新版本。
记住这些修改转发到复制节点是异步的,它们并不能保证到达的顺序与发送相同。如果
Elasticsearch转发的仅仅是修改请求,修改的顺序可能是错误的,那得到的就是个损坏
的文档。
批量操作
如果是批量操作,请求节点知道每个文档所在的分片。它把多文档请求拆成每个分片的对文档请求,然后转发每个参与的节点。
- 客户端向 Node 1 发送 mget 请求。
- Node 1 为每个分片构建一个多条数据检索请求,然后转发到这些请求所需的主分片或复
制分片上。当所有回复被接收, Node 1 构建响应并返回给客户端。