不知不觉已经写到了最后一部分,回顾经历的这段架构演进历程,内心还是非常感慨。在商业竞争中,技术团队和其他团队一样,作为组织的一部分,应该是荣辱与共的。但是,就行业而言,饿了么创造的社会价值也是显而易见的,而且,饿了么塑造了这个行业最初的模样,对社会创造的价值影响是长远的。
回顾前两篇文章:
第四阶段:Cloud Ready
这个阶段,技术体系承担了日均千万级的单量,通过建设多数据中心的技术体系,提供了数据中心节点跨地域水平展开的能力,从根本上解决了扩展性的问题。为业务发展提供足够的系统容量保障。同时,架构演变到了Cloud-Ready的状态,也为我们技术体系演进提供了更多可能性。
这个阶段我们面临的是前所未有的挑战,架构也因此迭代到了全新阶段
1、数据中心容量到达上限,如何避免成为业务发展的瓶颈
2、两次大规模组织融合,技术体系如何融合
3、全面上云后技术体系如何演进
多数据中心
2017 年 5 月,建成了多数据中心的技术体系。后面很多看起来轻而易举的事情 —— 午高峰线上故障容灾、全面上云、全站底层容器及调度系统的升级等等 —— 没有这次架构演进将会很艰难。
体会和教训:多数据中心——多数据中心核心解决高可用诉求和容量带来的性能需求:
高可用:多个数据中心节点解决了单点问题。
性能和扩展性:通过部署在不同地域的节点,解决了两个问题。
离用户更近:具备地域属性的用户群体,和他们相关的运算和数据,离得更近。尤其适用于业务范围地域分布广的场景——全国甚至全球。
水平扩展能力:理论上可以在任何的地域拉起数据中心节点,解决业务快速发展带来的容量压力,从而解决性能瓶颈。具备多数据中心能力的架构,可以看作广义的分布式体系。
基于以上几点,多数据中心架构有它适用的场景:
用户有地域分布的特征
业务对可用性和弹性扩展能力有很高的要求
反之,以下场景就不适合多数据中心架构:
数据必须集中处理
业务没有按地域分布的特征
要求强一致、不能接受系统环境的不确定性、系统不具备弹性的架构体系
架构非常简单、业务量很小,分布式节点和冗余没有带来太多收益
三种形态:主备(active-passive)模式,对等(active-active )模式,以上两者的混合。
主备:通常的同城双中心,在一个地理位置上相近的区域(比如云上的一个region内),建立起两个数据中心(比如云上的availability zone),组成一个虚拟的数据中心,流量按照一定策略负载均衡到两个数据中心。无状态的服务,或者只读的请求,通过负载均衡策略,可以同时分发到两个数据中心处理,这个场景下,但是涉及到写请求只能在一个数据中心处理。存储服务的主节点故障会触发主备切换,写操作由另一个数据中心的节点承担。容灾为主,扩展性稍差,两个数据中心的时延要求严格,所以不能太远(通常同城),极端情况下,region故障,或者region容量达到上限,会比较被动,优点在于改造起来简单。
对等:跨区域部署的,基于地理位置的“分布式”数据中心。数据中心之间没有主次,可互为容灾对象,理论上可以水平扩展到更多节点。通常数据中心会部署在不同区域(云上的不同region),容灾能力和扩展能力都更强,缺点在于改造成本和对中间件等基础设施的要求高。
混合:更适合多数据中心建设从主备演进到对等模式后的形态
两种模式如下图所示:
图:主备
图:点对点
上下文
对于饿了么而言,核心诉求首先是扩展性,然后才是容灾。根据当时业务团队评估,在年底行业的单量就会翻番,当时的系统是无法承担这个业务量的,就地扩容是第一选择,但是当时的 IDC 供应商告诉我们没有这么多的资源,不是机器或者机架问题,是没有机房了,新机房在建,按照进度,交付时间风险非常大。在这个背景下,我们启动了多数据中心的建设,并选择了对等架构。
从业务开发进场改造,到完成线上切流,我们用了 3 个月的时间。但是,所依赖的基础设施和架构建设,是在之前几年时间积累起来的。
体会和教训——选型考量
为什么不采取同城双中心?如果仅仅是为了容灾,那可能也足够了,但是,加上扩展的需求就有问题。我们的数据中心,消耗资源最多的并不是承担业务逻辑的SOA服务类应用,算力消耗的大户实际上是基础设施中间件 —— 消息队列、分布式缓存、监控体系、各种类型的数据库等等。同城双中心主备的架构,写操作只能在一个机房,比如数据库等只能是主/备,写操作是没有办法充分利用多数据中心的优势水平扩展的,如遇到单机房容量瓶颈,比较被动。
多数据中心建设架构选型还是要依据自己的业务特点,综合考虑到系统的现状、能承担的冗余成本、以及业务规划,选择适合的架构。
基础设施
解耦
多数据中心可以水平扩展的前提是,各个数据中心之间需要解耦,从用户端发起请求开始,一笔交易内的调用链封闭在当前数据中心完成,尽量减少跨数据中心的RPC请求。与此同时,还要求数据中心之间互为容灾的角色。依赖两个组件解决这个问题:Data replication service 和 Gateway。
Data Replication Service
作为数据同步服务,这个组件主要解决以下问题:
1、数据中心之间的数据复制:出于容灾的需要,数据在一个数据中心写入后,需要同步到其他数据中心
2、循环复制阻断:确保一条数据的复制是单向的
3、数据变更事件广播:供业务方订阅用于更新缓存、异步解耦等等场景
4、写冲突的记录和告警:确保第一时间发现数据冲突介入解决
体会和教训——数据同步和复制
上海数据中心上线切流成功的那一天,我们心里面还是没底,担心数据同步出错。系统挂了可以恢复,各数据中心节点间数据发生不一致的话,数据订正的成本很高。多数据中心架构实施后的几年里面,发生过一次 DRC(我们的数据复制服务)变更引入的bug,导致同步出错,好在影响的数据库实例范围可控,但是仍然花了一个通宵订正数据。如果是大规模出问题,后果不堪设想,技术团队可以下课了。
还有一个教训,DRC 被滥用了,因为我们的疏忽,对数据变更事件订阅服务的治理和管控不足,各业务方随意订阅其他业务方的DRC事件广播。因为 DRC 是基于数据库的 bin log 生成的事件,也就是说,订阅方直接监听这个事件,等同于直接访问数据库,如果这个数据库不属于订阅方的业务领域,那么订阅方业务就和数据 owner 的领域数据库耦合在一起了。因此也没少吃亏,某业务系统 S 订阅了商户端领域数据库的部分 DRC 消息,商户端领域的开发团队在一次重构过程中,有部分相关的表不得不双写了半年,还下线不掉,因为 S 的技术团队没空改造……。合理的做法应该是,只允许领域服务订阅自己数据库的 DRC 事件,其他领域作为消费方应该订阅这个领域服务封装的对外消息广播。
Gateway
API Gateway 一开始是由中间件团队负责的。后来,包括 API Gateway 在内的大网关,收口到了大前端团队来负责。之所以称为“大网关”,是因为包括