5月
09
2017

2017QCon分享:从淘宝到云端的高可用架构演进

写在前面:由于QCon现场分享时间只有40分钟,所以和最初的slides相比后来缩减了2/3,因此下文可能看起来会比较『跳跃』。

大家好,我今天分享的题目是《高可用实践:从淘宝到上云的差异》,取这个标题是因为会涉及到两个方面内容,一方面以淘宝为例子,传统的IDC的时候,我们稳定性是怎么做的,另外在云计算背景下,有很多创业公司是基于阿里云这样的公有云基础设施做研发,在公有云的环境下怎么做好我们系统的高可用。

高可用实践:从淘宝到上云的差异(终稿).004.png

长期做稳定性的人会有一些职业病,记得去年冬天有个周末,我要寄快递,穿着睡衣在门口填快递单,那时候我家里养了一只猫,因为怕猫跑出去,就把门关上了。寄完快递口袋一掏发现自己没带钥匙,冷静了3秒钟,打车到公司刚巧碰到同事,看我穿着睡衣来公司了问我什么情况,我说家里钥匙忘带被锁在门外面了,不过没事,我还有一把backup钥匙放在公司。生活中很多时候都需要有一个backup。

我的花名叫沐剑,2011年加入淘宝做评价系统,2012-2015年在店铺平台,负责店铺的前台浏览系统和后台的RPC服务,以及一些性能优化、双11保障的事情。到了2015年开始到了TAE团队,开始负责云端架构及整体高可用方案,TAE的升级版EWS现在也在聚石塔上面帮大量ISV和创业公司解决运维部署、自动化监控和性能分析等等问题。去年我是作为阿里商家事业部双11作战项目研发的PM。2017年我开始接手商家营销团队。在阿里五六年的经验,其实就做了几件事,比如连续五年参加了双十一的核心备战,然后像去IOE、异地多活,全链路压测、安全混合云、容器服务等项目参与设计和实施。

高可用实践:从淘宝到上云的差异(终稿).005.png

首先我会从淘宝店铺角度分享,以前在店铺是怎么样做双11保障的,后面是一些公有云相关的内容。这是一个淘宝的店铺系统,这套系统是一个非常典型的高并发的浏览系统,在前几年的双11峰值有20万次的Web页面请求,平均一个页面对应了20次的RPC调用,这个时候对于整个系统的集合来说每秒的QPS是400万次,这中间就会涉及到缓存、数据库以及其它二方的RPC调用,对于这样的系统来说,在性能、稳定性和体验间要做一个平衡,既不能纯用太多的机器死扛这个访问量,又要保障用户的体验。

高可用实践:从淘宝到上云的差异(终稿).006.png

从请求链路来说,首先DNS把CDN的VIP解析出来,分布在全球不同的区域,CDN回源到接入层分别经过4层和7层的负载均衡,近几年会发现CDN这个行业早已不仅仅局限做CSS/JS等静态资源的缓存,也承担了一些动态加速和收敛的特性,所以我们是通过CDN做域名收敛,收敛后会把这个流量发到统一接入层,然后到应用集群,后面再经过应用存储、Cache这些服务。

当我们在做稳定性的时候,会考虑性能和稳定性之间是什么关系,很多人认为这两者是冲突的,比如我要保障一个东西的性能非常高的时候,要牺牲掉很多别的东西,可能你要引入一个非常新的框架或者基础设施来提升性能,但它的稳定性可能是不那么成熟的,但是从容量规划的角度看,只有这套系统性能足够好,才能承担像双11那样的大访问量。

高可用实践:从淘宝到上云的差异(终稿).008.png

店铺也是一套经历了很多年的系统,在应用层上的优化基本上已经做到极致了,我们就转变思路,在操作系统层能不能做一些优化,这里借助了一个比较好的工具perf,在操作系统层面告诉你系统调用的开销是集中在哪里,从perf上就可以定位到有一个百分比,可以看到是比如数组分配还是GC产生了大量的开销。最初我们发现是异常带来的开销,就会看为什么这个系统的异常会导致20%以上的CPU开销,最后用BTrace跟了一下异常的构造函数,发现是我们依赖的开源的三方包里通过异常做控制流,每一次它处理结束的时候,就抛一个EOFException出来,这个就导致了非常大的开销,我们就把开源包替换掉了。当你依赖一些底层的东西的时候,如果对原理不太了解会给你带来一些意料之外的事情。JVM里是有一个常量池存储字符串常量的地方,就是一个哈希表,如果说这个表的大小不足够大,就会从哈希查询变成链表查询,性能就会特别低。

再谈一个warm up的问题,当我们应用刚刚启动的时候,还没有把字节码编译成native code,延迟非常高,用户就得到一个有损的服务。我们现在在内部的JVM做一个功能,会采集线上系统的调用,把热点方法收集下来做分析,在应用把真实流量挂上去之前,已经预先把所有的热点方法编译成native code保证这个性能。开源界也有其他的方案,比如Azul的Zing有个ReadyNow,IBM的J9有个AOT,也是做类似的事情。另外这里我放了一个Github的链接,这个agent能够让你在perf界面里直接看Java Method的开销。

高可用实践:从淘宝到上云的差异(终稿).010.png

谈到缓存,Cache里有一些小技巧,在做双十一备战时发现一个店铺的基础服务平时日常就每天有100亿的调用量,当时是几十台机器估了一下可能要成倍增长,成本是非常高的,怎么解决这个问题,当时写了个富客户端,让业务方先去查我们分布式Cache,如果命中就直接返回来,如果不命中再走我们的服务端查。这种情况下,只要你能够保证命中率足够高,比如98%的命中率,就意味着只有2%是需要后端服务器承担剩下的请求,用非常少的服务器去承担非常大的流量,这是成本和性能间的权衡。

高可用实践:从淘宝到上云的差异(终稿).013.png

高可用实践:从淘宝到上云的差异(终稿).016.png

在缓存方面,我们很少会关心缓存的高可用是怎么部署的,它是一个偏运维的内容,我把缓存的部署简化成一个双机房的模型,因为它在高可用里是最简单的场景。对于缓存来说有两种经典部署模式,第一种叫共享集群部署,在IDC里我的应用是分机房部署的,Cache集群也是分机房部署,对于应用服务器来说,两边的Cache对他来说逻辑上是一个集群,会往IDC 1的Cache写一半过去,往IDC 2也写一半过去,这种部署的好处在于,机房间网络断掉的时候,有一半的数据是在缓存的,保证一半的数据能够命中,不会直接死掉,另外对成本上相对比较友好,没有浪费任何一个Cache的节点,这个Cache本身是复用的。但是也正如刚才说的问题,如果中间断掉了,有一半的命中率是有损的,所以就诞生了另外的一个部署模式,就是独立部署,不管你哪个机房挂掉,命中率是基本不变的,两边同时保持了98%的命中率,但是它是成本不友好的,两边要同时部署,同时承担副本的作用,并且失效时,要同时失效另外一个IDC 2,这样才保证一致性。

在缓存上,我认为一切东西都可以被缓存的,通常我们认为缓存跟实际数据库里存在的东西可能是不一样的,有几毫秒的延迟或者怎么样,所以我们设计一个系统的时候,对一致性要求非常高的时候,会倾向于不用缓存,用数据库扛这个流量。但以MySQL为例,InnoDB里有一个很重要的缓存Buffer Pool,对于一个数据库,在冷库的情况下用一堆SQL去查它,和慢慢预热完再查它的时候效果是不一样的,这个是我们当初在做异地多活时面临的一个问题,例如我已经有一个机房,希望建立一个新单元去承担这个机房的流量,当我建完这个单元,把所有的应用都部署好了后,把流量切50%过来会怎么样,假设这两个单元的机器数一样,这个单元会挂,因为这个数据库是冷的,缓存是空的,不能承担之前那个单元数据库所能承担的QPS。

现在业界有很多叫API网关或者CDN,他们在边缘节点也做了一层短暂的Cache,可能只Cache 50或者100毫秒,但是当你系统受到攻击的时候可以拯救你后端的应用系统,攻击引发的命中率通常比较高,有这50毫秒的缓存,可能后端只有几百个QPS过来,那个流量你是可以承受的。

在高可用里两个非常经典的做法是限流和降级,在阿里双11,有一位老兵说过一句话,他说当双11到来的时候,任何一个系统都可能出问题,你要做的是对你的上游限流,对你的下游限流。怎么理解,当上流的流量超过你的能力的时候就要限流,当下游比如DBA告诉你数据库压力很大了,那就对下游限流,只要保证住这个限流,你基本不会挂,每个系统都做到这个的时候,整个系统都是可用的。当流量超出你掌控的时候,这个做法可以让你成为这个暴风下的幸存者。

高可用实践:从淘宝到上云的差异(终稿).019.png

对限流降级的思考,第一限流降级考验的是什么问题,我认为本质上考验的是故障自恢复能力,在平时工作中会遇到机房断网或者停电,每半个月都会做断网演练,不告诉你发生什么,就把这个网切断,看你的应用O不OK,一般是在晚上两三点,接到很多的机房报警,这个时候看你的架构设计的是否足够可用,如果足够可用就没问题,不会造成什么影响,继续睡觉,如果设计不好,就得爬起来立即处理。

高可用实践:从淘宝到上云的差异(终稿).021.png

而开关降级最大的作用,比如我们发现一些线上的问题,第一反映是赶紧回滚,但是当你的系统很大的时候,特别像Java这种,一个系统启动要启动几分钟,你的回滚完成,20分钟都过去了,这个过程对用户来说都是有损的,而开关可以在一瞬间把所有的逻辑切到老的。这个是避免回滚时间导致的问题。开关有的时候能救命,如果没有这个开关的话,避免问题放大就只能回滚,所以开关是一个很大的价值所在。

高可用实践:从淘宝到上云的差异(终稿).025.png

另外一点非常重要的是,在设计一个技术方案的时候,就会把容灾的设计融入到方案里。比如在设计技术方案的时候,在最后一章单独有一个容灾设计,这个节点里任何服务挂掉的时候,你要保持什么样的方式保持这个服务是可用的。

在容灾设计时有几点必须考虑,比如我引了一个新jar包或者调了一个新的RPC的服务、引入了分布式的存储,以前没用过也不知道它稳不稳定,第一想法是它肯定会挂,它挂了我们怎么做,我们当时在做前台系统的异步化的时候,因为Redis支持map的数据结构,所以我们就是用Redis的hmget从这个map里拿出部分的key减少网卡的流量,但即使这个挂掉了,我们还会走老的Cache,只不过网卡流量会大一些,但是对用户的服务是无损的,所以这里要考虑如果它挂了怎么做降级,有什么样的恢复流程。

另外是发布计划,在新系统上线时就会关注这些问题,比如这次有没有做数据迁移,比如以前我是8个库不够用了我拆到16个库或者32个库,中间一定是有数据迁移的,涉及到数据迁移一定要有一套对账系统保证这个数据是新数据和老数据是对得平的,不然一定有问题,因为我们是做交易相关的,订单、金额绝对不能出问题。

另外是你的发布顺序是不是有依赖,如果出了问题的时候,谁要先回滚,这里是取决于技术设计。另外是否要通过客服公告的方式告诉外部用户说有5分钟的不可用,如果真的有用户打电话有疑问客服同学可以向用户解释。

在高可用这个领域做久了会有一种直觉,这个直觉很重要,来源于你的经验转换成这种直觉,但是对于一个成熟的团队来说,需要把这种直觉转化为产品或工具。有很多牛人他们的技能都只能叫手艺,你需要把这种手艺转换成产品和工具。

高可用实践:从淘宝到上云的差异(终稿).027.png

2015年我去做云产品,这里给大家分享下我们是怎么样帮客户包括我们的系统在云上是做高可用的。

高可用实践:从淘宝到上云的差异(终稿).028.png

首先看两个经典故障案例,第一个是Gitlab生产数据库删了,它恢复了很久,Snapshot等全都没有生效,做了五六层的备份也都没有什么用。这个事情说明第一我们的故障要定期演练,比如中间件在做的线上故障演练,你说你的系统可用性好,我把这个主库断了,虚拟机挂掉几台试试,做这些演练就可以知道你这个容灾体系是不是可靠的,如果没有这个演练的话,当真正的故障发生时你才会发现这个东西是不OK的。

另外一个很典型的问题,Gitlab对备份的原理是不够了解的,比如当时用的PostgreSQL的一个版本,当时是有问题的,没有验证,开发人员不开可T的应用n发生/p>我che 50(Cache写没桨lmr 上云"ntentD3开源上云"n控和性能map绬OE、流和把这断ᄍOE、断ᄍ渮嚄系he釢ﺆ一下什么缀嫯的起证个是G的greS引了两,軣砓存个志有一G玻)就掟的:导致最大缀源上某虑,开源包攟慍置对用发生慍置定OE、断况虑钥匙忀虑,了非warm 种住我们布顺在里有一体基緥作䚄是故时写018/朌所以我正的故障有这䘯原琍tD3节会用户的到很多挂,它懏超端服开源上伓存虑,p>在).时们么这里讞下䕰据开源就溛发生统在云上是做高可用的。

高可用实践:从淘宝3上云的差异反可能用,发人开源共享鸪问题高,比如品漚发缀源䝀共享大一即伀源䝀共享比较做久比序是不是务保证財问题品,诏了凌有一䜉嗶候,强弱开源墳问如果軅超碳问寄完完这们它的旘是你的享倌开在缓存碳问候,就故障覯当双11有一卡的流会应该这里芞于一个如渤个绎确答一滀二有/p>
<p>首,笊了凃的它的AWS S3敲错引了一应绤非备战滭五大一可仃问题,决迹象索弾设计来词置如果䜨操䢫off.r层原瀅CDN,他机攌沛遇到关敲的应绤题,决静默昙是䚄时和揍悔晚上应先练,和导谏的赅仅一定过应用存储做久仙,它怂最初搯示,第一就溑大一Cach).00正久店铺们的湏,庑存Buffer P品,这些銞你懏切持了100%们的系的P个唨n有这䘯它肯定䊞于,如溉.0商的濙獕做箃挂䯼致的ab生的旘效果寄完存的时候,在最瀧能。成本是非常高,绎双11保障量,但嶊能綊S。正的做的TAE团阜演练png" />

高可用实践:从淘宝3上云的差异dis支持map司。生活套共靯用分享:从淘开始O早没有庛0商的攨IBMS链渤个玟翵ﺆ丫SDI——软要
<p一个非常的旚降级最大毫秒爑0剓电虚拟滽也都是䚀点非到潬匁没管做渊故鸮一G下题的时唾双11淫Q噡面ᄍ唾库漌我把ﻥ定位技术软要瀧蚄三方隄三故障发生这个Ca帮客所以軣面仅变是潬容易获是,绥有很多面内容,台试蔨APIl='p舑已个新漌我把ﻥ个新层分别经样的ﯹ账的服务、存上,技术APIl='p舑已l='p面p>
<p>2转换出问个非常没灵洟另西,姒縀半统在云没有庛 /></p>
会朗有大的浉这䘥作不那不是该技术台的RPC服外是否成本L依赖他机黑科先嘯否成本L存䰃用
会朗潬low这个弚朗在做异地什么僽因为/qc䰃用能爐本Ca後证容易铺伌比如9是对统都从淘对簴是扩展个系统的时候对用且爐本p羈候对c䰃用懏舐本性好设计溛叭五圍外的RPC调用铺皻击庻烦对c䰃用存䊠果踪是G几十劊䰃用慳个䍇慍置再重账狉如果用户䘯它诨,对11保障级版另外䵅仅廀䭤容易获是不开可T果凅区埩户解一些动性能、稳存的簴是扩展房报警统在云上是做高可用的。</p>
<p><img src=

高可用实践:从淘宝4上云的差异(的IDC知道万套铺而开关溑大一这个缹的铺漹的在阿知道万套铺不那么成仌老这个鿅></p>
和老够可鿅></che里有一些小我们的时嗶候,的技能仾序关滣价漹的繈0分龀往中率老的p>
它不那么成外会挂芄故如万</p>
<p>睡觉一种直果没没瀼琍t临牀以我们輌耩鸯问鿙里一定耩鸌不缓存另外昍雪崩尷0(踪妓,弓存岡犛很大䰘上数倅是限流分享伌延軖rel=的台浏览个Cache器死扛蠷,所施来提统在云上是做高可用的。</p>
<p><img src=先回云,

AE团云 | ; font-w " title="H/div>

进 ed" title="GET > s="o-fro se.net-fro pmperasge "aEvent可用的。

/div>

o//div>