高可用解决方案:同城双活?异地双活?异地多活?怎么实现?( 二 )


其他的高可用方案还可以参考各类数据库的多种部署模式 , 比如mysql的主从、双主多从、MHA;redis的主从 , 哨兵 , cluster等等 。
同城双活前面讲到的几种方案 , 基本都是在一个局域网内进行的 。业务发展到后面 , 有了同城多活的方案 。和前面比起来 , 不信任的粒度从机器转为了机房 。这种方案可以解决某个IDC机房整体挂掉的情况(停电 , 断网等) 。
同城双活其实和前文提到的双机热备没有本质的区别 , 只是“距离”更远了 , 基本上还是一样(同城专线网速还是很快的) 。双机热备提供了灾备能力 , 双机互备避免了过多的资源浪费 。
在程序代码的辅助下 , 有的业务还可以做到真正的双活 , 即同一个业务 , 双主 , 同时提供读写 , 只要处理好冲突的问题即可 。需要注意的是 , 并不是所有的业务都能做到 。
业界更多采用的是两地三中心的做法 。远端的备份机房能更大的提供灾备能力 , 能更好的抵抗地震 , 恐袭等情况 。双活的机器必须部署到同城 , 距离更远的城市作为灾备机房 。灾备机房是不对外提供服务的 , 只作为备份使用 , 发生故障了才切流量到灾备机房;或者是只作为数据备份 。原因主要在于:距离太远 , 网络延迟太大 。

高可用解决方案:同城双活?异地双活?异地多活?怎么实现?

文章插图
 
图1 两地三中心
如上图 , 用户流量通过负载均衡 , 将服务A的流量发送到IDC1 , 服务器集A;将服务B的流量发送到IDC2 , 服务器B;同时 , 服务器集a和b分别从A和B进行同城专线的数据同步 , 并且通过长距离的异地专线往IDC3进行同步 。当任何一个IDC当机时 , 将所有流量切到同城的另一个IDC机房 , 完成了failover 。当城市1发生大面积故障时 , 比如发生地震导致IDC1和2同时停止工作 , 则数据在IDC3得以保全 。同时 , 如果负载均衡仍然有效 , 也可以将流量全部转发到IDC3中 。不过 , 此时IDC3机房的距离非常远 , 网络延迟变得很严重 , 通常用户的体验的会受到严重影响的 。
高可用解决方案:同城双活?异地双活?异地多活?怎么实现?

文章插图
 
图2 两地三中心主从模式
上图是一种基于Master-Slave模式的两地三中心示意图 。城市1中的两个机房作为1主1从 , 异地机房作为从 。也可以采用同城双主+keepalived+vip的方式 , 或者MHA的方式进行failover 。但城市2不能(最好不要)被选择为Master 。
异地双活同城双活可以应对大部分的灾备情况 , 但是碰到大面积停电 , 或者自然灾害的时候 , 服务依然会中断 。对上面的两地三中心进行改造 , 在异地也部署前端入口节点和应用 , 在城市1停止服务后将流量切到城市2 , 可以在降低用户体验的情况下 , 进行降级 。但用户的体验下降程度非常大 。
所以大多数的互联网公司采用了异地双活的方案 。
高可用解决方案:同城双活?异地双活?异地多活?怎么实现?

文章插图
 
图3 简单的异地双活示意图
上图是一个简单的异地双活的示意图 。流量经过LB后分发到两个城市的服务器集群中 , 服务器集群只连接本地的数据库集群 , 只有当本地的所有数据库集群均不能访问 , 才failover到异地的数据库集群中 。
在这种方式下 , 由于异地网络问题 , 双向同步需要花费更多的时间 。更长的同步时间将会导致更加严重的吞吐量下降 , 或者出现数据冲突的情况 。吞吐量和冲突是两个对立的问题 , 你需要在其中进行权衡 。例如 , 为了解决冲突 , 引入分布式锁/分布式事务;为了解决达到更高的吞吐量 , 利用中间状态、错误重试等手段 , 达到最终一致性;降低冲突 , 将数据进行恰当的sharding , 尽可能在一个节点中完成整个事务 。
对于一些无法接受最终一致性的业务 , 饿了么采用的是下图的方式:
高可用解决方案:同城双活?异地双活?异地多活?怎么实现?

文章插图
 
 


推荐阅读