【架构入门 – 高可用篇】计算高可用

计算高可用的目标是当部分服务器停止服务时,整体的计算任务能够继续进行,所以本质是通过冗余来规避风险

问题

计算高可用的复杂度体现在 任务管理 方面,比如一台机器挂了,那么上面的任务如何处理?所以设计高可用架构有以下问题:

  1. 哪些服务器可以执行任务?第一种方式是每个服务器都能执行任务;第二种方式是特定主机可以执行任务,如etcd的leader
  2. 任务如何重新执行?第一种是即使任务失败也不处理,但要保证新的任务分配到其他正常机器上执行;第二种是通过任务管理器来管理计算任务,当任务执行完成之后反馈给管理器来决定是否将任务重新分配到其他服务器上执行

那么针对以上问题,有以下几种常见架构可供选择

主备

主备的架构:

  • 主机执行所有计算任务。备机上的业务系统已经准备好启动环境(冷备)或正在运行业务系统(热备)
  • 主机故障时,将计算任务继续发送给主机,此时系统部分不可用
  • 如果主机恢复了,任务分配器继续发送任务给主机,如果不能恢复,则需要人工操作,将备机升级为主机,还需要拿掉原来的主机,且增加一台备机

优点:简单,主备、任务分配器之间不需要交互来判断状态和自动切换的配置

缺点:人工操作不可控、系统挂掉的可能性大、备机性能的浪费

适合:使用人数不多,不太重要的后台管理系统

主从

主从的架构:

  • 主机与从机同时执行计算任务
  • 主机故障时,将计算任务继续发送给主机,此时系统部分不可用
  • 如果主机不能恢复,需要人工操作,将从机升级为主机,拿掉原主机,增加新从机

优点:系统稳定性得到部分提升、所有机器的性能充分发挥

缺点:人工操作不可控、系统挂掉的可能性大、需要对任务分配器进行任务分配的配置

适合:使用人数较多,比较重要的后台管理系统

对称集群

首先定义一下集群的分类:

对称集群,就是集群中每个服务器都是执行的相同的任务

非对称集群,就是集群中的每个服务器的角色可能不同,执行不同的任务

主备与主从的最大的问题在于只有固定的主备和主从两个(组)服务器,需要人工干预进行增减,不能保证服务的可用性。所以在集群方案里,系统需要完成自动切换操作

对称集群的架构:

  • 所有机器同时执行计算任务
  • 某台机器故障时,将计算任务停止发送给它,而是发给其他机器

这里的复杂度在于:

1) 任务分配器如何分配任务?

在之前的 【架构入门 – 高性能篇】集群高性能 已经讲到过负载均衡算法,这里不废话了

2) 任务分配器如何检测服务器状态?

一般是根据任务分配器与服务器之间传递心跳包、或者任务分配器对于发送给服务器的请求做记录,比如一段时间内超过多少个错误请求来检测的,如Nginx的配置:

upstream backend {
    server backend1.example.com;
    server backend2.example.com max_fails=3 fail_timeout=30s;
}

如果NGINX未能在30秒内向服务器发送请求或未收到响应3次,则表明服务器在30秒内不可用。如果本次请求中,节点正好出现故障,Nginx将把请求转交给接下来的节点处理。所以不会影响到这次请求的正常进行。

优点:系统稳定性高、所有机器的性能充分发挥

缺点:复杂度高

适合:在线服务

非对称集群

非对称集群的架构:

  • 集群中用某种方式来区分不同服务器的角色。如取当前存活服务器中节点ID最小的服务器作为master服务器
  • 任务分配器将不同的任务发送到不同服务器。如将A任务发送给master服务器,将B任务发送给slave服务器
  • 当服务器故障时,需要重新分配角色

对比对称集群,复杂度更高:

  1. 任务分配策略更复杂,需要将任务划分成不同类型到不同角色节点
  2. 角色分配策略也复杂,需要ZAB/Raft算法实现Leader选举

比如在Zookeeper中:

  • 任务分配器:每个节点都是任务分配器,Follower角色收到请求后判断,如果是写请求就发送给Leader角色,如果是读请求就自己处理
  • 角色分配:ZAB算法选举Leader,当Leader故障后,所有Follower角色会暂停写操作,然后开始选举,直到新的Leader选举出来之后才继续提供服务

优点:系统稳定性高、所有机器的性能充分发挥

缺点:复杂度高

适合:大规模集群内部高性能分布式协调管理中心

参考

号外号外

最近在总结一些针对 Java 面试相关的知识点,感兴趣的朋友可以一起维护~

地址: https://github.com/xbox1994/2018-Java-Interview