前面两篇文章,向读者介绍了Elasticsearch中REST API的基本规范,相信读者阅读完后,对REST API已经有了一个基本的认识,从本篇文章开始,要慢慢向读者介绍文档的相关操作了,那么在详细介绍文档的相关操作之前,本文先来对文档相关读写操作做一个简单概述。
本文是Elasticsearch系列的第七篇,阅读前面的文章,有助于更好的理解本文
Elasticsearch中的每个索引都会进行分片,每个分片又都会有多个副本,这些副本称为replication group,在添加或删除文档时这些副本也必须保持同步,否则在数据读取时就会出现数据紊乱,保持分片副本的同步并从中提供读取的过程就是我们所说的data replication model。
Elasticsearch的数据复制模型基于 主-备
模型,在这个模型下,分片分为主分片和副本分片,主分片是所有索引操作的主要入口点,它负责验证并确保所有操作是正确的,一旦主分片接受了索引操作,主分片在索引操作执行成功后还要负责将操作复制到其他副本。
Elasticsearch中的每个索引操作首先通过路由解析到replication group,这一操作通常基于文档ID,一旦replication group被确定后,索引操作将在内部转发到replication group的当前主分片上,主分片将负责验证操作并将操作转发到其他副本。由于副本可以离线,因此不需要将主分片复制到所有副本,Elasticsearch会维护一个应该接收操作的分片副本列表,这个列表称为同步副本并由主节点维护。顾名思义,这些是“好”分片副本的集合。
主分片遵循以下基本流程:
在索引的过程可能会出现各种各样的异常情况,例如:1.磁盘损坏;2.节点相互断开连接;3.由于配置错误导致复制副本上的操作失败,尽管它在主服务器上操作成功,等等。虽然这些问题并不一定常见,但是开发者还是有必要作出相应的预案。 在主分片本身发生故障的情况下,托管主分片的节点将向Master发送有关它的消息,此时索引操作将等待(默认情况下最多1分钟),以便Master将其中一个副本提升为新主分片,然后,该操作将被转发到新的主分片处理。 请注意,Master还会监控节点的运行状况,并可能决定主动对主分片进行降级(这通常是由于网络问题导致的)。一旦在主分片上成功执行了操作,主分片就必须处理在副本上执行操作时存在的潜在故障,这些潜在的故障可能是由副本上的实际故障或由于网络问题导致操作无法到达副本(或阻止副本响应)引起的。所有这些都具有相同的最终结果:同步副本集中的一部分副本错过了即将被确认的操作。此时,主分片向Master发送消息,请求从同步副本集中删除有问题的分片。只有在Master确认删除了分片后,主分片才会确认操作。注意,Master还将指示另一个节点开始构建新的分片副本,以便将系统还原到正常状态。 在将操作转发到副本时,主分片将使用副本来验证它仍然是活动主分片。如果主分片由于网络原因(或长GC)而被分离,它依然可能会在被降级之前继续处理传入的索引操作,此时副本将拒绝来自旧主分片的操作。主分片收到副本的拒绝请求后会请求Master节点,Master会告诉旧的主分片你已经被替换掉,然后操作会被路由到新的主分片。
由于索引的配置原因或者所有副本都已失效,在这种情况下,会发生主分片没有副本。此时,主分片处理操作而没有任何外部验证,这可能看起来有问题。另一方面,主分片本身不能使其他分片失效,但可以请求Master代表它执行此操作。这意味着Master知道主分片是唯一的好副本。因此,我们保证Master不会将任何其他(过时的)分片副本提升为新的主分片,并且任何索引到主分片的操作都不会丢失。当然,由于此时我们只使用单个数据副本运行,因此物理硬件问题可能导致数据丢失。
Elasticsearch中的读取操作,可以是按照ID查找这种非常轻量级的操作,也可以是具有复杂聚合的大量搜索请求,这些聚合操作会占用非常大的CPU算力。 主-备
模型的优点之一是它使所有分片副本保持一致(除了飞行中的操作)。基于此,单个同步的副本足以处理读取请求。
当节点收到读取请求时,该节点负责将其转发到保存相关分片的节点,整理响应并对客户端做出响应。此时,我们将该节点称为该请求的协调节点,该节点的基本工作流程如下:
当分片无法响应读取请求时,协调节点将从同一复制组中选择另一个副本,并将分片级别搜索请求发送到该副本,不过要是重复失败可能导致没有可用的分片副本。在某些情况下,例如search请求中,Elasticsearch更愿意快速响应,而不是等待问题得到解决(此时虽然只有部分结果,部分结果会在shards中指出)。
这些基本流程确定了Elasticsearch读取和写入系统的行为。此外,由于读取和写入请求可以同时执行,因此这两个基本流程彼此交互,有一些固有的含义:
在正常操作下,对每个相关的replication group执行一次读取操作。只有在失败的情况下,才会对同一个分片的多个副本执行相同的搜索。
由于主分片首先在本地进行索引,然后将操作发给副本去执行,因此并发读取可能在确认之前就已经看到了更改的数据。
此模型可以容错,同时只保留两个数据副本。这与基于法定数量的系统形成对比(容错的最小副本数为3)。
在操作失败的情况下,以下是可能的:
1.单个分片可以减慢索引速度
由于主分片在每个操作期间等待同步副本集中的所有副本,因此单个分片操作速度慢可能会降低整个replication group的速度。这是我们为上述阅读效率付出的代价,同时,单个慢速分片也会降低已经路由到它的搜索请求。
2.脏读
被隔离的主分片可以执行写操作,但是却无法被确认,这是因为隔离的主分片只有在向其副本发送请求或向Master发送请求时才会意识到它是隔离的。此时,操作已经索引到主分片中,并且可以通过并发读取来读取。Elasticsearch通过每秒ping一次Master(默认情况下)并在没有Master的情况下拒绝索引操作来减轻这种风险。
好了,本文先介绍到这里,有问题欢迎留言讨论。