前言
在学ES之前先学习的hadoop、hbase、kafka这些分布式存储框架。再学ES的时候有很多可以类比的地方,但是也有很多跟其他框架不太一样的地方,感觉有些别扭。比如副本概念的些许偏差。
在hadoop、HBASE、kafka中,副本是没有主从区别的,因此再说有几个副本的时候基本就是在说同一份数据有几份。比如我们说hadoop有三个副本,意思就是同一份数据有三份,他们之间互为备份。
但是在ES中,感觉副本约定俗称的概念跟上面并不一致。因为ES是有主从副本之分的。如果说某个数据有两个副本,那么大概率是说数据有三份,一个主副本,两个从副本。
当然这种概念上的细微差别并不影响使用,但是还是想在写下文之前把概念性的东西达成共识。
数据复制模型
ES中的每个索引(index)都分为多个分片(默认只有一个分片),每个分片可以有多个副本。这些副本被称为复制组,在增删文档时必须保持同步。保持碎片副本同步,并对外提供数据读取服务的过程,被称为数据复制模型。
ES的数据复制模型是基于主备模型的。即客户端的操作首先会通过路由发送给索引的主分片,主分片如果验证客户端的请求是合法的,主分片会将该请求转发给复制组的其他副本分片。
索引分片顾名思义,就是将一个索引进行纵向切割,划分成多个可独立执行搜索、存取等基本任务的单元。如果学过HBASE,会发现ES的索引分片和HBASE表的Region是差不多的概念。都是为了增加数据并行读取的能力。
基本写模型
ES中的每个索引操作首先使用路由解析到一个复制组。一旦确定了复制组,该操作将在内部转发到该组的当前primary
分片。primary
负责验证操作并将其转发到其他replica
。由于replica
可以离线,因此不需要primary
复制到所有副本,相反,ES的master
节点会维护一个同步副本列表(这一点跟kafka很类似),同步副本需要满足一个条件,即该副本的所有索引和删除操作都跟主分片是同步的。
总的来说,primary
副本的基本流程如下:
- 验证客户端的传入操作,如果结构无效(如数字字段却传入一个字符串)则拒绝该操作。
- 在primary副本本地执行操作,即删除或者索引某个文档。
- 将操作转发到当前复制组,同步副本集中的每个
replica
副本,如果有多个replica
这是同步完成的 - 一旦所有
replica
都成功执行了操作并对primary
做出响应,primary
就确认完成了请求并返回给客户端。
错误处理
- 如果
primary
本身发生故障,primary
分片所在的节点会向集群master
节点发送故障信息,master
节点将会把其中一个同步replica
提升为新的primary
分片。然后客户端的请求将会转发到这个新的primary
分片进行处理。 - 如果
replica
分片发生故障,导致primary
的请求无法到达,或者master
请求到达以后无法收到确认消息。primary
会向master
节点申请将该分片从同步副本集中删除。primary
分片在确认master
节点删除有问题的同步副本以后才会向客户端发送操作成功的确认消息。之后master会尝试在其他节点创建新的同步副本,以便将系统恢复到健康状态。
基本读模型
ES的读取可以是非常简单的按照ID查找,也可以是一个具有复杂聚合的繁重搜索请求。
当节点接收到读取请求时,该节点负责将该请求转发到保存相关分片的节点。我们称该节点为该请求的协调节点,基本流程如下:
- 将读取请求解析到相关分片。由于大多数搜索将被发送到一个或者多个索引,所以他们通常需要从多个分片读取,每个分片表示数据的不同子集。
- 从分片复制组中选择相关的活动分片,可以是
primary
也可以是replica
分片。 - 向所选分片发送读取请求。
- 将结果整合。如果是按照id查找,只有一个相关的分片,也就不需要整合。
错误处理
- 如果所选分片没有响应读取请求,协调节点会将请求重新发送到同一复制组的其他分片。
- 如果复制组中的所有分片都没有响应,那么会导致请求的结果不完整,但是为了确保快速响应,
search
/mutil search
/bulk
/multi get
API会以部分结果响应,并且状态码为200.
注意事项
在上述读写模型中有几个概念非常重要,如果不能理解这些概念,那么对于ES的读写模型就很难真正理解。这里再强调一遍:
- 分片:最简单的理解就是分区。类似MySQL中的分区表。随着数据量的增大,不可能将所有数据都放到一起,这样在查询和删除的时候都会非常慢。其他系统如HBASE中Region的概念对应ES的shard概念。kafka中也有分区的概念可以近似对应分片的概念。
- 复制组:复制组是以分片和副本为基础的。上面讲到了分片的意义。一个ES索引可以有多个分片,同样也可以有多个副本。同一分片的不同副本就构成了一个复制组,只是在ES中分的比较清楚,主副本叫做
primary
,从副本叫做replica
。很明显前者只能有一个,后者可以有多个。 - 同步副本:数据写入ES是先写到
primary
副本再同步到replica
副本的。但是由于网络等一系列问题,很难保证所有备份副本都能跟primary
副本一直同步,这些能保证同步的副本就是同步副本。很明显,同步副本集合是动态变化的。其实这里还有一个问题无法保证replica
副本写入正常,那就能保证primary
写入正常吗?当然不能。但是如果primary
都没有写入正常,这就需要开发人员或者运维人员去排查并解决问题。但是为了效率,在配置ES集群的时候可能会容忍可以有一定数量的replica
副本同步不正常也算成功。 master
节点和primary
分片:已经很明显了,前者代表集群的一个节点,而后者则代表一个索引一个分片的主分片。前者的主要功能是选举primary
分片等。而后者的主要功能是协调数据写入。