数人云|90%产品服务化,细说豆瓣的5年变革之路

背景

今天主要分享下微服务中的Auto Scale,豆瓣2005年3月上线,是一家历史比较悠久的互联网公司,主要覆盖文化综合领域的Web、APP等各类产品,如今有豆瓣读书、豆瓣电影、豆瓣音乐等等。数据库

Markdown

〓 豆瓣简介

在技术方面,豆瓣主要的开发语言是Python和Golang,豆瓣拥有自研私有云平台Douban App Engine(如下简称“DAE”),上面托管豆瓣网全部应用使用配置来描述应用:应用依赖MQ、Daemon,以及Cron,这样开发者使用一个配置文件就能够描述对资源的全部需求,平台拿到描述文件后能够在上面作须要的资源管配。服务器

Markdown

〓 Douban App Engine

在DAE上会统一调度全部资源,产品开发人员没必要关心具体的机器设备,好比无需关心某个业务线须要配备多少台物理机器,全部资源由平台统一调配,全部开发流程,从提交PR到测试,上线是一套统一流程。运维

Markdown

〓 现状

豆瓣从2012年开始作服务化,主要由于随着产品线愈来愈多,单体应用已经没法知足豆瓣对开发效率的需求,所以,2012年起逐步开始拆分整个网站,截止2016年末,90%以上的产品已经完成产品服务化,因为前期准备充分,这个过程当中整个网站性能没有发生变化,没有由于作了服务化致使性能上的降低,全栈可用性获得提高,不会由于新入职同事作了一个不太成功的提交,而致使全栈挂掉,发布也由每日发布变为按需随时发布,服务化后,全部上线流程由各个业务线自行控制。微服务

回归今天的主题,为何豆瓣要作Auto Scale,作了微服务的公司内部各个系统之间会造成很是多的依赖,微服务化以后,整个系统结构很难用层次化的模型来描述,呈现出来的是一个复杂的网状依赖关系,大量应用相互之间有交错的依赖。工具

目标

Markdown

这里有个问题,单体应用时,运维人员部署应用其实很是简单,在一台机器上将应用部署完毕,按照机器的性能部署相应的进程,当请求过来处理能力不足时,直接加服务器。oop

微服务化以后,运维人员手里有大量的微服务,每一个服务的请求量和性能都不一样,运维很难手工维持每一个具体的应用须要多少计算资源,这就带来一个问题:怎样可以让应用既能跑得好又跑的省,若是每一个应用都给予足够多的资源,这显然不是一个经济的方式,迫切须要一个既能提升服务器利用率,又能提升自动化的方式。性能

Markdown

〓 服务化以前的方式

豆瓣微服务的时间起始于2013年12月,由于过早,如今流行的一些开源技术当时尚未用到,2014年2月,开始进行简单的场内线上应用,3月,已经能够接管部署在平台上的140多个应用。公司处在服务化进程中,当时只有一小部分应用部署了微服务享受到Auto Scale带来的好处。测试

14年3月,Docker还没出来,豆瓣此时是一家纯Python的公司,用Python作应用打包,2014年下半年,开始发现Docker的巨大优点,因而作了整个平台的Docker改造,2015年Q2完成总体Docker化改造。优化

整个AutoScale的发展是从前面提到的140个应用开始,随着服务化推荐,持续优化性能,提升稳定性,目前整个平台上500个托管应用都在Auto Scale之下。网站

Markdown

〓 DAE Scale模型

一个Git Repo映射到DAE平台上的资源分配、调度、计费和逻辑集合,每一个应用全局惟一且相互独立,经过thrift/pidl/http RPC相互调用,对于Web和Service服务,豆瓣支持Multi-instances,好比一个应用既须要有Web页面,也须要Thrift服务,能够用一份代码起两个不一样服务,其中Web服务主要服务天天来自外部用户的访问,Thrift Service是内部调用,量级比外部访问大很得多,Auto Scale提供一个机制,经过配置把两个Instance分拆开,Austo Scale提供一直机制,经过配置将两个Instance分拆开,分别作Scale。

Markdown

DAE Scale是多进程模型,每一个请求由一个进程来处理,整个系统能够理解为Worker的总数和应用服务处理能力直接相关,Node是物理机,有些Node会部署一个应用,有的部署若干个应用,从平台资源调度来看,全部无状态节点都是均等的,差异主要在CPU和Mem方面,Node和APP之间是多对多的关系,每一个APP在每一个Node里面有多少Worker(工做进程),是Auto Scale的关键,会放到数据库里。

Markdown

从理论上来讲,全部应用都是平等的,但有些应用相比其余应用重要度更低,须要物理层面的硬隔离,Pool就是一组节点,在被分隔开的若干个Pool中,有的Pool是公司内部的小应用,只需作有限支持,计算资源很是受限,对外较重要的应用分红两级,Production Pool和Stable Pool以及一些很是重要的应用,是公司的核心产品,它们会单独用本身的资源,另外,有些部门有本身的计算资源,但愿用到平台调动的机制,这种状况部门能够将本身的计算资源贡献出来单独有一个Pool。

Markdown

上图是整个Auto Scale结构,最下面的节点上有Monitor,会采集借点上面各类性能指标,包括Memory、CPU、Load、当前进程的繁忙程度,采集以后发到若干地方,主要用来给监控人员查看,在Auto Scale的应用中,其实它的性能还不够好,因此通常会存一份数据Redis里面,到了Redis以后,整合的数据称做Bridge,在Bridge节点上面采集的数据进一步加工封装出一些API,包括关于APP、Node、以及Pool的API。全部应用Scale各类策略的配置都在这个应用里作。

真正作Auto Scale策略的应用是DAE Scale,Scale这一块会有若干个Cron Job,作相应的事情,好比APP的Auto Scale,Web Auto Scale、真正去Scale他们的Worker,里面会配置一系列的策略,对于Pool,豆瓣最核心的几个应用,计算资源也是共享的,Movie、Group和SNS是豆瓣最核心的三个业务,会独占一个Pool,但天天须要Pool中的多少节点,是一个动态调整的过程,会有专门的Pool作弹性伸缩。

在Scale里作完运算,下一步要么Scale UP到某一个APP,要么Scale Down某个APP,或把一个APP从一个节点挪到另外一个节点,或者把一个APP在某个节点上放上去或拿掉,Scale产生这些行为,最后落地又回到节点上,节点上面有一些工具暴露API,让Scale回到节点上面来,这样将整个流程串起来。

外部应用更新完毕后,会更改Nginx的配置,不一样节点同一应用的触点不一样,配置反应不一样的权重,处理能力强的节点拿到的请求更多,能力弱的节点拿到的请求少一些,这就是Scale总体的结构。

Markdown

〓 采集数据

关于采集数据,豆瓣是多进程模型,怎么去判断这个进程在工做没有呢?是去数,每一个进程在运行以前会作一个标记,完成后这个标记会删掉,Monitor会到这个机器上数,这台机器上有多少个Worker,多少标记,标书就是正在忙的节点,正在忙的进程,这里有一个小技巧,标记放在内存盘上,它的系统上就看不到了。

Markdown

〓 Scale应用策略

整个APP Scale有两种策略,一是每一个应用Instance如今有多少个进程在忙,须要有一个策略来计算,到底须要多少进程,豆瓣尝试过若干策略,好比Noop,有的应用不须要Scale,配几个进程就够了,不须要Scale,不须要干涉,但busy_ratio_mark_cnt是须要干涉的,rps_ratio能够根据应用的具体请求量和响应时间计算出来,当前应该还需多少个Worker。

还有一个Ondemand_rps进程,Auto Scale基于的假设是,全部请求都是一个逐步增加和减小过程,但有特例,好比APP作一次大规模推送,或上一个广告,这时有预期推送后或广告放出去后,会有大量的回放上来,此时Auto Scale的曲线型就会比较明显,由于它没办法与指导RPS陡然的上涨,豆瓣处理方式是给Scale提供一个API,将主动权交回给应用开发者,让他按照推送的规模,估计大概的规模,平均回访率,反馈到Scale后,Scale会作一个快速拉起动做,立刻将须要的进程涨上去维持一段时间,等待请求过来,而后随着请求过去再慢慢Down下去。

Ondemand_rps还有一点经验,就是须要有一个大概预估的时间,Scale上去后,若是请求还没来,那么Auto Scale会很快介入,若是仍是没有足够请求它会开始往下Down,好比保持半个小时,这是一个产品经验值,若是半小时请求还没来,可能此次就不会有那么强的请求了。

Markdown

关于哪些节点加进程,有两个策略:一个是彻底equal,好比某个应用在5个节点上须要20个进程,每一个节点作4个,绝对均衡,有的应用要求每一个节点处理能力是至关的,可是,更多的节点容许不一样的节点上处理能力不同,这个前提下会稍微保证节点之间不要差的太多,某些处理能力强的节点也不会拿到太多进程,好比将80%的请求都放在一个节点,若是那个节点有问题,就会都有问题,而应该是当某个节点宕掉,当期那的冗余度可以Cover宕掉的问题。

Markdown

每一个应用会作一个配置,这个应用最小须要多少节点,各个应用不同,有大的需求得更高,好比至少10个节点,有的应用两个节点就能够了,这也是经过Scale确保上面作这些操做不会破坏掉最低的要求。

因此整个Scale核心诉求是,调整总Worker以及到每一个节点上面去调进程,在工程上有时会将VIP和普通分开,若是某一次Scale卡住,好比迟早高峰,会有相应的报警,若是那个时候没有把处理能力加上去,极可能会出大面积的问题。

Scale一些基本的策略,在加Worker时必定要快,请求来的时候要很是快的响应,但减的时候须要慢,若是很快减掉了,可能系统会颠簸比较厉害,另外,节点之间分配杜绝过于不均,后期简单算一下各个节点之间的标准差距,看是否是差的太远。

还有一个维度,从节点的角度看,须要同一个Pool里面平衡各个节点的负载,在同一个Pool的节点之间作均衡,平衡主要看CPU、存储、能够优先把Worker较小的应用拿掉,留下一些比较大的Worker,过一段时间Scale趋于稳定后,会发现有些访问量很大,一些应用慢慢会独占一些节点,这也是IT人员但愿看到的状况。

对于VIP的Pool,它们会有一个弹性池子的概念,也有一个Freed Pool,咱们目前闲置的资源都是Free Pool里,当VIP Pool有资源的需求的话它会从Free Pool里面拿,Load下去以后它会还回去,在这几个大的VIPPool之间,实际上是共享整个计算资源的,主要的考虑也是各个产品用户访问Pattern不太有同样,有的产品白天访问量比较高,晚上比较低,有的则反之,同一组机器其实经过机制调度可以用的更充分一些。

Markdown

〓 监控

Auto Scale是一个完整自动化的工具,豆瓣围绕它作了不少监控,网站全部的资源调配都交给Auto Scale来管理,一旦Auto Scale出现任何卡顿,或其余状况,会产生很是大地问题,因此会有大量报警去看相关的事情,另外,Scale应用是5分钟作一个,频率更高意义并不大,会致使整个系统颠簸的太厉害,还须要提供足够的手工工具,当Auto Scale自己出现情况时,须要给运维人员提供充分的脚本,若是自动系统出现情况而不能人工干预是一件很是要命的事情。

有一些典型的状况,好比网站被DDOS,整个网站访问量直接Down到底,全部Worker都闲下来,这时Auto Scale开始介入工做,会逐渐把Worker往下调,DDOS过去以后这些Worker是不够的,因此当出现相似情况时,用手工的开关把它停掉,同时也须要强劲的LOG,这样在后续查找问题能够快速定位。

Markdown

〓 推而广之

作完App Auto Scale后推而广之发现,豆瓣有大量离线MQ Consumer,以前是产品开发人员来调配,应该调到多少是比较难以把控的,MQ的Auto Scale作下来发现和外部请求类不太同样,外部请求来了以后,不管响应与否,它很快就走掉了,但MQ来了以后就不会走,它会一直在那里,MQ可能会愈来愈长,还有一个以前作APP没有关注到的点——排队,队列在这时很是重要,须要看看队列是否是在增加,若是增加须要快速把Consumer加上来。

相关文章
相关标签/搜索