后台服务分为有状态和无状态两类。高可用性对于无状态应用来说相对简单。无状态应用只有通过F5或者任何代理才能很好的解决。下面的描述主要是针对有状态服务的分析。服务器的状态维护主要通过磁盘或者内存来保存,比如MySQL数据库,redis等内存数据库。除了这两类维护方式之外,还有jvm的内存的状态维护,但是jvm的状态生命周期通常很短。一些高可用性解决方案是高可用性的。从发展来看,大致经历了以下几个过程:冷备双机同城热备双活异地双活异地多活。解决方案,帮助我们理解许多设计的原因。冷备是通过停止数据库对外提供服务和复制文件的能力,对数据进行快速备份和归档的一种操作方式。简而言之,冷备就是复制粘贴,在Linux上可以通过cp命令快速完成。它可以手动完成,也可以通过预定脚本完成。它具有以下优点:简单快速的备份(与其他备份方法相比)和快速恢复。只需要将备份文件复制回工作目录即可完成恢复过程(或者修改数据库的配置,直接修改备份目录为数据库工作目录)。更重要的是,恢复可以通过两个mv命令立即完成。可以根据时间点恢复。比如前几天发生的拼多多优惠券漏洞被刷了一大笔钱,可以按照之前的时间点恢复,“追回损失”。以上好处是以前软件的好方法。但对于今天的很多场景来说,它并不好用,因为:需要关闭服务。N个九是绝对做不到的。那么,以前我们的停机冷备份是在凌晨没人用的时候进行的,但是现在很多互联网应用已经是全球性的,所以随时有人在用。数据丢失。如果不采取任何措施,数据恢复完成后,从备份时间点到恢复时间点的数据将会丢失。传统的方法是冷备恢复后,通过数据库日志手动恢复数据。比如通过redologs,更有什者,我曾经用业务日志手动replayrequests来恢复数据。恢复是一项巨大的体力活动,错误率高,恢复时间长。冷备份是完全备份。完全备份会造成磁盘空间浪费和容量不足,只能通过将备份复制到其他移动设备来解决。因此,整个备份过程耗时较长。想象一下,每天要将数TB的数据拷贝到移动硬盘,需要多少移动硬盘和多少时间。此外,无法自定义完整备份。例如,只有某些表无法备份。如何权衡冷备份的利弊,是每个企业都需要考虑的问题。与冷备份相比,双机热备份与热备份的主要区别在于不需要停机,在备份的同时提供服务。但是恢复的时候还是需要关机。由于我们讨论的是存储相关的,所以共享磁盘的方式不算双机热备。Active/Standby模式相当于1主1从。主节点对外提供服务,从节点作为备份。通过某种方式,将数据从主节点同步到从节点,当发生故障时,从节点设置为工作节点。数据同步的方法可以是软件层面的,也可以是硬件层面的。软件层面,比如mysql的master/slave方式,通过同步binlog的方式;sqlserver的订阅复制方式。在硬件层面,通过扇区和磁盘拦截等镜像技术将数据复制到另一个磁盘。面向硬件的方法也称为数据级容灾;面向软件的方法称为应用程序级灾难恢复。后面的文章会更多的讲到应用级的容灾。双机互备本质上是Active/Standby,只是互为主。双机互备对同一个业务不起作用,但是从服务器的角度来说,更好的挤压了可用资源。比如两个业务分别有A库和B库,通过两台机器P和Q进行部署,那么对于业务A来说,P是master,Q是slave,对于B业务来说,Q是master,P是slave。从整体上看,两台机器似乎是互为主备。在这种架构下,读写分离非常好。单写多读,减少冲突,提高效率。其他的高可用方案也可以参考各种数据库的各种部署方式,比如mysql主从、双主多从、MHA;redismaster-slave、sentinel、cluster等。上面提到的同城双活的几种方案,基本都是在一个局域网中进行的。业务发展后,有打算多住同一个城市。和之前相比,不信任的粒度从机器变成了机房。该方案可以解决IDC机房整体挂掉的情况(停电、断网等)。其实同城双活和上面说的双机热备没有本质区别,只是“距离”更远,基本是一样的(专线网速在同城还是挺快的)。双机热备提供容灾能力,双机互备避免资源过度浪费。借助程序代码,部分业务还可以实现真正的双活,即同一个业务,双主,同时提供读写,只要处理好冲突即可。需要注意的是,并不是所有的企业都能做到这一点。行业更多采用两地三中心的做法。异地备份机房可以提供更强的容灾能力,更好地抵御地震、恐怖袭击等情况。双活机必须部署在同一个城市,距离较远的城市作为容灾机房。灾备机房不对外提供服务,仅作为备份,发生故障时将流量切换至灾备机房;或者它仅用作数据备份。主要原因是距离太远,网络延迟太大。如上图所示,用户流量负载均衡,将服务A的流量发送到IDC1和服务器集合A;服务B的流量发送给IDC2和服务器B;同时,服务器组a和b分别从A和B进行同城专线数据同步,通过长途异地专线同步到IDC3。当任何一个IDC宕机时,将所有流量切换到同城另一个IDC机房,完成故障切换。当1市发生大面积故障时,比如地震导致IDC1和2同时停止工作,数据会保存在IDC3中。同时,如果负载均衡仍然有效,则可以将所有流量转发到IDC3。但是此时IDC3机房距离很远,网络延迟变得很严重,通常会严重影响用户体验。上图是基于Master-Slave模型的两地三中心示意图。1市两机房作为一主一从,远程机房作为从机。也可以采用同城双主+keepalived+vip的方式,或者MHA的方式进行failover。但是城市2不能(最好不要)被选为Master。异地双活和同城双活可以应对大部分容灾情况,但在大面积停电或自然灾害发生时,服务仍然会中断。对以上三个中心进行两地改造,前端入口节点和应用异地部署,在1城停止服务后将流量切换到2城,可以在降低用户体验的同时降级。但是,用户体验明显下降。因此,大多数互联网公司都采用了远程双活方案。上图是一个简单的远程双活的示意图。流量经过LB后分发到两个城市的服务器集群。服务器集群只连接到本地数据库集群。只有当所有本地数据库集群都无法访问时,它们才会故障转移到远程数据库集群。这样,由于远程网络问题,双向同步需要更多的时间。较长的同步时间将导致更严重的吞吐量下降或数据冲突。吞吐量和争用是两个对立的问题,您需要在它们之间做出权衡。比如为了解决冲突,引入分布式锁/分布式事务;为了获得更高的吞吐量,使用中间状态、错误重试等方式实现最终一致性;可以在一个节点中完成整个交易。对于一些不能接受最终一致性的业务,饿了么采用下图所示的方式:针对个别需要高一致性的应用,我们提供强一致性解决方案(GlobalZone)。GlobalZone是一种跨机房的读写分离机制,所有写操作都指向一个Master机房保证一致性,读操作可以在各个机房的Slave库中进行,也可以绑定Master机房room,都是基于我们的数据库访问层(DAL)完成的,业务基本无感知。也就是说,该区域不能进行双活。采用master代替双写自然就解决了冲突的问题。其实remote-active和remote-multi-active已经很相似了,active-active的结构更简单,所以程序架构不需要考虑太多,只需要做传统的限流,故障转移和其他操作。但实际上,双活只是暂时的一步,最终目的还是要转为多活。因为双活存在数据冲突的问题,无法横向扩展。根据异地多动的思路,我们可以画出异地多动的示意图。每个节点的出度和入度都是4,这样的话,任何一个节点下线都不会影响业务。但是考虑到距离,一次写操作会带来更大的时间开销。除了影响用户体验,时间开销也带来了更多的数据冲突。在数据冲突严重的情况下,使用分布式锁的代价也更大。这将增加系统的复杂性并降低吞吐量。因此,不能使用上面显示的解决方案。还记得我们在求解网状网络拓扑时是如何优化的吗?引入中间节点,将网络改成星型:改成上图后,各城市下线不影响数据。对于原请求城市的流量,会重新LoadBalanced到新的节点(最好LB到最近的城市)。为了解决数据安全问题,我们只需要和中心节点打交道即可。但这样一来,对中心城市的要求就会高于其他城市。比如恢复速度、备份完整性等,这里暂且不展开。我们首先假设集线器是完全安全的。如果我们按照上图的结构部署了远程多活业务,那么各地数据同步的问题已经基本解决了,但是还是会存在大量的冲突,可以简单的认为类似于双活性。那么有没有更好的办法呢?回顾上面提到的饿了么的GlobalZone方案,大意是“去分布式”,即将写好的业务放在一个节点(同城)机器上。阿里是这样想的:其实我猜很多业务也是按照上图实现的,比如滴滴打车业务,所有业务都是按城市划分的。用户、车主、目的地的经纬度通常在同一个城市。单个数据中心不需要与其他数据中心交互。只在生成报表的时候需要,但是报表不太注重实时性。那么这样的话,全国业务其实是可以很好的分片的。但是,对于电商等复杂场景和业务,上述方式的分片已经不能满足需求。由于业务线非常复杂,数据依赖关系也非常复杂,各个数据中心之间难免会同步数据。淘宝的方案有点类似于我们切分微服务的方法:注意图中的数据同步箭头。以交易单元为例,属于交易单元的业务数据会从两个方向同步到中心单元;不属于交易单元的业务数据将从中央单元单向同步。中心单元承担最复杂的业务场景,业务单元承担相对单一的场景。对于业务单元,可以进行弹性伸缩和容灾;对于中央单元,扩展性较差,稳定性要求较高。可以看出,大部分故障都会发生在中央单元。按业务切分单元已经需要对代码和架构进行彻底的改造(也许这就是阿里从双活转多活的原因,用了3年时间)。比如业务拆分、依赖拆分、mesh转star、分布式事务、缓存失效等,除了对编码的要求很高,对测试和运维也有很大的挑战。在如此复杂的情况下,如何自动化覆盖,如何进行演练,如何改造流水线。这种级别的容灾不是一般企业敢做的,投入和产出不成正比。但是,我们还是可以把这个场景作为我们的“假想敌”来思考我们自己的业务,未来会怎样发展,我们需要什么样的灾备水平。相对而言,饿了么的多活方案可能更适合大部分企业。本文仅通过配图进行简要说明。其实异地多居需要很多非常强大的基础能力。比如数据传输、数据校验、数据操作层(简化客户端控件编写和同步的过程)等。来源|https://blog.dogchao.cn/?p=299
