Elasticsearch 高可用系统架构设计
高可用性即:High Availability(HA),高可用性是分布式系统架构设计的重要因素之一,简单来说,可用性越高的集群在发生意外情况(如断电、节点宕机)的时候,服务发生故障而不可用的可能性越低,也就是降低了意外情况而对整体服务产生的影响的可能性。
高可用性原理
- ES使用数据分片(shard)来提高服务的可用性,将数据分散保存在不同的节点上以降低当单个节点发生故障时对数据完整性的影响,同时使用副本(repiica)来保证数据的完整性。关于分片的默认分配策略,在7.x之前,默认5个primary shard,每个primary shard默认分配一个replica,即5主1副,而7.x之后,默认1主1副
- ES在分配单个索引的分片时会将每个分片尽可能分配到更多的节点上。但是,实际情况取决于集群拥有的分片和索引的数量以及它们的大小,不一定总是能均匀地分布。
- Paimary只能在索引创建时配置数量,而replica可以在任何时间分配,并且primary支持读和写操作,而replica只支持客户端的读取操作,数据由es自动管理,从primary同步。
- ES不允许Primary和它的Replica放在同一个节点中,并且同一个节点不接受完全相同的两个Replica
- 同一个节点允许多个索引的分片同时存在。
ES的容错机制
容错性可以理解系统容忍的局部发生异常情况的比率和当异常发生时自行恢复的能力。在ES
中表现为对节点宕机的处理机制。
步骤:
- Master选举:选出集群中的Leader。
- Replica容错:新的
Active Master
会将丢失的Primary的某个Replica提升为Primary。 - 重启故障机:Master尝试重启故障节点。
- 数据同步:Master将宕机期间丢失的数据同步到重启节点对应的分片上去,从而使服务恢复正常。
高可用性集群设计:
高可用性的中心思想就是采取一切可能的策略,降低集群中任意一部分节点出现问题后导致服务整体不可用的概率。其包含数据的完整性,集群的存活概率以及选主等。
小规模集群
- 单节点集群:
一般用于学习或者开发、测试环境,不推荐在生产环境中使用单节点集群。由于集群只有单个节点,为了适应这一点,ES默认会给集群分配所有角色。单节点角色不具备高可用性,并且无法分配副本分片。为了使集群保持健康,单节点模式下创建索引,需要使用index.number_of_replicas
设置副本数量为0。
两节点集群:
- 如果处于硬件成本考虑,集群中只允许有两个节点,那么一般来说最好把两个节点都设置成数据节点。还应该通过在每个不是可搜索快照索引的索引上设置
index.number_of_replicas
为 来确保每个分片都冗余存储在两个节点1
上。这是默认行为,但可能会被索引模板覆盖。Auto-expand replicas也可以达到同样的效果,但是在这么小的集群中没有必要使用这个功能。 - 推荐在两个节点之一设置node.master: false明确告知其不具备候选节点资格。目的是为了确定哪个节点是主节点。集群可以容忍另一个不具备候选资格的节点的丢失。如果不做此设置,这时两个节点都会具有候选资格,但是其中一个节点如果宕机,由于选主需要票数过半(票数>N/2+1),也就是票数必须是两票才能选出active master,所以会导致无法选主。此时集群无法容忍任何一个节点宕机
- 默认情况下,ES会为每个节点分配所有角色,如果手动分配角色,一般建议为每个节点分配所有角色,如果其中一个节点宕机,另一个节点可以取而代之。
- 两个节点的集群,只允许其中一个固定的节点宕机,而不是任意一个节点。因为如果允许两个节点可以独立选举,那么如果集群由于网络或者其他原因导致节点连接断开,那么两个节点没办法确定另一个节点是否是宕机了,也就是会产生所谓的”脑裂“问题,而产生多主的情况。Elasticsearch 避免了这种情况并通过不选择任何一个节点作为主节点来保护您的数据,直到该节点可以确保它具有最新的集群状态并且集群中没有其他主节点。这可能导致集群在连接恢复之前没有主节点。
三节点集群:
- 三节点部署:如果整个集群中所有节点一共只有三个,建议把三个节点全部部署为数据节点和候选节点。虽然active master节点一般只负责轻量级任务不做数据节点。但是通常来说三节点集群一般不会承载很大的业务量,也就不必考虑那么多了。这也是处于成本考虑不得已而为之。三节点集群的容错能力是1,即允许一台节点故障。
- 二加一部署:即两个候选节点,一个仅投票节点,若干数据节点。这种配置的最大好处就是在保证高可用的前提下性价比更高,适用于小规模集群。由于在避免脑裂的前提下,要选举出主节点的最小节点数量是3,也就是选主的必要条件是票数过半也就是2票。而候选节点一般是不负责其他的任务的,也就不会为其分配data角色,那么集群通常会出现三个节点不存放数据的局面。此时会产生造成资源浪费。因为active master只存在一个,另外两个master作为候选节点,在及群众仅仅是充当了负载均衡器。为了避免这种资源浪费,通常的做法是把其中一个候选节点设置为仅投票节点,即node.roles: [ data, master, voting_only ],此时,当前节点在选举过程中,仅有选举权而没有被选举权,这样就可以同时给他分配数据节点的角色,因为其不会被选举为active master。三节点集群中,三个节点必须都具有master角色,并且仅投票节点最多只能有一个。仅投票节点由叫仲裁节点起着决胜票的作用。
多节点集群
- 一旦集群增长到三个以上的节点,可以开始根据它们的职责对这些节点做职责专一化。主要根据需要配置尽可能多的数据节点、预处理节点、机器学习节点等来均衡工作负载。随着集群变大,一般建议给每个角色使用专用节点,以便为每个任务独立扩展资源。
- 但是,最好将集群中候选节点数量限制为三个。主节点不像其他节点类型那样扩展,因为集群总是只选择其中之一作为集群的主节点。如果有太多候选节点,那么主选举可能需要更长的时间才能完成。在较大的集群中,一般建议把候选节点设置为专用候选节点,即不分配其他角色,并避免向这些专用节点发送任何客户端请求。以免候选节点被不必要的额外工作所拖累导致集群服务不稳定。
- 但是可以把候选节点之一配置为仅投票节点以便它永远不会被选为主节点。例如,集群可能有两个专用的候选节点和一个既是数据节点又是仅投票的候选节点的第三个节点。这第三个仅投票节点将在Master选举中投出决胜票,但是自己永远不会被选举为active master。
大规模集群
单集群
- 避免跨数据中心:ES对网络和宽带要求较高,并且一般来说要尽量避免服务跨多个数据中心。因为一旦遇到分区恢复问题,它必须重新同步任何丢失的数据并重新平衡集群。如果一定要跨多个数据中心,建议在每个数据中心部署独立集群,然后配置跨集群搜索或跨集群复制。
- 部署分片分配感知:为了降低当集群出现单个或区域节点(比如一个机架)宕机对整个服务造成的影响,一般策略是通过分配感知来实现。
双区集群:
- 如果集群部署在两个区域比如两个机房内,应该在每个区域中拥有不同数量的候选节点,这样在其中一个区域出现问题的时候,会增加另一个区域的存活概率。比如两个机房部署同一个集群,那么两个机房的候选节点避免相等,因为此时如果一个机房意外断电,两个机房的服务都会停止。配置单数投票节点可避免此问题。此时其中一个机房断电,服务可用的概率为50%。
- 双区集群理论上能容忍一个区域的数据丢失,但不是任意一个区域,打个比方:服务部署在两个机房,机房A和机房B,要么是仅允许A机房出现故障而不允许B机房出现故障,也就是A机房断电服务可用,但是B机房断电服务中断;要么是仅允许B机房出现故障而不允许A机房出现故障,也就是B机房断电服务可用,但是A机房断电服务中断。从高可用的角度想,我们更希望任意一个机房断电,另一个机房的服务都不受影响,但是这是不可能的。因为没有断电的机房不知道出现故障的机房是断网了还是断电了,也就不知道应该是发起独立选举还是等待下去。如果两个机房都可以独立选主,那么就无法避免脑裂,可能会产生两个机房选出active master。解决办法是在两个区域中都配置一个仅投票节点并在独立的第三个区域添加一个额外的候选节点。这样两个区域其中之一断电,额外的投票节点就可以投出关键票。这个额外的节点也叫专用tiebreaker节点,此节点可以用低配服务器。
多区集群
- 如果集群中有三个区域,那么每个区域中应该有一个候选节点。如果集群包含三个以上的区域,那么应该选择其中的三个区域,并在这三个区域中的每一个区域中放置一个候选节点。这意味着即使其中一个区域发生故障,集群仍然可以选举主节点。
多集群
- Elasticsearch是主从结构,主节点能管理的节点上线一般不超过一千个,如果继续增加节点,可能会导致active master不稳定,如果集群想突破集群规模带来的性能瓶颈,一般可配置多集群,利用跨集群搜索单个超大集群拆分成多个小集群(相对小,千节点级别)来完成对集群的性能扩展。
总结
- 集群应该至少有两个区域包含数据节点。
- 除了主分片之外,每个 不是可搜索快照索引的索引都应该有每个主分片的至少一个副本。
- 分片分配感知配置为避免将分片的所有副本集中在单个区域内。
- 集群至少有三个候选节点。这些节点中至少有两个不是仅投票节点,均衡分配在至少三个区域中。
- 客户端被配置为将其请求发送到多个区域中的节点,或者被配置为使用负载平衡器来平衡一组适当的节点之间的请求。所述弹性云服务提供了这样的负载平衡器。