竹庄:弹性伸缩对于优秀的架构设计的支持
11月21日,阿里云“弹性计算技术专场”活动在深圳举行。原计划200人的会场接待实际到场观众接近300人,很多观众站在过道上或席地而坐,津津有味地听完整场分享。参会者还与讲师积极互动,现场气氛非常火爆。应广大用户要求,我们将讲师现场分享内容整理出来,供大家参考。
以下为讲师邓明鉴(花名:竹庄)的分享内容:
大家好,我叫邓明鉴,以前我一直是负责阿里巴巴内部的hbase系统,包括之前做Hadoop方面的运维和支持,这次给大家分享弹性伸缩服务,这也是阿里云刚开始的服务,也是我们10月份才发布的。接着刚才马涛一个话题,刚才有个问题,有个同学说openstack社区,为什么我们不采用这个技术,或者评价它的一些比较,因为我以前有五年的时间是在Hadoop hbase社区工作,也看到了一些问题,这样的开源社区确实是很美好的,我们一开始在上面也有很多借鉴别人的工作成果,自己也会跟他们做一些分享,时间长了这种用户增加的话,开源社区会走向一个趋势,大的厂商之间,相互之间的利益就会产生一些冲突,导致每个大厂商其实都在开源版本上做自己的一些版本,到后面很难再一些回馈等,比如网上提交一个功能,但是用户多了,有的人觉得这个功能不实用,不适合在别的系统,这样会导致它的进展越来越慢。一开始是Hadoop社区大概在2012年的时候大概已经走入这个趋势,Hbase社区活跃了三年以后在2014年差不多也走入了这个趋势,版本发展变得越来越慢,新的功能增加会导致大的像现在的Hbase跟Facebook、cloudera和hortonworks他们都自己走自己的版本,相互之间的交流越来越少。
但是在开始的时候这确实是有很大的优势,我相信openstack现在也会对很多很多的公有云的社区会有相当大的帮助,阿里云也走了自己的一条道路。我今天讲的可能跟前面两位同学有些不一样,因为我更多是做一些服务性的工作,就是在这个集群的技术架构之上,因为我们有些思考,到底我们觉得公有云的核心优势在哪里,很多人会认为优势就是两个,一个是在成本上,另外一个是在运维上。从成本来说如果公有云发展的越来越大的话,大规模的采购和部署会降低单机的成本,另外随着技术的发展,服务能力,超卖能力的提升也会进一步降低成本,这个甚至有人提出随着机器规模和超卖能力到了一定程度的时候公有云上面iaas层的资源成本会接近于零,然后灵活的一些弹性伸缩像亚马逊的做法,可以让用户在不同的时间段,把用户平均分在每个时间片上,然后导致我们的成本也会变得越来越低。这是从资源上的。
另外我们从运维上来看,大家可以都有很深的体会,一个网站从零开始到一千万或者上亿的用户,基础架构的难度上升不是一个线性的,是一个指数上升程度,所以你运维能力的要求会非常的高。像淘宝或者支付宝这样的公司,从一开始几个人就可以运维,或者一个人就可以运维,到后面每一年运维人员的上升都不是一个直线性的,都是一个指数上升的阶段,并且这些人员的经验和技术的积累都是一个很长期的过程。所以很难说当整个社会的计算能力都是普遍需求的时候,很难让每一家公司,每个企业都有这样高的运维能力和统一的运维标准。
所以需要公有云统一的运维标准和专业的人员来降低整个运维的成本,提高安全的门槛。包括在这个基础之上,用他们自己的一些经验,开发出相应的自动化运维产品,来提升整个把每个企业的运维能力都提升到一定的程度,这样的话可以,当然这个在通用性上会受到一些挑战,比方说我制定的一套运维标准,可能并不符合某些企业的运维标准,或者在一些特点上有相互的冲突。但从社会整体来说,比如说有一千个公司如果很难去需要两千个运维人员,因为每个公司平均要两个运维人员的话,如果有一个公有云用一百个运维人员就可以为他们服务的话,整个运维成本是降低很多的。
我们在4月份的时候已经有这样的思考,我们怎么样来放大公有云的优势,后面在iaas的基础之上提供一些更多往(pass)层发展的一些服务,从成本来说,当时我们在4月份的时候,或者更高的时候,通过数据分析发现我们绝大部分用户采用的是包月包年的方式,当然这也是阿里云自己的一种方式。我把服务器按月或者按年买下来之后,我的成本会比较低,然后从用户的角度来说,他只能够提前一段时间去购买他的服务器,把服务器放在那,过一段时间把服务部署上去,这样可以提供应用。这是从成本来说,从业界来说,亚马逊已经没有这个概念了,亚马逊所有的服务器都是资源在使用的时候才去购买,所以这样一种方式不符合绝大部分用户的使用习惯。
目前这个阶段还是很有市场的,只是说从未来考虑的话,可能不太符合一些用户的使用习惯,我们需要去把这个方向逐渐的优化,比如说这样一个图,很多用户现在都是这样的,我先申请一批资源放在那里,比方说SLB或者是带宽或者是VM资源放在阿里,不管我的业务规模是怎样的,我有这样一个高峰期和低谷期,我都需要把这个资源放在这里。有些用户是这样的,先申请一部分业务资源,当我的业务上去之后就会申请更多的资源,然后再部署我的应用。
在曲线向这个地方,这一段会有不好的用户体验,有个时间差,部署完系统可能才会去满足当前的业务需求,这个用户方向用同一条曲线,需求和资源我们希望尽量地趋近而不是有一个提前部署的阶段。我们当时是这样一个思考,刚才说从成本方面考虑,从另外一方面考虑的话,我们当时是觉得因为淘宝也是一路走过来很多年,运维人员是公司里面非常辛苦的一批人员,他可能比开发人员更加辛苦,因为他根本没有时间,他需要随时随地盯紧监控,随时会收到报警,他们可能会出差或者半夜的时候都会去做这样的事情。业内的人都知道运维人员最苦的工作,这个工作不符合一个人性的要求,我需要把人像机器一样去盯着这个系统,在业务峰值的时候,就像淘宝的每年“双11”可能在那个时候需要有很多人加班,这种加班对运维人员要求是非常高的,甚至可能导致出错的情况,可能很多人都没有时间去休假。比如需要在最紧张的时候,双11的时候正好遇到我家里孩子出生,类似这样的事情,都是很苦的事情。在公有云现有阶段的话,可能需要你盯紧控制台,比如说你的阿里云服务器可能在控制台上去做一些临时性的处理,这些处理可能对运维人员,一个公司的运维人员都是比较头疼的事情。刚才一位同学说,我有一百台机器,这里面怎么样高效地去运维那一百台机器,仅仅通过一个web页面可能是比较困难的一件事情。
像这些都是一些比较典型的运维的场景,可能在各个场合我都需要去,可能在专业运维都了解到,我在各个场合,必须在一分钟,30秒之内做出反映,在各种场合我都需要带上电脑,带上我的vpn然后去做一些操作。这就是控制台的页面,可能我需要再随时随地通过这样一个控制台,然后去做一些操作,这些都是比较痛苦的,这样的话我们就得有些思考,到底我们将来是希望IT的运维或者说我们的运维应该是什么样子,首先用户应该只关心核心问题,只关心业务,只关心程序的逻辑和数据,不需要去关注资源,资源这个事情是把公有云把这个事情给解决掉的事情,因为大家都是用同一个公司,或者说少量公司运维平台的一些服务器,不应该去关心资源怎么去申请,什么去部署,而我只需要关心我核心的业务和数据就可以了,因为这才是每个公司差异化所在,这个东西应该是作为标准化的东西。
我们也看到亚马逊也有这样一个路线,亚马逊早在2010年就已经推出了一个产品autoscaling,我可以自动化地弹性伸缩做一些事情,把我的VM做一些增长或者减少,后来又增加了cloudformation可以自动化地部署很多服务器,然后最近推出了opsworks在部署人机上部署的进一步灵活了,直到前几天推出了lambda,在产品发布会上他们提出的核心观念跟我们很相象,我们觉得用户关心业务、逻辑、数据这些东西,lambda当然也提出我们的客户应该只关心三样东西,事件、逻辑和数据三个东西。每一个在公有云上的业务应该只关心这个东西,而不应该关心资源,因为资源是一个标准化的东西,在我们之前的所有公司程序类服务的时候都是有一个趋势,业务或者说你的程序再去追逐资源。先有资源,然后我的程序或者我的计算是去放到资源上去部署使用的。未来应该是资源去追逐业务,我有业务当业务有需要的时候资源自动就有了,而不是我先把资源部署好再考虑业务怎么去放置,未来应该把业务追逐资源向资源追逐业务这个方向去发展。
所以我们就会有这样的一个东西,在10月份发布了弹性伸缩服务,当然只是我们目前的第一步,我们第一步能够把这个方向,刚才说到这样不好的东西,像把资源和需求像趋近的这样一种事情来做,能够做到自动化的程度,而不是通过这两种方式来达到不好的业务体验。我们是希望资源能够按需的变化,希望运维能够往自动化方向趋近这是我们目前弹性伸缩服务目前想做的事情,当然后面可能还有更加自动化的事情。
说到弹性伸缩服务的话,当时我们发布一段时间就发现,有些适用的用户,也产生了一些困惑,很多用户觉得当我资源不够的时候,为什么不能够帮我把2核4G调成4核8G这样的一些事情,我们也说这个东西就是业界的两个方向,Scale up与Scale out,一个是垂直化的扩展,一个水平化扩展的问题。资源不够的时候能够把CPU内存磁盘资源能够往垂直化的方向提升,这有点像数据库里面,把数据库做得更大。而不是说像这样分布式的,在业务上来说应该是水平扩展的能力,要求用户的业务都是无状态的,在无状态的情况下,可以把业务不断地复制,复制之后让他们分别去承受一部分的业务,这是水平扩展能力。这是两种扩展模式,我们目前阿里云发布的也是后面这种模式,水平扩展的能力,前面这种垂直扩展的话最严重的问题我业务需要去重启,或者需要迁移,业务或者数据发生迁移来达到这样的目的。在后面这种情况业务连续性不会受到影响,不管是增加还是减少,连续性是一致的,不会受到大的影响。我们都希望用户增长是这样的,在这样的情况下,很多经历这样的,高增长的公司都会了解到网站的复杂性程度是指数上升的,我的网站需要不停地去更新业务架构来支撑这样一个业务形式。
但实际上一些最基本的东西现在已经可以自动化做到了,至少网站的服务能力,在无状态的节点上可以做到水平把资源往上加,达到这样的目的,比如说论坛就可以达到。这种方式必须采用横向扩展的模式,纵向扩展再怎么也只有个位数的能力上升,这个是可以达到成百上千倍的网站规模上升的,是可以支撑这样一个模式的,比如说你当一千万用户增长,现在绝大部分都是公司创业,用户的目的就是向一百万到一千万这样一个目标迈进的。这样的增长我觉得水平扩展模式才是他必须要去拥有的。当你有一个水平扩展能力之后就可以采用一些自动化的产品让你的网站在公有云上有个自动化的部署和运维,最大化地减少运维成本以及你的资源成本。
但是像这样的模式我们觉得需要三个要素的,像公有云我们希望有三个要素才能支撑业务的成长。第一个是公有云的资源必须是按量计费,阿里云目前还是按小时计费的。我们未来肯定都是计费模式会越来越精细的,这个并不是核心的东西。服务器首先我们需要按资源计费,流量带宽的资源也是需要按量付费的包括像DP或者缓存,连接数之类的东西,都是需要支持按量计费的,只有支持了按量计费我们才能够做弹性的伸缩。
公有云的产品我们第二步是希望拥有完整和强壮的OpenAPI体系,所有的服务不仅是通过网页,能够通过API,开放出去了API来提供服务,比如VM资源,数据库资源,缓存、SLB这样的资源全部都拥有完善的Open API体系,这个Open API接口是能够被用户快速运用,并且他们是健壮的,返回的信息码,错误码都是有明确语义的,在各种各样复杂的情况下都没有歧异的,这个是很难做的。因为我们今天的网络情况非常复杂,可能会发生各种各样的问题,在不同的问题我能的错误码或者是信息码返回值都是明确的,这个是我们希望拥有的完善的健壮的Open API体系,而且我的功能上是需要能全方面覆盖的,并且是拥有比较强的隔离能力,用户反复调用结果都是可预期的。并且刚才说到的用户的应用自身需要水平扩展能力,当有这三个要素以后,我们就可以设计出弹性伸缩的服务。当然现在我们简单介绍一下前段时间发布的弹性伸缩服务,这只是目前发布的第一个产品。后面会发布越来越多的自动化产品。
弹性伸缩服务,在阿里云目前是ESS(Elastic Scaling Service),只是根据用户的需求和策略来自动调整用户的资源,并且能够对他的资源进行分组自动化的管理。我们在用户业务增长或者降低的时候,增加或者减少他的VM实例数,并且将这些实例进行一些自动化的配置,比方说配到SLB里面去,比方说在RDS的白名单里面去增加或者减少。类似这样的一些服务,或者说授权这样的事情。我们CPU达到一定程度的时候会加一些机器,或者当CPU降低到一定程度的时候我会减少一些,这是反馈系统,反馈最关键的是有个监控系统,能够通过监控系统知道这个东西。这只是简单介绍,当我发现CPU用户率突破80%的时候会增加一台机器,这是简单的模型。我们目前发布的产品除了刚才这种动态的模式,像监控模式以外,另外一些比较实用的模式,有定时模式、固定模式。定时模式就比方说业务在某个时间点有一个峰值或者某个时间点是不需要的时候可以配置一个策略去定时增加或者减少。
最终用户使用的都一定是多模式的组合,把多个模式放在一起进行自由组合的。之前一些典型的应用场景,比方说游戏公司每天中午12点要打怪他需要去定时扩容,不需要为了12点去增加这么多的机器。电商公司在每年比方说类似双11这样的时间点上促销需要临时增加服务器数目,可能需要负载的模式来自动调整弹性伸缩的策略,视频网站公司也是,有视频会议或者转码任务的时候可以通过CPU的利用率自动计算出我需要多少的机器来自动地做一些工作。搜索公司的话是用弹性伸缩作为部署手段,始终保持实例的固定数量。因为有一些异常情况中断服务了比如说到期了或者其他情况,通过我们的配置让它的机器使用保持恒定,这是典型的应用场景。
这里有个图是介绍了整个目前发布的弹性伸缩服务工作原理,这个可能现在分辨率不够高,后面的看不清楚,大家可以通过PPT来下载一下,我们发现有一些,刚才提到这个问题,用到的技术都是开源,发布出来的产品我们也可以自己去搭建这样的产品,发布这个产品只是抛砖引玉。因为不是每个企业都可以自己去做这样的东西,而且大家做的标准化程度也不一样,后面也会提到这里面有一些问题可能需要我们阿里云自己去做这样的服务,会更好一点。
第一步需要配置一个伸缩组,配置完伸缩组以后通过监控程序,发现达到阈值之后可以做一些自动化的处理。当自动化处理完成以后比较重要的一步在后期我需要把这些东西加上SLB里面去,按照一定的顺序加到SLB里面把它启动,然后再通过一些Open API把流量引入进来,搞一个业务无缝的扩展或者说减少的程度,这是目前能做的事情。这是我们自己内部的一个系统架构,从一开始是自己设计的,跟Open API或者跟亚马逊的设计都不太一样,我们这边有一个协调器,前面是接收请求层,因为我们也发布了Open API,通过API可以请求服务,或者通过在网站上产品的控制台去访问服务,在服务所有的请求,在协调里面去做一些判断处理,这里面有一个独立的触发器,比方说定制器,监控,健康检查的一些触发器,这些触发器会分别独立地去做一些事情,然后来检查有没有达到活动发生的(阈值),发生阈值之后会通过前面的请求然后去决定是不是要把请求分发下去。然后这边所有的请求它都会去做一个工作,在这一层是无状态的,每个worker只管接收到请求就去干活,他不用做任何的判断。下面就是把我们用户分到不同的伸缩组里面去,这伸缩组是用户自己定义的,我们可能会有很多很多这样的伸缩组。每个伸缩组里面让它的业务会在一定范围内进行波动,这些波动都会体现在前面的SLB,存储上面做一个自动化的弹性的服务。我的伸缩组可能没有数据库,也可能没有前端的SLB的,都是有可能的。
在调用的时候,这是程序里面的图,前面还是说Open API和控制层发到我们这边来,API服务会有一个订阅,下面会通过自己的ESS自身,下面是其他产品,帮助用户去做判断调用其他产品的API层,我们需要非常强健的Open API体系,有了Open API体系之后我们自身才能发挥作用。这里面会和这面的鉴权系统进行一些交互,然后判断用户有没有权限做这样的事情。刚才说到设计的核心,必须要做到能够定时或者自定义监控的触发器来触发一些事件,这些事件是由用户来定义的,刚才只说到了CPU。然后我们还有自定义的接口,用户可以接入任意的条件,比如连接数。然后在有触发器以后就会根据用户时间定义的配置进行资源的选择,比方说用户要做一个负载均衡,可能需要所有的服务器都需要同一个配置,否则不知道流量怎么分配,包括资源如何进行创建和启动,以及最后把所有的环境都配置好,像这几个规划全部是自动完成,相当于节省用户运维的一些事情。
用这个东西伸缩组可以完成自己的业务,而不需要再自己去ESS支撑控制台上去做一些事情,你定义了伸缩组就是定义业务组,可以在这个业务组里面管理你的这个应用所使用的所有资源。但是这里面有一些问题,比方说我们在设计的时候必须深刻理解各个产品的Open API,必须清楚他们的语义,他们是同步的还是异步的,他们返回值是怎样的,不同的异常的语义都必须要一清晰地理解。再加上对它的状态机的理解才能够设计出这样一套系统。如果用户需要自己设计的时候,需要对这些东西进行深刻的了解。因为你只有知道了一个资源,比方说一个ECS它整个状态机的机制,然后在每个状态会发出什么样的返回值,自动化地运维系统。否则你可能需要一个东西,在某些自动化的场合下,比如说某些异常的场合下会出错,今天我找不到机器,但是你认为找不到机器就是vm挂了,这显然不是合适的解释,类似这样的一些状态需要对它进行非常清晰地理解,才能够做一个自动化的事情,否则用户是不会放心交给一个自动化机器的。
我们需要精确地让活动去触发,我们是公有化的平台上面对应是很多的用户,每个用户的需求都是不一样,这是可能很多做公有云的同学跟做私有云的很不同之处,用户的需求通常是相互矛盾的,你怎么样去做一个触发器,你认为什么样的需求是用户真正的需求,产品需要去做深挖。在这个基础之上,用户的伸缩活动,比方说假设说你增加了一台机器是增加错了,这样会浪费用户的钱,如果删除一下,删除错了有可能会让用户的业务受到影响,甚至会让他的数据发生丢失,这是非常危险的事情。一个自动化的系统需要去做这样的事情,就需要考虑非常全面,然后在产品设计上也需要去了解什么是用户的需求,什么是所谓的用户需求,用户需求和所谓的用户需求是两种东西,有的用户可能会说我需要一个什么什么东西,但其实不是这样子的。他其实要的是另外一个东西。
对于活动失败,这个是最难处理的事情,在处理的时候,失败的时候做了什么样的事后处理,这也是需要去考虑的事情,在设计的时候会遇到这样的问题。
做所有的事情对用户的业务都需要去透明的,比方说你从SLB里面去加一台机器不能影响用户已有的连接的请求,比如活的连接,等它死掉以后才能去做一些工作,这都是我们需要妥善考虑的问题。
我们在10月份发布了这样的产品,在这背后我们有很深的思考的,能够让我们的服务,让用户降低使用成本和运维成本,这是我们设计的初衷,后面会在这个方向上做更多的一些努力。下面只是简单做产品的一些演示。当我们发现性能发生问题的时候会去增加一台机器,这是简单的适应,增加机器的过程是这样的,通过监控发现这个用户这一组机器的平均负载过高的时候,会在资源池里面添加一台机器,添加一台机器进去以后,添加这个机器的动作本身是有监控触发的,监控在计算达到一定阈值的时候会触发一个请求,这个请求是到产品这边,产品就会发到coordinator那一层,会分发请求,把这个服务器添加进来,当然添加也会有失败的情况。最终完成的时候,会增加一个机器,这时候负载不会发生变化,但是我们在一定时间内不会计算负载变化情况,你应用起来有一个热加载的过程,这个加载过程本身是有时间的。在完成以后,比方说负载率降低了把这台机器减少,这是自动化的过程。
还有一个更强健过程,正在运行的机器里面有一台机器挂掉了,这个不一定是挂掉了,准确说我们通过TCP发现它的端口不通了,这是TCP发生的问题,这个就涉及到比如说你欠费了这样的问题,它会自动追加一台机器进来,让我的实例数是一致的。这些东西是可以用户配置的,这个配置大家可以上产品上面看一下,一分钟要不了就知道所有的配置应该怎么做。后面演示比较简单,这边网络情况不太好,没有做现场的演示。把它存储放在OSS的产品上面的,后面会增加更多的阿里云产品,如果用户增加的话还会增加docker支持的,因为dorker比刚才那种方式更好,我们所有的业务增加一个实例的话,是通过一个镜像去复制你的实例。把业务放在一个image里面去,每次启动的时候通过这个image来启动,镜像有个问题,不能够去频繁使用,因为每次是很费IO的过程,并且也是很漫长的过程,而且它还可能会发生变化。而docker则可以看作是动态变化的image,当服务发生变化的时候,能够及时更新,包括你原先的那些实例也能够实时变成新的代码。不过docker也有一些问题,比如安全性,需要VM去保证它的安全性。这边的介绍暂时到这里。