elasticsearch一些原理
shard = hash(routing) % number_of_primary_shards
routing
是一个可变值,默认是文档的 _id
,也可以设置成一个自定义的值。 routing
通过 hash 函数生成一个数字,然后这个数字再除以 number_of_primary_shards
(主分片的数量)后得到 余数 。这个分布在 0
到 number_of_primary_shards-1
之间的余数,就是我们所寻求的文档所在分片的位置。PS:之前看其他的文档,说id是随机字符串,当时就怀疑~~ 自动生成的 ID 是 URL-safe、 基于 Base64 编码且长度为20个字符的 GUID 字符串。 这些 GUID 字符串由可修改的 FlakeID 模式生成,这种模式允许多个节点并行生成唯一 ID ,且互相之间的冲突概率几乎为零。
所有的文档 API( get
、 index
、 delete
、 bulk
、 update
以及 mget
)都接受一个叫做 routing
的路由参数 ,通过这个参数我们可以自定义文档到分片的映射。
主分片与副分片如何交互
我们可以发送请求到集群中的任一节点。 每个节点都有能力处理任意请求。 每个节点都知道集群中任一文档位置,所以可以直接将请求转发到需要的节点上。
当发送请求的时候, 为了扩展负载,更好的做法是轮询集群中所有的节点。
新建、索引和删除文档
新建、索引和删除 请求都是 写 操作, 必须在主分片上面完成之后才能被复制到相关的副本分片
以下是在主副分片和任何副本分片上面 成功新建,索引和删除文档所需要的步骤顺序:
- 客户端向
Node 1
发送新建、索引或者删除请求。 - 节点使用文档的
_id
确定文档属于分片 0 。请求会被转发到Node 3`,因为分片 0 的主分片目前被分配在 `Node 3
上。 -
Node 3
在主分片上面执行请求。如果成功了,它将请求并行转发到Node 1
和Node 2
的副本分片上。一旦所有的副本分片都报告成功,Node 3
将向协调节点报告成功,协调节点向客户端报告成功。
在客户端收到成功响应时,文档变更已经在主分片和所有副本分片执行完成,变更是安全的。
取回一个文档
以下是从主分片或者副本分片检索文档的步骤顺序:
1、客户端向 Node 1
发送获取请求。
2、节点使用文档的 _id
来确定文档属于分片 0
。分片 0
的副本分片存在于所有的三个节点上。 在这种情况下,它将请求转发到 Node 2
。
3、Node 2
将文档返回给 Node 1
,然后将文档返回给客户端。
在处理读取请求时,协调结点在每次请求的时候都会通过轮询所有的副本分片来达到负载均衡。
在文档被检索时,已经被索引的文档可能已经存在于主分片上但是还没有复制到副本分片。 在这种情况下,副本分片可能会报告文档不存在,但是主分片可能成功返回文档。 一旦索引请求成功返回给用户,文档在主分片和副本分片都是可用的。
局部更新文档
- 客户端向
Node 1
发送更新请求。 - 它将请求转发到主分片所在的
Node 3
。 -
Node 3
从主分片检索文档,修改_source
字段中的 JSON ,并且尝试重新索引主分片的文档。 如果文档已经被另一个进程修改,它会重试步骤 3 ,超过retry_on_conflict
次后放弃。 - 如果
Node 3
成功地更新文档,它将新版本的文档并行转发到Node 1
和Node 2
上的副本分片,重新建立索引。 一旦所有副本分片都返回成功,Node 3
向协调节点也返回成功,协调节点向客户端返回成功。
多文档模式
- 客户端向
Node 1
发送mget
请求。 -
Node 1
为每个分片构建多文档获取请求,然后并行转发这些请求到托管在每个所需的主分片或者副本分片的节点上。一旦收到所有答复,Node 1
构建响应并将其返回给客户端。
使用 bulk
修改多个文档
bulk
API 按如下步骤顺序执行:
- 客户端向
Node 1
发送bulk
请求。 -
Node 1
为每个节点创建一个批量请求,并将这些请求并行转发到每个包含主分片的节点主机。 - 主分片一个接一个按顺序执行每个操作。当每个操作成功时,主分片并行转发新文档(或删除)到副本分片,然后执行下一个操作。 一旦所有的副本分片报告所有操作成功,该节点将向协调节点报告成功,协调节点将这些响应收集整理并返回给客户端。
bulk
API 还可以在整个批量请求的最顶层使用 consistency
参数,以及在每个请求中的元数据中使用 routing
参数。