简介
在es中,每个索引都被划分为分片,每个分片都可以有多个副本。这些副本被叫做副本组,每次文档新增或者删除都需要进行同步,如果不同步的话,那么读一个副本返回的结果和读另一个副本返回的结果不一样。数据复制模型可以保持分片副本同步并为从中读取的数据提供服务。es的数据复制模型是基于主备模式的,改模式已经比较成熟了。该模型基于从副本组中复制一个副本,该副本充当主分片,其他副本称为副本分片,主节点是所有索引操作的主要入口点,它负责验证它们并确保它们是正确的,一旦索引操作被主分片接受,主分片还负责将该操作复制到其他副本。
写模式
Elasticsearch中的每个索引操作首先使用路由解析到一个复制组,通常基于文档ID。一旦确定了复制组,操作将在内部转发到组的当前主分片。主分片负责验证操作并将其转发到其他副本,因为副本可以脱机,主节点不需要复制到所有副本,相反,Elasticsearch维护一个应该接收操作的分片副本列表,这个列表称为同步副本,由主节点维护。这样保证有分片副本来接收用户的索引和删除操作。主分片负责把所有的操作复制到副本分片中。
主分片的流程:
1、验证传入操作,如果验证失败就直接报错,如需要数字的属性传了字符串。
2、在本地执行操作,如索引或删除相关文档,也还将验证字段的内容,并在需要时拒绝请求,如关键字值太长,无法在Lucene中建立索引。
3、将操作转发到当前同步复制集中的每个副本。如果有多个副本,则并行执行。
4、一旦所有副本都成功地执行了操作并响应了主分片,主分片就会向客户端确认请求成功完成。
错误处理
索引过程中可能出现许多错误——磁盘可能损坏,节点之间可能断开连接,或者一些配置错误可能导致在副本上的操作失败,尽管在主分片上操作成功。虽然这些情况不太常见,但是主分片还是要对这些情况作出回应的,在主节点本身失败的情况下,承载主节点的节点将向主节点发送关于它的消息。如果主节点挂了那么会重新选举一个节点作为主节点,在这个过程中所有的索引操作将等待(默认是等待1分钟),操作会转发到新的主节点上进行处理,注意,主节点还监视节点的健康状况,并可能决定主动降级主节点,这通常发生在持有主节点的节点因网络问题与集群隔离时。
一旦在主分片上成功执行了操作,主分片就必须处理在复制分片上执行操作时可能出现的故障。这可能是由于副本上的实际故障造成的,也可能是由于网络问题导致操作无法到达副本(阻止副本响应),如果出现上面的情况,那么副本将错过主分片传过来的信息,主分片会向集群分片发送消息把有问题的分片从同步副本集中踢出。只有集群同意移除该分片,那么主分片才会执行移除分片的操作。注意,主节点还将指示另一个节点开始构建一个新的分片副本,以便将系统恢复到正常状态。
主分片转发操作到副本集,同时也告诉副本集该主分片是活跃的分片。
如果主节点由于网络分区(或长时间GC)而被隔离,它可能会在意识到已降级之前继续处理传入索引操作。过了一会网络恢复了(或者gc完成)原来被降级的分片重新连上副本集,它是以主节点的身份来执行操作,但此时它会被副本集拒绝。当主分片收到来自副本的响应,拒绝了它的请求(因为它不再是主分片),那么主分片就会向副本集发出请求,并知道它已经被替换了,然后将操作路由到新的主分片。
没有副本会怎么样?
这种场景可能会出现,可能是由于索引配置,也可能只是因为所有副本都失败了。在这种情况下,主要是没有任何外部验证的处理操作,这可能会有问题,另一方面,主分片不能自己决定哪些分片失败,而是通过副本集来进行投票,这就意味着副本集只知道只有主分片是活着的。当然,由于此时我们只使用数据的单一副本运行,物理硬件问题可能会导致数据丢失。
读模式
Elasticsearch中的读取可以是非常轻量级的ID查找,也可以是非常繁重的搜索请求,其中包含复杂的聚合,占用大量CPU资源。主备模式的优点是保持所有副本数据都是相同的,这样一个简单的副本同步集就可以满足查询。当节点接收到读请求时,该节点负责将其转发给包含相关切分的节点、整理响应并响应客户端。我们将该节点称为请求的协调节点。基本流程如下:
1、解析读请求到相关分片,注意,由于大多数搜索将被发送到一个或多个索引,因此它们通常需要从多个分片中读取,每个分片表示数据的不同子集。
2、从分片复制组中选择每个相关分片的活动副本。这可以是主分片,也可以是副本。默认情况下,Elasticsearch只是在分配副本之间进行轮询调用。
3、将分片级别的读请求发送到所选副本。
4、合并结果并做出响应。注意,在get by ID查找的情况下,因为已经路由到具体某个分片了,所以可以跳过这一步。
分片故障
当分片无法响应读请求时,协调节点将请求发送到相同副本集中的另一个分片副本,重复失败可能导致没有可用的分片副本。为了确保快速响应,如果一个或多个分片失败,以下api将以部分结果响应:
Search
Multi Search
Bulk
Multi Get
包含部分结果的响应仍然提供一个200 OK HTTP状态码。分片故障由响应头的timed_out和_shards字段表示。
一些概念
这些基本流程中的每一个都决定了Elasticsearch作为读写系统的行为。
因为可以读和写可能同时进行,这两个基本流程相互影响,下面介绍下一些基本概念:
读取效率
在正常操作下,每个读操作为每个相关副本集执行一次。只有在出现故障的情况下,同一个分片的多个副本才会执行相同的搜索。
读未响应
由于主索引先本地索引,然后复制请求,在确认更改之前,并发读取可能已经看到更改。
默认为两份
这个模型可以容错,同时只维护两个数据副本。基于quorum的配置,其中容错的最小副本数为3。
故障
在失败的情况下,以下是可能的
单个分片可以降低索引速度
由于主分片在每次操作期间都要等待同步副本集中的所有副本,因此一个慢分片可能会减慢整个副本集的速度,这是我们为上面提到的读取效率所付出的代价,当然,一个单一的慢分片也会减慢已经被路由到它的搜索。
脏读取
一个独立的主节点可以公开不被承认的写。这是因为隔离的主分片只有在向其副本发送请求或向副本集发出请求时才会意识到它是隔离的。此时,操作已经被索引到主操作中,并且可以被并发读取。Elasticsearch每秒钟(默认情况下)ping一次主节点,如果不知道主节点,则拒绝索引操作,从而降低了这种风险。
注意:本文归作者所有,未经作者允许,不得转载