本文转载自:https://www.elastic.co/guide/cn/elasticsearch/guide/current/index.html,ES版本号6.3.0
局部更新文档
update API 结合了之前提到的读和写的模式。
下面我们罗列执行局部更新必要的顺序步骤:
- 1.客户端给Node1发送更新请求
- 2.它转发请求到主分片所在节点Node3
- 3.Node3从主分片检索出文档,修改_source字段JSON,然后在主分片上重建索引。如果有其他进程修改了文档,他将按照retry_on_conflict设置的次数重复步骤3,都为成功则放弃
- 4.如果Node3成功更新文档,他同时转发文档的新版本到Node1和Node2上的复制节点以重建索引。当所有复制节点报告成功,Node3返回成功给请求节点,然后返回给客户端。
update API还接受《ElasticSearch学习之路-day09》章节提到的routing、replication、consistency和timeout参数。
note:基于文档的复制
当主分片转发更改给复制分片时,并不是转发更新请求,而是转发整个文档的新版本。记住这些修改转发到复制节点是异步的,它们并不能保证到达的顺序与发送相同。如果Elasticsearch转发的仅仅是修改请求,修改的顺序可能是错误的,那得到的就是个损坏的文档
多文档模式
mget和bulk API与单独的文档类似。差别是请求节点知道每个文档所在的分片。它把多文档请求拆成每个分片的对文档请求,然后转发每个参与的节点。
一旦接收到每个节点的应答,然后整理这些响应组合为一个单独的响应,最后返回给客户端
下面我们将罗列通过一个mget请求检索多个文档的顺序步骤
- 1.客户端向Node1发送mget请求
- 2.Node1位每个分片构建一个或者多条数据检索请求,然后转发到这些请求所需的主分片或者复制分片上。
- 3.当所有回复被接收,Node1构建响应并返回给客户端
routing参数可以被docs中的每个文档设置
下面我们将罗列使用一个bulk执行多个create、index、delete和update请求的顺序步骤:
- 1.客户端向Node1发送bulk请求
- 2.Node1为每个分片构建批量请求,然后转发到这些请求所需的分片上。
- 3.主分片一个接一个有序的执行操作。当一个操作执行完,主分片转发新文档(或删除部分)给对应的复制节点,然后执行下一个操作。一旦所有复制节点报告所有操作已成功完成,节点就报告success给请求节点后者整理响应并返回给客户端
bulk API还可以在最上层使用replication和consistency参数,routing参数则在每个请求的元数据中使用。
为什么是奇怪的格式?
当我们在《批量》一章中学习了批量请求之后,你可能会问:“为什么bulkAPI需要带换行符的奇怪格式,而不是像mget API一样使用JSON数组?”
为了回答这个问题,我们需要简单的介绍一下背景
批量中每个引用的文档属于不同的主分片,每个分片可能被分布于集群中的某个节点上。这意味着批量中的每个操作(action)需要被转发到对应的分片和节点上。
如果每个单独的请求被包装到JSON数组中,那意味着我们需要:
1.解析JSON为数组(包括文档数据,可能非常大)
2.检查每个请求决定应该到那个分片上
3.为每个分片创建一个请求的数组
4.序列化这些数组为内部传输格式
5.发送请求到每个分片上
这可行,但需要大量的RAM来承载本质上相同的数据,还要创建更多的数据结构使得JVM花更多的时间执行垃圾回收。
取而代之的,Elasticsearch则是从网络缓冲区中一行一行的直接读取数据。它使用换行符识别和解析action/metadata行,以决定哪些分片来处理这个请求。
这些行请求直接转发到对应的分片上。这些没有冗余复制,没有多余的数据结构。整个请求过程使用最小的内存在进行。