昨晚氵群的时候,几个读者群都很热闹,点开几乎都在讨论B站崩了的事情,大家还不断在给B站做压测,访问从没停止过。

写段子、调侃B站的文章已经太多了,作为技术人,正好借这次机会说说互联网公司是怎么做高可用的。

一般互联网公司,经过了这十几二十年的增长,技术的一轮一轮迭代,中型以上互联网公司基本都有一套自己的高可用的架构,经历了一个阶段:

  • 单机房
  • 同城多机房
  • 异地多活(二地三中心)

大多数互联网公司都是走了这样一个架构升级历程,但是真正在容灾方面做的怎么样?估计只有他们自己最清楚。

国内互联网公司的SRE很多都是参考Google 来做的,方法论是Google在2015年发表的一篇论文《High-Availability at Massive Scale: Building Google’s Data Infrastructure for Ads》,为此Google还写了一本书(书图片放下面了),相信很多人都看过。不过即使是强如Google,也有服务宕机的情况。

b站崩了那一夜我想该写点什么了_高可用

美国东部时间 12 月 14 日,大量用户反馈 Google 公司服务中断, YouTube、Gmail、Google 云端硬盘、Google Search 等服务无法正常使用。此外,不少热门手机游戏也受到了波及,因为需要用谷歌账户登录。长达 50 分钟的宕机,致使全球多个国家及地区用户受到严重影响。

原因:Google Cloud Platform 和 Google Workspace 经历了一次全球中断,影响了所有需要 Google 账户认证的服务,持续时间为 50 分钟。根本原因是我们的自动配额管理系统出现了问题,降低了谷歌中央身份管理系统的容量,导致其在全球范围内返回错误。因此,我们无法验证用户请求是否经过认证,并向用户提供错误。

简单来说,是由于内部存储配额的问题使 Google 身份验证系统中断,导致宕机了 50 分钟。

其实就算是做了异地多活,也不能完全保证系统服务完全不宕机,没有银弹,这是软件系统本身的复杂性决定的,一方面互联网技术在不断迭代,从最开始的单机,到双机HA、虚拟化、分布式、容器、再到上云、云原生、Service Mesh等。另一方面业务需求也越来越复杂,从原来的注重用户和业务的野蛮增长,到用户的精细化运营,从增量市场到存量博弈,业务的复杂度越来越高,随之也加重了技术的复杂度。

下面说一说互联网公司基础架构的演进。

单机房

一般对于很多服务连续性要求不高,可用性要求没那么高的,比如公司内部的系统,很多就是单机房部署,有的甚至是单机部署。

安琪拉以前大学给老师搞的软件,那时候用的C#写的,本地部署,说简单点就是直接在实验室老师的电脑上部署好,整台电脑(软件带硬件)一起卖给人家的,因为只是工具软件,数据都是保持在本地的,软件卡了直接关机重启,????。架构图如下:

b站崩了那一夜我想该写点什么了_互联网公司_02

一般虽然是单机房,但是很多都是分布式部署的,所以如果机房出现故障,就只能死等。

同城双机房

单个机房在出现不可抗拒的问题(如断电、断网等因素)时,会导致无法正常提供服务,会对业务造成潜在的损失。所以在金融级的高可用设计上,为了避免用户损失,需要一种可以基于同城或异地的多个不同机房之间的多活机制,在保障数据一致性的同时,能够最大程度降低由于机房的单点可用所导致的潜在高可用问题。同城双活就是其中的一种机制。

因为同城双机房实际就是在一个城市,建立了二个机房,从物理位置上可以离的足够近,所以可以在二个机房之间拉根专线,机房之间部署的系统可以相互调用,接口层的DNS、四层设备、反向代理、网关/Web层可以随机路由。

有一个机房出现故障时,可在基本不丢失数据的情况下进行应急切换,保持业务连续。逻辑架构图如下:

b站崩了那一夜我想该写点什么了_数据_03

如果从设计上,按服务维度拆分应用,应用之间用rpc服务调用连通,平台层面设计服务治理的策略,服务可做水平扩展,弹性扩缩容,机房之前近似与同机房部署,内部服务路由策略可以自由选择,例如:轮询、一致性哈希、同机房优先、sticky session、自定义路由规则等。

将业务系统拆分为模块化、标准化、松耦合、可插拔、可扩展的微服务架构。

存储层以MySQL数据库为例,主从复制,主节点故障时候可以手工或者自动切换从为主,但是这种方案只是解决可用性问题,对于数据一致性是有损的,以为这种架构设计一个时间点只有一个Master节点,目前更合理的设计是采用分布式数据库,利用Paxos、Raft分布式多数派原则,比如存在5个Master节点,写时需要3个节点都写成功才算成功,这样通过一致性协议保证数据强一致。

二地三中心(异地主备

因为出现某个城市出现洪涝、地震等自然灾害,会出现城市级机房不可用的情况,所以跨城机房就是避免这种情况出现而产生,但是很多公司因为成本和服务可用性要求没这么高,没有做异地主备。

这种架构模式是在同一个城市,弄二个机房,在另一个城市弄一个备用机房,叫做同城双活+异地灾备,也是很多CTO常常提的两地三中心。

b站崩了那一夜我想该写点什么了_高可用_04

一般跨城调用是有一定延迟的,上海杭州大概是30ms左右,一般异地主备主要还是一个做主,另一个主要起到数据备份,服务backup的功能,如果主机房服务出现可靠性问题,例如访问成功率断崖式下跌,可以立即让异地的备份机房立即切主,等到主机房故障恢复,再切回主机房。

备机房有点类似于主机房的镜像,所以访问层、服务层和存储层都是独立部署的。备机房访问层和服务层一直会有health check,以及仿真流量,保证备机房服务随时启用的时候都是可用状态,不然主机房挂了,启用备用机房的时候发现备用机房也是不可用的,那就完蛋了。

同城双活+异地灾备虽然对可用性有帮助,对于可用性要求不高的不需要做这种架构。这种同城双活+异地灾备架构也有一些弊端:

  1. 异地灾备没有业务流量,但是备份了二个主机房的所有业务数据,异地机房的机器容量、配置要求也不低,平常大部分情况机器都是空跑的,利用率比较低,所以成本还是比较高的。
  2. 跨城同步还是有一定延迟,如果平时没有经常演练,即使主机房出故障,也不敢贸然切异地灾备机房;每年蚂蚁5月份都有机房演练,比如直接把一个机房断电,断网,还有红蓝对抗,人为故障注入。
  3. 故障灾备策略往往不是自动化的,不能一有业务异常就切备,所以决策还是比较复杂的,一般也不会做出自动化的,需要测试演练,所以维护的成本、切换的风险也很高;
  4. 因为主备资源系统的相似性,所以伸缩性不好,扩容困难,因为主备肯定要一起扩一起缩容,服务和容量都要对应。

因为这些弊端的存在,就衍生了异地多活。

异地多活

异地多活指的是不是只有同城的二个机房提供服务,物理地址不同的机房同时提供服务。

架构设计图如下:

b站崩了那一夜我想该写点什么了_互联网公司_05

异地多活下,可以按照就近原则,用户访问更快,如上图,华东用户就访问上海机房,华南用户就走深圳机房,时效性更好,如果机房出故障,路由层把流量切到异地机房。业务流量可以自定义配置,不均等的分配到各个地域机房里面。与异地单机房相比,

  • 具备更快的恢复能力。流量动态分配,一个区域挂掉,流量可以自由的在地域间调度、切换。

  • 不用备份全站,成本更低。

  • 数据异地backup,同机房也有数据备份,数据流量支持自定义,机房维度扩缩容更灵活,比如我可以99%流量给到其中一个机房,把某个机房流量调到只剩1%,在云环境中,可扩展性更好。

当然并不是所有业务都需要做异地多活,对可用性有极致要求,核心应用,数据规模大的才优先做,否则整个技术复杂度也会比较复杂。

逻辑架构如下:

b站崩了那一夜我想该写点什么了_数据_06

 

LDC 单元化

LDC 单元化架构是可以实现异地多活和高并发场景的架构体系,LDC(Logic Data Center)逻辑数据中心是相对于传统的 IDC(Internet Data Center)提出的。逻辑数据中心所表达的中心思想是无论物理结构如何的分布,整个数据中心在逻辑上是协同和统一的。主要适用于大型互联网公司在线交易系统支持,比如淘宝、支付宝、携程等。

关于LDC架构,因为技术敏感方面原因,我隐去一些信息,周末整理以后再发出来,这个是目前阿里云和蚂蚁采用的部署架构。