一次高可用架构设计实战总结
Posted 云原生Lab
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了一次高可用架构设计实战总结相关的知识,希望对你有一定的参考价值。
一、引言
年前接到组织交下来的任务,国内一家新零售客户要对他们的架构做高可用改造,把当前云上单可用区的应用部署到两个可用区去,这活现在交付项目组上几个技术Leader都搞不定,老大让我把这活接了去。原先也做过一些类似的工作,心里暗爽,看上去这活不难啊,不就是把原先申请在一个可用区的服务器资源,在另外一个可用区也部署一些实例节点么,火速定了机票酒店,以一种“救世主”来carry全场的心态到了客户现场,大概和项目上的同事梳理了下他们架构现状。客户使用的架构大多是基于阿里云的中间件PaaS服务,大致用到了如slb负载均衡器、csb网关、edas服务治理中间件、ack云托管kubernetes集群、drds分布式数据库、还有包括redis、rocketmq这些缓存、消息中间件等。
既然是云托管服务,那也没什么可做的,直接把ack接入的ecs服务器实例一半迁移到另外一个可用区,这事就搞定了啊。于是就把PPT大笔一画,和客户约了时间跟客户做汇报去了。
回忆起当天的汇报情况,简直可以用灾难来形容了,即使事情已经过去了将近2个月,但这场噩梦始终挥之不去。客户看了眼架构图开始提问:“我们现在用的springcloud框架开发的分布式架构,整个链路至少10多次的服务链路请求,跨可用区所带来的响应时间增加你有考虑过吗,改造后的性能和现在的性能你们有评估过差异吗?” “跨可用区部署访问redis的延迟是多少测过吗?” “跨可用区部署之后,你的负载均衡器是不同可用区各接一个还是共用一个”,经过一连串的灵魂拷问之后,客户已经略显不耐烦了,质问我说,“你连最基本的业务场景,系统架构都不了解,这方案怎么证明我们线上不会出问题呢?”。回忆起当时的场景,当时的语气用词会可怕十倍,于是当下连声向客户致歉,表示一定会结合客户的实际场景出发在做改进。
在被客户的一连串问题无所应对吓得冷汗直流之后,又经历了大概1-2周的时间和项目组的同事、客户反复沟通,此时项目上的进展并不顺利,对于各个云产品的专业度也缺乏了解。终于挨到了过年。这次的春节可能是我工作以来最丧的一次,我开始复盘有哪些问题是之前没有考虑到的,慢慢地之前没理清楚的问题开始逐渐问题变得清晰,然后也开启了整个项目逆风翻盘之旅。
犯的第一个错是没有和客户对齐关于高可用的定义。关于系统架构高可用,从业务开发来看,可能是如何通过服务治理框架对业务进行限流降级;从系统架构师的角度看,则是当发生未知故障时,如何保障系统对于真实世界各种异常事件的容错能力。在分布式架构中,可以是小到云服务的一个实例挂了如何保障高可用,又或是当一个机房、一个地区、甚至是一朵云挂了如何做整个的架构高可用。对客户究竟要做到什么程度的高可用,这是先决要达成的核心要素。基于客户目标,然后逐一确认当前云产品的高可用能做到什么程度。
其次,在做解决方案时没有从全局视角出发看整体架构,当第一时间拿到客户的整体应用部署架构图时,觉得分布式架构长得都差不多,并没有想太多如何从架构视角看应用部署图。而在绝大多数的应用部署图上,并不会清晰呈现出链路的走向,云服务具备到怎样的高可用能力等细节。
客户反复提到的的性能问题,可以明确是其关注的核心问题。一开始我便遗漏了一个重要的细节,即客户作为新零售电商有自己的门户,并且平均每个月都会做大促活动,这次要做的高可用架构优化针对的也是业务中台系统。在过往的项目经历中,我确实认为性能的提升一定是在分布式架构是在应用多可用区部署的前提下去设计的,而跨可用区本身带来的网络延迟几乎是可以忽略不计的,而从没有思考过一个核心的问题,即云厂商是否应该为客户的业务系统提供高可用的能力前提下做性能的兜底。
单从分布式理论CAP,结合业务场景来看,阿里内部核心业务的高可用最佳实践实际上已经实现了单元化,即某一个机房因为故障整体不可用,通过流量切换,几乎能够对应用在秒级-分钟级完成切换。恢复时间依赖于目前正在做商业化的可用区工具实现,这又回到了关于服务成本的话题。客户最终愿意为整套架构快速恢复,支付多少预算?
运维管理无论是在任何情况下,都必须要去考虑的事情,如果设计的高可用方案对整体软件发布流程会有很强的侵入性,充斥着大量的手动操作,在遇到问题时难以定位,故障恢复时需要人工校验恢复,那整个架构必然是存在诸多问题的。
客户所使用到的绝大部分都是云服务,每个云服务本身的高可用如何做的你真的都知道吗?而每个云服务官方所述的高可用能力是否和客户的期望能够对齐呢?显然这个问题原先是被忽略的,对于云计算如果不太了解的工程师,常犯的一个错误是认为云产品本身的高可用能力由云厂商兜底。结合到真实的业务场景,这实际上是一句正确的废话,因为本质上每个云产品的高可用能力是没有办法完全对齐的,在实际过程中,往往会出现较大偏差,只有踩了坑知道痛了才能发现问题。
关于跨可用区网络延迟,这是一个绕不开的话题,只要有物理距离,网络延迟是必然的,而客观地说,客户提的问题并非无理取闹。在同可用区、跨可用区不同并发去请求业务应用接口,在去读写redis、数据库等,性能差异和理论差异是否有较大差异,实际上是需要有数据作为方案支撑的。
流量接入层该怎样去路由流量到两边的可用区。
业务服务层如何解决因跨可用区所带来的网络响应延迟。
数据层DRDS分布式数据库如果是以主备模式部署在两个可用区,那其中一个可用区在访问DRDS数据库时,响应延迟将会比同可用区调用的另一个可用区有显著增加。
方案一:一套SLB负载均衡器后接两套CSB网关,由SLB做权重比控制,CSB到EDAS的流量同东西向流量实现同可用区亲和性。
方案二:两个可用区CSB前各接一套独立的SLB,通过WAF对流量按比例分配,CSB到EDAS的流量同东西向流量实现同可用区亲和性。
方案三:放弃CSB到EDAS的南北向流量同可用区亲和性,WAF对访问流量不做任何流量比例规则限制。
在查阅了CSB产品的相关文档之后,发现原来CSB网关可以支持接多套SLB,但SLB后端无法接入多套CSB网关。因此也就在方案二和方案三之间进行权衡。考虑到在真实的业务场景下,南北向流量和东西向流量完全同比实际上很难做到,而CSB到EDAS的路由亲和性最多只能带来减少1-2次的跨可用区调用,效果十分有限,另一方面用户还要对WAF的后端流量比例进行定义,增加了管理上的复杂度。因此在权衡利弊之后,我们选择了方案三。
在整个架构蓝图基本成形之后,又有一个新的问题需要解决。无论是在日常1:1部署实例,还是在大促活动时以8:2的比例将pod部署在两个可用区。kubernetes的部署逻辑并不会像业务应用部署在指定服务器一样,而是会基于其调度器将pod实例部署在满足条件的可用区。在极端情况下,完全会出现一个可用区完全没服务pod,或主可用区有1个pod,而在备可用区有9个pod的情况。在这类场景下,性能不仅无法提升,还会造成部分服务负载过高影响业务的稳定性。尤其客户在每次大促过程中和接受,都会对其应用和底层资源进行扩缩容动作。
Kubernetes虽然支持Pod和Node级别的亲和性和反亲和性策略,但都还差点意思。在一次真正的扩缩容过程中,让用户每次都对Node节点打标,大量的人工介入在整个部署流程中,这几乎是不可接受的。
为此,又继续查阅起了文档,这就要用到接下来讲的 Kuberentes内置特性,topologyKey 了。
顾名思义,topology 就是 拓扑 的意思,这里指的是一个拓扑域,是指一个范围的概念,比如一个Node、一个机柜、一个机房或者是一个地区(如杭州、上海)等,实际上对应的还是 Node 上的标签。这里的 topologyKey 对应的是Node上的标签的 Key(没有Value),可以看出,其实 topologyKey 就是用于筛选Node 的。通过这种方式,我们就可以将各个 Pod 进行跨集群、跨机房、跨地区的调度了。
topologKey不同于nodeAffinity参数来说,提供的是一种软亲和的部署能力,pod在做跨地区、跨机房的部署过程,会尽可能的按比例将pod节点在不同机房部署。当底层ECS计算资源在两个可用区1:1,且资源充足时,K8s调度器则会将pod按照1比1的比例均匀部署在两个可用区,同样的如果底层计算资源是8:2,或者是7:3,pod节点也尽可能按照比例对底层计算池打分,并计算部署在哪个可用区的ECS实例上。
但有了topologyKey这一大神器之后,并不是说部署过程就完全高枕无忧了。在一次应用上线的版本发布日中,在一两个小时内上线几十甚至几百个服务是十分常见的事情。K8s的滚动升级机制,则是先部署一个新版本的实例,然后在注销一个。因此当底层预留计算资源不足时,即便是设置了topologyKey,依然会出现实例分配不均的情况。为此,EDAS-ASK(阿里云kubernetes托管服务)必须提供给用户能够查询到不同可用区部署情况的API接口。此外,在扩缩容或者发布时,pod没有按预期部署至多个可用区,也需要提供给用户一个能够校正pod实例分布情况的重启应用功能,以便于用户判断在业务低谷时重启实例节点。
至此,架构整体的设计基本达到客户的预期。剩下的就是云产品自身的功能迭代了。
每个客户要解决的问题是不同的,首要做的事情必须是对客户的业务场景、技术架构上下文全面了解。不要遗漏链路的任一一环。
明确了用户所使用到的服务组件及架构之后,云产品的高可用级别、性能等要素是务必要都研究透彻的。
前提和用户对齐目标投入预算,其中包含了优化后的资源成本的增长、开发成本以及后期运维成本。
故障恢复时间,实际上阿里云上关于故障恢复有许多方案可控选择,最简单的流量切换方式可以基于DNS(10分钟内恢复90%流量),也可以基于MSHA(秒级)实现同城多活、异地容灾等大型容灾架构。但每种方案涉及到的成本、系统复杂度也各不相同。
以上是关于一次高可用架构设计实战总结的主要内容,如果未能解决你的问题,请参考以下文章