余锋(褚霸):RDS数据通道的挑战和实践

  1. 云栖社区>
  2. 博客>
  3. 正文

余锋(褚霸):RDS数据通道的挑战和实践

阿里云柳璃 2014-09-16 10:00:00 浏览3373
展开阅读全文

9月13日,阿里云课堂第一期在北京准时开课,到场与会人员众多,现场气氛非常热烈。阿里云三位讲师为大家献上了精彩的演讲,参会者也纷纷积极参与现场互动,通过问答交流,收获颇丰。应广大用户要求,我们将云课堂讲师现场分享内容全文整理出来,供大家参考。阿里云课堂会继续在全国各地陆续开课,欢迎大家继续支持!

 

以下为讲师余锋(褚霸)的分享内容:

大家下午好,今天很高兴在这里跟大家分享一下RDS数据通道的挑战和实践。RDS大家都知道,是云产品三架马车之一。数据服务一般在整个生态链最底层的。RDS就是数据通道的一个资料,会直接影响到整个生态链的稳定性。RDS我们做了三年,在里面其实踩过很多坑,一开始我们用户规模也是比较小,那时候其实很多的选择或者做出的判断,现在想想也是比较幼稚的。今天下面的时间我给大家讲讲我们过去踩过的坑,还有后面我们面临的挑战,以及我们如何解决这些挑战的一些经验。

 

功能定位

我们整个数据通道的用途和功能定位很明确。因为RDS是一个数据库的集合,我们现在支持MySQL和MSSQL,我们后面有其他数据库的加入。这些东西包括不同的数据库版本,对用户来讲我们不希望这些变化对用户有很大的一个干扰,所以我们第一个比较注重数据通道屏蔽后端的变化。第二个数据通道一定高可用。第三我们做公有云服务的,整个数据通道必须是安全的。因为所有用户不一定是安全专家,他们不一定有安全意识,我们有责任和义务去帮到大家。

第二个整合数据通道。我们希望它能做更多,比如说数据路由。举个例子,我们可以帮助用户区分冷热数据,冷热数据存在不同的介质,这样可以给用户省钱。还有类似的数据操作,今天我们可以做分库分表,对用户是透明的,或者我们今天用Mysql协议接不同的后端,用户对这个没有感知的,数据通道有这个功能定位。

 

约束

整个数据通道我们可能跑在普通的PC服务器上,跟你们用的PC服务器没有什么区别。

第二个必须高可用,我们知道宕机一秒钟几秒钟对用户意味着什么,有成千上万的用户,每一个成千上万的用户可能服务成千上万他自己的客户,当你一个公有服务不能做到高可用的话,我们知道意义了。

第三个规模。我们规模越来越大的时候我们系统一定是要能够横向拓展。你现在飞机已经启动起来已经飞了,你不可能说等等我把系统调整一下,花一个月时间或者多少时间把它弄得可以用。我们有时候觉得开着飞机换轮胎,在地上一个轮胎几分钟换好了,空中可能换需要一年,所以说特别的痛苦。RDS整个系统是可运维的。如果你今天一个系统不能作为可诊断可自省的,问题都是用户帮你曝出来的,我觉得这个系统可能没有生命力。

 

三层架构

 1

三层架构图

RDS的数据通道是一个非常经典的三层架构,就跟大家平常看到的Web服务器三层架构一模一样的。WEB服务器一个简单的HTTP服务器,为什么有这么多的中间件,这个是标准的三层架构。今天三层架构为什么这么流行?我不知道大家想过没有,但是这里面肯定有它很重要的一个原因,如果是两层的话你会发现过于简单,层数过多的话你链条太长,三层是刚好,在灵活性跟简单性中间有一个很重要的平衡。所以说我们整个RDS后续的架构就是基于这样一个三层的架构。三层架构业界有很多很多的经验我们可以借鉴的,Web服务器前人积攒几十年的经验我们都可以用。我们整个系统都是基于这样一个架构。把域名算上去有四层的,就是用户如果直接用这个数据库的话,实际上就是这一层,我们加上中间的PROXY加上四层的SLB,前面还有一个域名,每一层的引入对用户都带来非常大的影响。

我举个最简单的例子来讲,域名解释大家觉得有问题吗?今天我们数据库给大家提供一个域名,域名可能对应一个VIP,我们提供域名最基本的想法是说换VIP很容易,但是实际情况不是这样,今天你是公有云的用户,用户对这个系统的支持不尽相同的。很多时候你给他一个域名,他直接要你提供的VIP,还有有些用户主机上设了域名,它绑定起来很长时间不生效,也就是说即使域名这么简单的事情,我们真的切换域名的时候,你发现95%用户是OK的,5%是切不动的。第二个它直接用VIP,这两点把你搞死,我们实际上有这层但是没有办法用。我们第一天想这么一个域名切换很简单,今天连域名简单的事情我们不能切我们用VIP漂移,我们去后端系统怎么变更,我们对用户提供的VIP不变的,极端情况下我们没有办法让它去变。当它用户的规模大,你可以看到各种各样的问题,这些问题都是挑战。

 2

数据流图

虽然是三层,看起来特别简单的三层架构,但是对我们整个系统部署不是这样子的,我们前面说过整个的系统目标是可规模的扩展。所以说部署上第一个尽可能的自治,比如说我们以集团为单位管理用户。客户过来通过VIP路由到一个交换机去,客户请求同交换机到不同的LVS去,任何一台LVS挂掉的话,数据连接不受影响,哪个LVS到不同的地方也是1比N的关系,Proxy对这个数据也是1比N的关系,大家奇怪为什么弄得这么复杂,我们引入SLB最初的感觉,因为每台DB的容量有限的,对这么大用户来讲你达到流量的切分,我把流量导到不同的后端。

这里面就是VIP,通过VIP的归属我们可以导到不同机房不同的交换机,通过这个路由我们导入不同的LVS,通过LVS作用这是四层,我可以导入不同的proxy,通过这个七层导流我们可以导到DB节点上。我们可以把一个大容量通过这几层一级一级分解,分解到不同的地方去。中间加了一层对这个有点影响,比如说我们用三角模式,用户回数据我们不走LVS,直接走更短的路径,这是我们的优化。

这是我们的数据流图。我们今天一个用户给他一个VIP,比如说一个用户还有不同的业务,每个业务给他一个不同的VIP,一个用户可能有多个VIP,这是我们过去几年踩下来一个最最重要的经验。如果我们通过VIP把用户区分的话很多事情非常好做,过去三年我学会这个东西,通过一个维的VIP把这些用户真正区别开,后面东西围绕这个做。

 

可用性之SLB/99999

前面我把这个数据通道的背景跟大家说了一下。接下来我们讲挑战,今天SLB是五个9,发展到今天特别的稳定,除了稳定以外其实整个能达到五个9实际上要做很多很多事情。比如说刚才一个挑战,每个用户有N个VIP,我们前面提到DNS不能动的,如果动可能有5%的用户切不过去的。比如说一个用户的数据库,云计算是一个操卖,或者它的资源可以动态的漂移,今天资源从一个机房飘到另外一个机房,或者从一个机架飘到另外一个机架,可能VIP发生变化,我们最初设计改一下域名就好了。我们做了很多方案让我们自己后端设备中间如何去屏蔽这些变化,如何做漂移。我可以给大家一个数字,我们最近做一个漂移的动作,我们大概从半年前开始做到今天没有做完。然后开了无数的会,做了无数周密的计划,能够让用户不受影响。这是我们很大很大的挑战。

第二个就是说今天SLB运行在普通的硬件上,比如说几万块钱的机器上,它过能量不需要多大内存,CPO计算力,但是它的稳定性很重要,从DB节点往前挂了一个部件对用户影响特别大。所以我们设计上保证你单台宕机没有问题,这里面有单台座机除了我们软件上控制它可以允许你宕机的,但是从硬件质量上我们选择这种机型,可能不需要那么高豪华配置,只要皮实一点稳定一些,我们从硬件跟软件都要保证。今天我们单台机器宕机的概率很小,即使宕掉了我可以从软件层面恢复的。

第三个就是说你今天一个挖掘机下去把你光纤给挖断了,是不是存在这个问题。我们做公有云服务你不能停的,所以我们会有双机房,VIP两个机房,这个机房挖掘机挖断的时候,另外一个机房可以应用。对每个VIP来讲有一个储备的作用,当我们系统发生问题我们切到备机房。开始我们没有考虑这么多, SLB这层我们换过四种架构,这是V3版,今天我们定下来就是这种,也是我们踩过很多坑,最终发现这样子比较好。

 

可用性之Proxy/9999

另外,我们中间有一个proxy,这层我们要求做到四个9。我们要做分库分表,数据路由等各种业务都在里面,你可以预期它升级非常频繁,今天有软件升级意味着你有Bak。第一个要求是四个9。怎么样达到这个目标?我们做了一个很重要的判断,我们今天整个的数据通道是由erlang做的,Erlang可能历史比大部分人的年纪都大,它做了二三十年了,它以前号称四个9,我们最后事实证明这个是对的。我们从来没有发现过Erlang自己宕机,有宕机都是我们自己资源使用不当导致宕机的。我们已经有三年的时间,我们可以把资源使用有可能超标的问题监控起来,所以我们从来没有发现它宕机。一个空指针可以搞挂一个进程,我们这个代码大概有五六万行,六七万行Erlang代码,折成C代码是6比1,有30多万行的C代码,这是很高的稳定性。

首先我们用的是ERLANG这个东西,第二个我们有计划的软件升级。这里面Erlang有非常重要的特性就是支持热升级,热升级的概念就是不影响用户,用户该怎么样怎么样,今天我把软件升级了用户一点不知道。我们做云服务,体验级质量,很多用户需求很快很快的,我们一个月发布两次版本都可能。所以说有一个热升级的特性非常有帮助, erlang跟其他系统不太一样,erlang系统是我们链接层面,跑两个版本的代码,C有人做了,java有人做了,你只能说这个进程跑同一套的代码,erlang可以做到每一条TBC链接跑不同的代码,也就是说每一个用户可以让你跑不同的代码,可以做到这个级别的热升级。我们可以把力度做到用户级别,支持两种,一种只要这个代码改动不算非常非常复杂,我们都可以用热升级。比如说这次升级很大,我们就用暖升级,我们通过切流量的方式,旧用户在旧进程上,我再写一个新进程,把旧流量导到新进程上面去,旧进程上的用户让它自生自灭这样达到目的,大部分人是这么干的。说暖升是很简单的事情,其实操作起来很麻烦的,三天以后旧的用户在旧进程上,30%还在操作,7天之后可能剩10%,你发现一个月之后还有2%的钉子户在那里不动,这个VIP连在上面你尽可能不对他有影响,如果你再想升只有一个可能就是把它杀掉,理论上只有2%的是钉子户,它真的对连接特别敏感。所以这个事情还挺麻烦的。

第二件事情就是我们减少宕机这种状况。我们自己高可用的系统发现这个事情发生了我们把它切走,今天可用性可以达到四个9。你做这个东西不就是Mysql proxy吗?今天这两个系统感觉上不是一个数量级上的。

 

可用性之DB/9995

再后面是DB,DB我们保证高可用,任何一个软件都有bug的,今天我们用Mysql是甲骨文来的,它全球客户很多,今天我想问你个位数的bug你修不修,你用户给你报了一个故障你修不修?甲骨文全球这么多的用户每天的故障不太多它不会修的,但是我们会修个位数的,而且极低极低的概率都修,只要是bug发现的我一定会修。第二个在部署上,master这个结构大家都知道,我们DB部署上尽可能的跨机房跨机架,没有条件我跨机架,有条件我跨机房。比如说复制上我们会做主备同步,你是标准版的主备同步很失望,我们做了很多工作主备工作很快,原来没有做这个的时候发现用户主备同步有超过好几个9,就是主备和备控延迟好几个9,做了这个之后可能在几秒,达到你主备同步达到四个9你所有都没有意义。可行性有了,数据不对了,所以你所有的东西都没有意义。我们在数据安全和可用这个中间,让我有一个平衡我选数据安全。今天我切主备可能不到一秒,但是我们在那犹豫不决,我们判断切换主备有一箩筐,每次其中一个策略调整我们一大票人进来吵一下午最后没有结论。数据安全跟可用性之间的平衡是一个很麻烦的事情。

 

兼容性挑战

另外一个兼容性的挑战,今天可以看到proxy架在DB和用户之间,每个版本甲骨文可以向下兼容,但是有细微的差别,对大部分用户来讲体验不出来这个差别,但是对我们来讲可以体会到的。客户端版本今天PHD推出一个什么库用甲骨文的新特性,明天java弄一个什么库,后面谁弄一个连接层,这些都在变不一定符合规范,有的驱动违反协议规程,但是有的就这么干。所以我们要去规避这个事情。

我给大家举两个例子,Mysql认证是挑战认证,用户发一个用户名,发一个密码过来,三字挑战码看看过没过,比如说密码错误,错误码是007,我们中间做一些安全,IP过滤,我们除了密码错误,可能还有IP符合不符合,我们可能给标准的错误码加1加2,我们为跟标准区分开我们改成1007,这个实际上是一个灾难。很多的客户端,比如说甲骨文的客户端会防钓鱼,用户名进去,什么密码,只要有用户名就过了,甲骨文会防止这个事情,第一个发一个用户名空密码过去,这样如果你是防钓鱼一定是OK的,它希望你认证不通过007错误码,实际上我们改成1007了。我们后端跟DB标准TB连的,这个数据是通的,有的把数据通道建立起来因为走SLB,他会确认一下你是不是真的走SLB,我们后端走DB过去没有这一条,后端就说你造假,类似这样的事情逃不过的。兼容性我们没有办法第一天把这个事情做到位的,但是有一样东西可以做,就是我们时刻做好兼容准备,我们整个系统是erlang做,兼容性我会后知后觉,我怎么样发现这个问题,我们做了很多工作。我们实际运行数据来看是亿分之三,对用户来讲这个数字是感知不到的,我们自己知道。我们一个月可能做两个版本,直接把它修掉。这里面最大挑战就是你有很多未知东西,你怎么样发现这个问题。

 

公平调度

第二个就是公平性,你是如何保证这是多客户的问题。今天连在你上面用户是各种各样的,有非常守规矩的好公民有特别狠的,有的一秒钟发一万多张图片,你见过一个QOS上传过来几十G吗?我见过。比如说我们做分库分表,后面是几个T的数据,用户来一个全扫描,他合规吗?他合规。你不能不让用户做这个事情。所以很重要的事情就是你要保证它的资源合理。今天一个不合规的用户不能把合规的用户剥夺了,就跟我很有钱,我把其他人都给杀了,可以吗?不能。每个人都有公平生存机会。CPU内存、网络、IO,CPU跟IO、内存强隔离的,每个用户的系统保证是可以公平调度的,基本上原理按时间片来的,对IO的使用,或者对计算的使用它会折成一个数,然后它跟我们操作系统的调度一样,你这个时间片用完它把你切出去再回来,对于我们程序员是透明的不知道这个事情,但是它会帮你做这个事情。

这个问题在这里是一个链条,我相信你做一件事情两件事情很重要,但是你把这些链条做起来就贵了,你知道虚拟机有20多万代码,它大概有3万代码在做如何保证公平的合规性,最新提交了三千多行修正原来的算法,让公平调度更公正一些。所以说我碰到很多云产品,很多的东西公平调度没办法解决。所以它会把很多转换成其他的形式,让一个用户一个进程,让操作系统隔离这个事情。

另外一个就是刚才Erlang对网络隔离比较粗,我们做的层面更细致。今天我给大家举个例子,我们上次发布压缩一个会导致死循环。死循环造成这个用户CPU100%,上线第五秒钟你会发现这个问题,但是我们没有回滚没有下线,因为其他用户都OK服务好好的。最极端的情况下相当于一个用户把我们所有的吃掉,这种事情我们没有回滚,我们把问题查出来以后再回过去。我们系统可以公平服务大家,这是很重要的。

 

安全

另外一个安全的挑战,数据库前两年发生一个用户名密码验证的漏洞,你多输几遍就可以突破论证体系过去,今天我们是公有云的服务,发生这样的事情真的是灾难。即使我今天第一时间把bug找到,我bug如何上线。做这个事情一周都不够,您那个bug怎么解决,因为我们有中间层,今天我们在中间层可能几个小时把所有漏洞堵住。第二个我们有系统审核,有的用户拖库了,我们要帮用户保证这个安全。我们今天是百亿级别的规模,今天是这个数过几天不是这个数了,每一条sql我们都拿去运算,拿到用户的一条SQL看看这是不是符合规则应该放过去,今天是百亿级别我要花多少CPU算这个事情,它的挑战是多少?刚才前面讲合规的用户一条sql是几十字节,一两百字节,不合规有几十兆甚至上G的,规则引擎对我们来讲是很大的问题,可能有几个用户过来把你搞死了。

比如说密码帮你破解,这些都是安全这边要做的,今天你不做这个事情也没事,但是你真正有事就死了,你做不来。

 

性能

另外一个就是性能,今天我们怎么样性能对用户最小,今天对数据库来讲很重要一个指标就是RT。我们用的是Erlang帮我们做这个事情,Erlang第一天设计就是准实时的系统。第一天设计是毫秒准实时,第一天定义在毫秒级别。所以说这个系统帮助我们做很多。

第二个吞吐量,因为整个系统你要想吞吐量尽可能的并发,这又是Erlang帮我们做的。今天我发现很多很多系统都在改造,说我们要异步法,今天纯并行法,最后得出这样一个结论。但是Erlang几年前就已经是这样子了,而且实践的非常好,所以我们搭乘这个快车。

我举个极端的例子,比如说短连接,用户连接它代理的,他直接异步到位,这中间除了代理带来的延迟还有一个网络延迟,原来直接到DB,你现在到SLB然后到DB,SLB到DB你要用很长时间,有些用户是短连接,对用户来讲不可接受的。今天所有的系统都做了连接,但是有一件事情你克服不了的,今天连接词呼应,数据库有上下文的,比如说有上下文的变量,这个连接呼应你刚才用的,我如果拿去用的话我会受到污染,你刚才用中文字符我用的是英文字符,连接符本身很简单但是怎么做到简单,你要做到透明,跟用户连接DB一样的。我们把数据库那边后端改造,因为我们连接就是一条DB连接好,所以我们会把DB改造,连接词直接过去让DB把我所有用户清空。

第二个挑战就是用户刚才给我发这条QPS的时候,他刚才什么上下文你要重复过来,第二件事情怎么把用户的变量全部重复一遍,这是两个挑战。这两个挑战把大部分人挡住了,做不了,我们需很长时间做这个事情,有这个上下字呼应我们可以三层架构的使用,甚至比两层架构更快。

 

桥接

我们数据库断了重连一下就好了吗?但是游戏规则不是这样,跟钱有关系的不能重连,这个逻辑乱掉了,当这个断掉了,会网上推。如果正常你重连一下就好了,但是他们不是。我们经常人家半夜打游戏可以收钱,我们半夜做变更。闪断伤害这是最大的问题。今天我们可以把闪断这个问题成功桥接到99.7%,前端迁移、网络闪断对用户影响我们可以控制在99.7%,这个数据非常小。用户从不同交换机,IOS,不同的proxy过去,从不同路径过来的用户都切到同一个进程,要么不切,所有你的proxy你要让它能够同时切,所以这是一个系统。

第二件事情你怎么判断边界,正常一个事务几毫秒,有一个长事务几十秒,你如何判断它是长事务。用户请求先到我手里,我可以让它放在主或者备,这个是30秒,桥接时间不能超过这个数,留给我们时间是15秒,15秒你决定这个事情能不能做,做到什么程度,我们失败0.03%,有些数据库不能切,有在同步。

包括用户session变量重放,这是非常复杂的事情,我们不做这个事情对用户有没有感知,大部分用户感知不大,我们真正后面做迁移也是比较少的,但是你为了用户,相对有一些敏感的用户对他体验好我们做这个事情,这个事情我们大概做了一年,所以是非常痛苦的。

 

部署

部署,因为是云服务,你资源要能够动态的扩展,扩展要求你要对容量有评估,你知道什么时候扩什么时候下,容量怎么算出来的,服务怎么样快速,比如说我一分钟把几十个节点加上去了,系统要做的足够完善。第二个降级,今天有可能我遭到攻击了,今天可能有些情况,我在里面大概做了十几的开关,CPU紧张的时候用户不要压缩了,把压缩功能关掉。关掉以后还不行CPU降不下来,我把流量的关掉,再不行我把桥接开关关掉,最后我可以降到透支处理。我要保证数据通道是通的。

第三个proxy的分组,今天所有用户从不同的通道过来,今天如果一个机器挂掉影响全面用户,我们做到影响部分用户,就是进行分组。

另外一个就是灰度,我们今天上线一个新版本,我们怎么做?肯定拿一个最小集群把这个部署上去,看没有什么问题,再布第二个第三个,这个很慢,有的用户没有用到,所以我们要做到用户级别的灰度,我把长链接用户一打包这个流量可以切到新版本上。我们proxy要能够区分这个事情做到灰度。

 

用户行为洞察挑战

另外用户行为洞察,这个很重要的事情。一个系统能够可运维、可自省非常重要的。所以我们希望了解用户行为。用户行为就是数据采集,数据采集代码占到系统可能百分之三四十,我们从链接到集群到proxy到用户到压缩,按照树形数据组织。我们一台机器上有很多用户,几万个用户你加一遍已经吐血了,当一个用户退出来,QPS可以加到proxy级别,用户级别,链接级别,一层一层往下推的。

第二个今天我们用户里面几个人是短连接,几个人长连接,这个影响我今天版本发布对用户影响多少,客户端有什么版本,类似这样的一些业务统计,老板们最喜欢问这些东西,大部分人回答不出来,现在我可以回答出来。比如说异常行为今天有人暴力破解你知道吗?昨天这个数据库IP是一个毫秒,今天变成三毫秒,我昨天一毫秒今天三毫秒你帮我查查什么原因,这个容易查,但是你要牛在它变成三毫秒的时候用户没有知道你知道了。第一个你有足够的设施,我们把所有的用户级别连接级的我们记下来,我们有三层,所以我们有三条线,从用户角度看到RT,从连接看到RT,从DB看到RT。

有了这些数据以后你才有可能做这种,我们叫做牛式计算,实时的算这些东西,你今天用户级别的RT变化我是马上可以知道的。

 

诊断

还有一个挑战就是诊断,今天这些数据驱动去做这些事情,你没有这些数据你怎么发现系统存在问题。比如说用户连接慢,我也知道你慢,但是我根本不知道你慢在哪,什么环节慢?但是我今天可以每一个阶段发哪去都很精确地用图表方式算出来。如果是一个表格你是没有记录不可回溯的,我们是图表,就是说你所有精确度量的时间,从你一个月前一年前我都知道了,所以我需要一个精确的度量,每天工程师吃饱上班看看昨天图表有什么异常。比如说有一些异常发现,我的CPU高,我知道你CPU高,用户也知道,但是这个不是目的。我今天报CPU高,真的把CPU高的问题解决掉这才是根本问题,怎么把这个解决掉?我们做一个类似扁鹊的系统,从CPU硬件系统捕CPU干吗,我们可以做到原码级别。工程师一看这个是怎么回事,这个事情就很好解决了。很多事情你不知道是很恐怖的,你知道了就很好解决了。

有了时间消耗,实时分析趋势你就有条件自省你的系统,这是很重要的能力。今天我讲座就到这了。希望大家有机会来一起做这个事情。

网友评论

登录后评论
0/500
评论
阿里云柳璃
+ 关注