ES读写索引内幕分析

一.简介

  ES中的索引都进行分片,每个分片都会保存多个副本。这些副本称为复制组,在添加或删除索引时必须同步副本。如果不这样,从不同的副本中读取的索引可能截然不同。保持分片副本同步并从中提供读取的过程被称为数据复制模型

  ES的数据复制模型基于主备份模型。该模型基于单一复制的副本组,该模型对应的分片充当主分片【primary shard】。其它副本称为备份分片【replica shards】。主分片作为全部索引操作的主入口,它负责验证副本并确保副本的正确性。当主分片接受到一个索引操作请求时,它还负责将操作复制到其它副本。

二.写模型

  ES中的每个索引操作首先使用路由解析为复制组,通常基于索引id。确定复制组后,操作将在内部转发到组的当前主分片。主分片负责验证操作并将其转发到其它副本。由于副本可以脱机,因此不需要将主副本复制到所有副本。相反,ES维护应该接受操作的分片副本列表。此列表称为同步副本,由主节点维护。顾名思义,这些维护好的分片副本的集合,保证已经处理了所有向用户确认的索引操作。主副本负责维护此不变量,因此必须将所有操作复制到此集合中的每个副本上。

  主分片遵守以下基本流程:

    1.验证传入操作并在结构无效时拒绝执行【例如:在数字字段中传入对象】。

    2.在本地执行索引操作,即添加索引或修改索引时,也将验证字段的内容并在需要的时候拒绝执行【例如:关键字值太长,无法在ES中创建索引】。

    3.将操作转发到当前同步副本集中的每个副本。如果有多个副本,则并行执行同步。

    4.一旦所有副本成功同步并响应主服务器,主服务器就会确认成功完成对客户端的请求。

三.失败处理

  ES在索引创建过程中可能会出现一些问题,磁盘可能会损坏,节点可能会断开连接,或者某些配置错误导致复制副本出错,尽管它在服务器上是成功的。这些情况并不多见,但主分片必须做出响应。在主分片本身发生故障的情况下,托管主分片的服务器节点会向主服务器发送相关信息。索引操作将进入等待状态【默认情况下最多等待1分钟】,以便主服务器将其中一个副本提升为新的主分片。然后,索引相关操作将被转发到新的主分片上进行处理。请注意,主服务器还会监控节点的运行状况,并可能决定主动降级主分片。当因网络问题导致拥有主分片的节点断开集群连接时,通常会这样操作。

  一旦在主服务器上成功执行了索引操作,主服务器就必须处理在副本分片上执行索引操作时它可能出现的故障。这可能是由副本上的实际故障或者网络问题导致索引操作无法到达副本【或者阻止副本响应】引起的。所有这些都会具有相同的最终结果:作为同步副本集的一部分的副本错过了即将被确认的索引操作。为了避免违反副本一致性,主分片向主服务器发送消息,请求从副本集中删除有问题的分片。只有在主节点确认删除了这些分片之后,主分片才会确认操作。此外,主服务器还将指示另一个节点复制新的副本分片,以确保副本维持在一个相对合理的数量。

  在将操作转发到副本时,主分片将使用副本来验证它仍然是活动的主分片。如果因网络分区【或者长时间GC】而被隔离,则它可能会在意识到它已被降级之前继续处理传入的索引操作。复制分片将拒绝来自旧主分片的操作。当主分片收到来自副本的拒绝其请求的的响应时,因它不再是主分片,那么它将联系主服务器并将知道自己已被降级。然后它将索引操作路由到新的主分片服务器上。

  当没有副本时,这可能是由于索引配置或仅因为所有副本都已经失败导致的。在这种情况下,主分片处理操作而没有任何外部验证,这看起来有问题。另一方面,主分片本身不能使其它分片失败,除非请求主服务器代表它执行此操作。这意味着主节点知道主分片是唯一的正确副本。因此,我们保证主节点不会将任何其它【过时的】分片副本提升为新的主分片,并且任何索引到主分片的操作都不会丢失。当然,由于此时我们只使用单个数据副本运行,因此物理硬件问题可能导致数据丢失。

四.读模型

  ES中的读取可以是ID非常轻量级的查找,也可以是具有复杂聚合的大量搜索请求,这些聚合会占用非常多的CPU。主备份模型的优点之一是他使所有分片副本保持一致【还未完成的操作除外】。因此,单个同步副本足以提供读取请求。

  当节点收到读取请求时,该节点负责将其转发到保存相关分片的节点上,整理响应并反馈给客户端。我们将该节点称为该请求的协调节点【coordinating node】。基本流程如下:

  1.将读取请求解析为相关分片。请注意,由于大多数搜索将被发送到一个或多个索引,因此它们通常需要从多个分片中读取,每个分片代表数据的不同子集。

  2.从分片复制组中选择每个相关分片的活动副本。这可以是主副本或副本。默认情况下,ES将简单的在分片副本之间循环。

  3.将分片级读取请求发送到所选的副本上。

  4.结合结果并作出回应。请注意,在通过ID查找的情况下,只有一个分片是相关的,此时可以跳出这个流程,直接发送到指定的分片!

五.失败处理

  当分片无法响应读取请求时,协调节点将从同一复制组中选择另一个副本,并将分片级别的搜索请求发送到该副本。重复失败可能导致没有可用的分片副本。在某些情况下,例如:search,ES更愿意快速响应,经管只有部分结果,而不是等获取到全部结果之后才做出反馈。

六.特点

  1.高效读取

    在正常操作下,对每个相关复制组只执行一次读取操作。只有在操作失败的情况下,同一个分片的多个副本才会执行相同的搜索。

  2.读取未确认

    由于主分片在本地然后复制请求发送到其它分片,因此并发读取可能在确认之前就已经看到了更新。

  3.默认2份副本

    此模型可以容错,同时只保留两份副本。这与基于法定数量的系统形成鲜明的对比,其中容错的最小副本数为3。

  4.故障

    4.1 单分片可以降低索引速度,由于主服务器在每个操作期间等待同步副本集中的所有副本,因此单个慢速分片可能会降低整个复制组的同步速度。当然,单个慢速分片也会降低已经路由到这个分片的不幸索引的索引速度。

    4.2 脏读,隔离的主分片可以暴露无法识别的写入。这是因为隔离的主服务器只有在向其它副本发送请求或向主服务器发送请求时才会意识到它已经被隔离了。此时,操作已经索引到主分片中,并且可以通过并发读取来读取索引。ES通过每秒ping一次主服务器【默认】并在没有master知道的情况下拒绝索引操作来减轻这种风险。

posted @ 2019-07-16 20:58  云山之巅  阅读(662)  评论(0编辑  收藏  举报