05. Document APIs(1)

data replication model

本节首先简要介绍Elasticsearch的data replication model,然后详细描述以下CRUD api:

读写文档(Reading and Writing documents)

介绍(Introduction)

在es中的每个索引都会被划分成一组分片,并且每个分片都有多个副本。这些副本是一组副本分片并且当删除或者添加文档的时候必须同步到各个副本。如果我们没有做到这点,从不同副本中读取的数据会不一致。我们把分片副本同步和使其能读取的过程,叫做data replication model.

es 数据分发模型基于primary-backup模型,并且在Microsoft Research 的PacificA paper中描述得非常好。这个模型从主分片获取副本。我们把非主分片的分片叫做副本分片。主分片是所有索引操作的入口。它负责验证索引操作是否有效。一旦主分片接受一个索引操作,主分片的副本分片也会接受该操作。

这章节的目的是,讲述 Elasticsearch replication model的高层概念和讨论读写操作之间隐含的多种交互。

基本的写模型(Basic write model)

每个索引操作首先会使用routing参数解析到replication group(分片组,包含主分片和副本分片),通常基于文档ID。一旦确定 replication group ,就会内部地转发该操作 到分片组的主分片中。主分片负责验证操作和转发它到其他副本分片。es维护一个可以接收该操作的分片副本列表(shard copies 包含主分片和副本分片)。这个列表叫做in-sync copies并由master节点维护。正如名字那样,担保这些分片都会处理所有的索引和删除操作,这些操作都会经过用户确认。主分片负责维护不变性(各个副本保持一致),因此必须副本这些操作到列表中的每个副本。

主分片的处理过程:

  1. 验证操作,如果它的结构有错就拒绝该操作(例如,对object字段指定一个数字值)
  2. 在本地执行操作。即索引或删除相关文档。这也会验证字段的内容,如果不通过就拒绝操作(例如,字段串的长度超出Lucene的定义的长度)
  3. 转发该操作到当前in-sync 副本组的所有副本分片。如果有多个副本分片,会并行转发。
  4. 一旦所有的副本分片成功执行该操作就会返回给主分片,主分片把请求的成功执行的信息返回给用户。

错误处理(Failure handling)

索引期间会发送很多错误,例如硬盘坏了,节点丢失和其他节点的连接,或者某些配置错误会导致不能在副本分片上执行某个操作,尽管该操作成功地在主分片上执行。虽然这是罕见的,但是主分片必须汇报这些错误信息。

对于主分片自身错误的情况,它所在的节点会发送一个消息到master节点。这个索引操作会等待(默认最多一分钟)master节点提升一个副本分片为主分片。这个操作会被转发给新的主分片处理。注意master同意会监控节点的健康,并且可能会主动降级主分片。这通常发生在主分片所在的节点和集群失去联系的时候。查看这里连接更多细节。

一旦操作在主分片执行成功,主分片必须处理可能在副本分片上发生的错误。错误发生的原因可能是,在副本分片上执行操作时发生的错误,也可能是因为网络阻塞导致主分片无法转发操作到副本分片,或者副本分片无法返回结果给主分片。这些错误都会导致相同的结果:in-sync replica set中的一个分片丢失一个即将要确认的操作。为了避免出现不一致,主分片会发送一条消息到master节点,要求它把有问题的分片从in-sync replica set中移除。 一旦master确认移除了该分片,主分片就会确认这次操作。注意master也会指导另一个节点建立一个新的分片副本,以便把系统恢复成健康状态。

当转发请求到副本分片,主分片会使用副本分片验证它是否仍是是一个活跃的主分片。如果主分片因为网络原因被孤立了,在它被降级之前,他会继续处理索引操作。来自陈旧的主分片的操作将会被副本分片拒绝。当主分片接收到来自副本分片的拒绝响应时主分片将不会再访问master,并且知道自己已经被取代了。这个操作会被路由到新的主分片。

如果没有副本分片会发生什么?

索引配置副本分片为0,或者所有的副本分片不可用的时候会发生这种情况。这时候在没有任何外部验证的情况下处理该操作,可能会导致问题。另一方面,主分片不能使它分片失效,但它会请求master使它们失效 。这意味着,master知道只有主分片才是一个可用的副本。因此我们担保master不会提升任何其他分片副本(过时)为主分片,并且主分片上的操作也不会丢失。

基本的读模型(Basic read model)

通过id查找是非常轻量的,一个复杂的查询并且需要进行聚合预算的请求需要消耗大量cpu资源。 primary-backup model 一个好处是保证所有的分片副本都是一致(正在执行的操作例外)。因此,单个 in-sync 副本也可以服务请求。

当一个读请求被节点接收,这个节点负责转发它到其他涉及相关分片的节点,并整理响应结果,发送给客户端。我们叫这个节点为这个请求的协调节点。基本流程如下:

  1. 把读请求发送到相关分片。注意,因为大多数搜索都会发送到一个或多个索引,通常需要从多个分片读取,每个分片都保存这数据的一部分。
  2. 从shard replication group选择一个相关分片的活跃副本。它可以是一个主分片或者副本分片。默认,es会简单地循环遍历这些分片。
  3. 发送一个分片level的读请求到被选中的副本
  4. 合并结果和响应客户端。注意对与通过id查找的get请求 ,会跳过这个步骤,因为这种请求只有一个相关的分片。

错误处理(Failure handling)

当分片不能响应一个读请求,协调节点会从replication group中选择另一个副本,并发送请求到该副本代替不可用的副本。没有可用的分片副本会导致重复的错误。某些情况下,es更喜欢尽早响应,即使只有部分的结果,而不是等待问题解决(你可以在响应结果的_shards字段,检查本次结果是完整的还是部分的)

一些简单的暗示(A few simple implications)

读和写的流程决定es行为。而且,因为读和写请求可以并发执行,这两个流程会相互交替。因此一些固有的暗示:

Efficient reads

正常情况每个读操作仅仅在每个相关的分片执行一次。仅仅在出现错误的情况下,需要对同一个分片的多个副本执行操作。

Read unacknowledged

因为索引操作首先在主分片执行,有可能在主分片还没确认的情况下,同时会发送一个读请求。

Two copies by default

当仅仅维护2个副本时,这个模型可以具备容错能力。这与基于法定数量的系统形成对比,其中容错的最小副本数为3。

错误(Failures)

A single shard can slow down indexing(某个分片可能会减慢整体索引的速度)

因为每次操作,主分片都会等待所有(in-sync copies)中的副本分片,如果其中有一个分片很慢,将会导致整个操作变慢。这是为了上述所说的一致性,需要付出的代价。当然,也会减慢搜索速度。

Dirty reads(脏读)

一个孤立的主分片能够暴露那些没有确认的写操作。因为仅仅当它发送请求到它的副本分片或者访问master的时候,才意识到它被孤立了。在这一刻,这个操作已经写到了主分片,并且同时可以被读取。es 通过每秒(默认)ping一次master降低这种错误,并且,如果联系不上master,会拒绝索引操作。

冰山一角(The Tip of the Iceberg)

本文档提供一个关于es如何处理数据的高层概念。当然,在底层还有很多很多细节。例如 primary terms,集群状态和master选举等都可以在保持系统正常运行方面发挥作用。本文档也未覆盖已知或重要的bug(包括关闭的和开启的)。我们认识到GitHub很难跟上。为了帮助人们掌控这些,我们在我们的网站上维护了一个专用的页面。我们强烈建议你阅读它。

猜你喜欢

转载自www.cnblogs.com/wtc1994/p/10703647.html