1. 路由文档到分片
当你索引一个文档,它被存储在单独一个主分片上。Elasticsearch是如何知道文档属于哪个分片的呢?当你创建一个新文 档,它是如何知道是应该存储在分片1还是分片2上的呢?
进程不能是随机的,因为我们将来要检索文档。事实上,它根据一个简单的算法决定:
所有的文档API( get 、 index 、 delete 、 bulk 、 update 、 mget )都接收一个 routing 参数,它用来自定义文档到分片的 映射。自定义路由值可以确保所有相关文档——例如属于同一个人的文档——被保存在同一分片上。
2. 主分片和复制分片如何交互
我们能够发送请求给集群中任意一个节点。每个节点都有能力处理任意请求。每个节点都知道任意文档所在的节点,所以也 可以将请求转发到需要的节点。下面的例子中,我们将发送所有请求给 Node 1 ,这个节点我们将会称之为请求节点 (requesting node)
当我们发送请求,最好的做法是循环通过所有节点请求,这样可以平衡负载。
3. 新建、索引和删除文档
新建、索引和删除请求都是写(write)操作,它们必须在主分片上成功完成才能复制到相关的复制分片上。
下面我们罗列在主分片和复制分片上成功新建、索引或删除一个文档必要的顺序步骤:
- 客户端给 Node 1 发送新建、索引或删除请求。
- 节点使用文档的 _id 确定文档属于分片0 。它转发请求到 Node3 ,分片 0 位于这个节点上。
- Node 3 在主分片上执行请求,如果成功,它转发请求到相应的位于 Node1 和 Node2 的复制节点上。当所有的复制节点 报告成功, Node3 报告成功到请求的节点,请求的节点再报告给客户端。
客户端接收到成功响应的时候,文档的修改已经被应用于主分片和所有的复制分片。你的修改生效了。
有很多可选的请求参数允许你更改这一过程。你可能想牺牲一些安全来提高性能。这一选项很少使用因为Elasticsearch已经 足够快,不过为了内容的完整我们将做一些阐述。
-
replication
复制默认的值是 sync 。这将导致主分片得到复制分片的成功响应后才返回。如果你设置 replication 为 async ,请求在主分片上被执行后就会返回给客户端。它依旧会转发请求给复制节点,但你将不 知道复制节点成功与否。
上面的这个选项不建议使用。默认的 sync 复制允许Elasticsearch强制反馈传输。 async 复制可能会因为在不等待其它分片就 绪的情况下发送过多的请求而使Elasticsearch过载。
-
consistency
默认主分片在尝试写入时需要规定数量(quorum)或过半的分片(可以是主节点或复制节点)可用。这是防止数据被写入到错 的网络分区。规定的数量计算公式如下:
consistency 允许的值为 one (只有一个主分片), all (所有主分片和复制分片)或者默认的 quorum 或过半分片。注意 number_of_replicas 是在索引中的的设置,用来定义复制分片的数量,而不是现在活动的复制节点的数量。
-
timeout
当分片副本不足时会怎样?Elasticsearch会等待更多的分片出现。默认等待一分钟。如果需要,你可以设置 timeout 参数让 它终止的更早: 100 表示100毫秒, 30s 表示30秒。
注意:
新索引默认有 1 个复制分片,这意味着为了满足 quorum 的要求需要两个活动的分片。当然,这个默认设置将阻止我们 在单一节点集群中进行操作。为了避开这个问题,规定数量只有在 number_of_replicas 大于一时才生效。
4. 检索文档
文档能够从主分片或任意一个复制分片被检索。
下面我们罗列在主分片或复制分片上检索一个文档必要的顺序步骤:
- 客户端给 Node1 发送get请求。
- 节点使用文档的 _id 确定文档属于分片0 。分片 0 对应的复制分片在三个节点上都有。此时,它转发请求到 Node2
- Node2 返回endangered给 Node1 然后返回给客户端。
对于读请求,为了平衡负载,请求节点会为每个请求选择不同的分片——它会循环所有分片副本。
可能的情况是,一个被索引的文档已经存在于主分片上却还没来得及同步到复制分片上。这时复制分片会报告文档未找到, 主分片会成功返回文档。一旦索引请求成功返回给用户,文档则在主分片和复制分片都是可用的。
5. 局部更新文档
下面我们罗列执行局部更新必要的顺序步骤:
- 客户端给 Node1 发送更新请求。
- 它转发请求到主分片所在节点 Node3 。
- Node3 从主分片检索出文档,修改 _source字段的JSON,然后在主分片上重建索引。如果有其他进程修改了文档,它以 retry_on_conflict 设置的次数重复步骤3,都未成功则放弃。
- 如果 Node3 成功更新文档,它同时转发文档的新版本到Node1 和Node2上的复制节点以重建索引。当所有复制节点报 告成功,Node3 返回成功给请求节点,然后返回给客户端。
update API还接受上一篇提到的 routingreplication
consistency 和 timout 参数。
基于文档的复制
当主分片转发更改给复制分片时,并不是转发更新请求,而是转发整个文档的新版本。记住这些修改转发到复制节点 是异步的,它们并不能保证到达的顺序与发送相同。如果Elasticsearch转发的仅仅是修改请求,修改的顺序可能是错 误的,那得到的就是个损坏的文档。
6. 多文档模式
mget 和 bulk API与单独的文档类似。差别是请求节点知道每个文档所在的分片。它把多文档请求拆成每个分片的对文档请 求,然后转发每个参与的节点。
一旦接收到每个节点的应答,然后整理这些响应组合为一个单独的响应,最后返回给客户端。
下面我们将罗列通过一个 mget 请求检索多个文档的顺序步骤:
- 客户端向 Node1发送mget请求。
- Node1为每个分片构建一个多条数据检索请求,然后转发到这些请求所需的主分片或复制分片上。当所有回复被接 收,Node1构建响应并返回给客户端。
routing 参数可以被docs中的每个文档设置。
下面我们将罗列使用一个 bulk 执行多个 create 、 index 、 delete 和 update 请求的顺序步骤:
- 客户端向Node1发送bulk 请求。
- Node1为每个分片构建批量请求,然后转发到这些请求所需的主分片上。
- 主分片一个接一个的按序执行操作。当一个操作执行完,主分片转发新文档(或者删除部分)给对应的复制节点,然后 执行下一个操作。复制节点为报告所有操作完成,节点报告给请求节点,请求节点整理响应并返回给客户端。
bulk API还可以在最上层使用 replication 和 consistency 参数, routing 参数则在每个请求的元数据中使用。
摘自:es权威指南