本节首先简要介绍Elasticsearch的数据复制模型,然后详细描述以下CRUD API:
Single document APIs
Index API
Get API
Delete API
Update API
Multi-document APIs
Multi Get API
Bulk API
Delete By Query API
Update By Query API
Reindex API
注意:所有CRUD API都是单索引API。 index参数接受单个索引名称或指向单个索引的别名。
读取和写入文档
介绍
Elasticsearch中的每个索引会分成多个分片,每个分片可以有多个副本。 这些副本被称为复制组(replication group),在添加或删除文档时必须保持同步。 否则会导致从不同的副本查询出来的结果不一致。 保持分片副本同步并提供读取操作的过程就是我们所说的数据复制模型(data replication model)。
Elasticsearch的数据复制模型基于primary-backup模型,在微软研究院的PacificA论文中有很好的描述。
该模型基于复制组的一个副本,该副本充当主分片(primary shard)。其他副本称为副本分片(replica shards)。主分片是所有索引操作的主要入口点,负责校验并确保操作是正确的。一旦索引操作被主分片接受,主分片也负责将操作复制到其他副本。
本节的目的是高度概述Elasticsearch复制模型,并讨论它对写入和读取操作之间各种交互的影响。
基本写入模型
Elasticsearch中的每个索引操作首先使用路由(通常基于文档ID)解析到对应的复制组。 一旦确定了复制组,该操作就会在内部转发到组的当前主分片。 主分片负责校验操作并将其转发给其他副本。 由于副本可能脱机,因此主分片不需要把该操作复制到所有副本。相反,Elasticsearch维护应该接收操作的分片副本列表。 该列表称为同步副本(in-sync copies),由主节点(master node)维护。 顾名思义,这是一组“好”的分片副本,保证已经处理了所有索引和删除操作。 主分片负责维护此不变量(前面说同步副本由master维护。这里又说由primary维护,困惑),因此必须将所有操作复制到此集合中的每个副本。
主分片遵循以下基本流程:
验证传入操作,拒绝结构无效的操作(例如:传入一个对象字段,但期望的是一个数字)
在本地执行操作,即索引或删除相关文档, 这也将验证字段的内容并在需要时拒绝(例如:关键字值在Lucene中索引太长)。
将操作转发到当前同步副本集中的每个副本。 如有多个副本,会并行完成。
一旦所有副本都成功执行操作并响应给了主分片,主分片就会确认已成功地完成了客户端的请求。
失败处理
索引期间很多事情都可能出错 --磁盘可能损坏,节点可能互相断开连接,或者某些配置错误可能导致某个副本上的操作失败,尽管它在主分片上成功了。 这些并不常见,但主分片还是要对它们做出回应。
主分片本身发生故障的时,主分片所在的节点将向master(主节点)发送一条消息。 该索引操作将等待(默认情况下最多1分钟),以便maser将其中一个副本提升为新的主分片。 该操作将被转发到新的主分片进行处理。 请注意,master还监视节点的运行状况,并可能决定主动降级主分片。比如网络问题,持有主分片的节点与集群隔离时,通常会发生这种情况。更多详情请看这里。
一旦在主分片(primary)上成功执行了操作,在副本分片(replica shards)上执行时,主分片(primary)还需处理潜在的失败,失败可能来源于:
- 在副本上执行失败了
- 由于网络问题副本未接收到操作(或副本的响应无法接收)。
所有执行失败的这些分片具有相同的结果:一个副本是同步复制集(in-sync replica set)的一部分,如果错过了即将被确认的操作。为了避免违反不变量,主分片会向主节点(master)发送一条消息,请求将有问题的碎片从同步复制集中删除。只有主节点(master)确认移除分片后,主分片(primary)才会确认操作。请注意,主节点(master)还会指示另一个节点开始构建新的分片副本,以便将系统恢复到健康状态。
在将操作转发给副本时,主分片将使用该副本来验证它是否仍然处于活动状态。如果主分片由于网络问题(或长时间的GC)而被隔离,它可能会继续处理传入的索引操作,然后才意识到自己已被降级。已降级的主分片接收的操作不会被副本承认。当它收到来自副本拒绝的响应后,那么它将与主节点(master)联系并知道它已被替换。然后该操作被路由到新的主分片。
假如没有副本会发生什么呢?
这是一个有效的场景,可能是由于索引配置,或者仅仅是因为所有的副本都失败了。在这种情况下,主分片处理操作,而不需要任何外部验证,这可能看起来有问题。
另一方面,主分片不能舍弃其他分片,但会请求主节点(master)代表它执行此操作。这意味着主节点(master)知道主分片是唯一的好的副本。我们会因此保证主节点(master)不会将任何其他(过时的)分片副本提升为一个新的主分片,并且任何索引到主分片的操作都不会丢失。当然,物理硬件问题可能导致数据丢失。请参阅 Wait For Active Shards 。
基本读模型
Elasticsearch中的读取操作可以通过ID进行非常轻量级的查找,也可以通过复杂的聚合进行重量级的搜索请求,这些请求会占用大量的CPU资源。主从复制(primary-backup)的一个优点是它可以保持所有分片副本一致(with the exception of in-flight operations)。因此,单个同步副本足以满足读取请求。
当某个节点收到读取请求时,该节点负责将其转发到相关分片的节点,整理响应并响应客户端。我们称该节点为该请求的协调节点(coordinating node)。基本流程如下:
解析读请求到相关的分片。注意,由于大多数搜索将被发送到一个或多个索引,它们通常需要从多个分片读取,每个分片表示不同的数据子集。
从分片复制组中选择每个相关分片的活动副本。这可以是主分片或副本。默认情况下,Elasticsearch只会在分片的副本间循环。
将分片级别的读请求发送到所选副本。
结合结果并做出回应。请注意,在通过ID查找的情况下,只有一个分片是相关的,该步骤可以被跳过。
失败处理
当分片无法响应读取请求时,协调节点将从同一复制组中选择另一个副本,并将分片级别搜索请求发送到该副本。 重复性故障可能导致没有可用的分片副本。 在某些情况下,比如_search,Elasticsearch会更倾向于快速响应,可能会只有部分结果,而不是等待问题得到解决(部分结果在响应的_shards头中)。
一些简单的含义
这些基本流程中的每一个都决定了Elasticsearch作为读写系统的行为。 此外,由于读取和写入请求可以同时执行,因此这两个基本流程相互作用。 这有几个内在的含义:
有效的读取
在正常操作下,每个相关复制组执行一次读取操作。 只有在失败情况下,同一个分片的多个副本才会执行相同的搜索。
读未确认
由于主分片首先在本地建立索引,然后复制请求,因此并发读取可能在未确认的情况下就被读取。
默认两个副本
该模型可以容错,同时只保留两个数据副本。 这与quorum-based 系统相反,该系统容错的最小副本数为3。
Failures
在失败的情况下,以下是可能的:
单个分片会减慢索引
由于主分片在每次操作期间都会等待设置同步副本中的所有副本,因此单个慢分片会减慢整个复制组的速度。 这是我们为上述读取效率付出的代价。 当然,一个缓慢的分片也会减慢已经发送给它的搜索。
脏读
一个孤立的主分片可以暴露不被确认的写入。 这是由于一个孤立的主分片只有在向其副本发送请求或向主节点(master)发送请求时才会将其隔离。 此时该操作已经被索引到主分片,并可以被并发读取。 Elasticsearch通过每秒(默认情况下)对主节点(master)执行ping操作,在没有发现主节点(master)存在的情况下拒绝索引操作来减轻风险。
冰山一角
本文档提供了Elasticsearch如何处理数据的高级概述。 当然,还有很多事情要做。 诸如primary terms, cluster state publishing 和 master election 等都在保持系统正常运行方面发挥了作用。 本文档也不涵盖已知和重要的错误(包括已关闭和打开)。 我们认识到GitHub很难跟上。 为了帮助人们保持最佳状态,在我们的网站上维护了专用的弹性页面。 强烈建议你阅读它。
官方文档:https://www.elastic.co/guide/en/elasticsearch/reference/current/docs-replication.html