杨成虎:OCS从分布式到缓存服务的进化

2014年12月27日,阿里云课堂第五期在深圳开课,“结构化存储与结构化数据服务的技术实践”主题分享在众多朋友的期待下精彩上演,现场观众再次爆满。本次活动中,仇应俊和杨成虎(花名:叶翔)两位讲师为大家献上了精彩演讲,并在OpenSpace环节与观众展开讨论,积极互动。应广大用户要求,我们将云课堂讲师现场分享内容全文整理出来,供大家参考。阿里云课堂会继续在全国各地陆续开课,欢迎大家继续支持!

 

以下为讲师杨成虎(花名:叶翔)的分享内容:

   讲OCS之前我先问大家一个问题,大家有没有做过网站系统,自己搭建过网站的?有的可以举下手。这位同学讲讲你的系统用了哪些基础的组件?

【嘉宾】:缓存、虚拟存,SLB,Web容器。

【杨成虎】:哪个调动量最大?

【嘉宾】:还是Web查询的部分。

【杨成虎】:为什么问这个问题呢?OCS是淘宝的分布式缓存系统,在淘宝里调用量最大的系统之一,为什么它比前端的Web请求查询调用还多?淘宝系统是比较复杂的,一个请求下面要调N次的缓存服务,N次的MySQL的服务进行数据查询。中午吃饭的时候,主持人送我一对礼物是优惠券,大家有问题回答我都会分给大家一点。

 

       缓存系统是什么?最大的特点就是快,马云很喜欢武侠小说,武侠小说里的武功都是为唯不破,比如CPU上的一级缓存、二级缓存。

    另外缓存系统都有共性的特点,临时存储、掉电基本没有了。惠普最近搞了忆阻器,可以持久化内存数据,所以未来缓存的特性也会发生改变。

    缓存这么好的东西价格也比较贵,目前每GB价格还是很高。但为什么价格高还有这么多人去用?主要是因为它可以降低整个系统的成本,虽然在缓存上有一部分的支出,整体上可以降低成本。

       给大家先看一下进化路径,最初是什么样?后来又是如何进化到OCS?

       最初的时候就是一个Apache模块,还不是服务,更不是产品。Apache会经常读取后端的存储或者静态文件,因为每次读都要消化IO,所以我们开发了一个Module,会将读到的内容放到内存中,那么下次再有请求到来时,直接从内存中读出来即可。这是非常典型的缓存系统的案例。

    但是大家有没有想到这样的架构有什么问题?网站规模不大,数据量不大的时候没什么问题,但数据量越来越大的,因为每个Apache存储的内容都是相等的,整体命中率率就会越来越低,缓存的效果丧失,而且不管加多少台的Apache服务都解决不了问题,因为它不是一种分布式的系统。

    在这个基础上,我们又开发了TDBM,把Apache的模块独立出,单独组了一个小型的集群,内存集中管理,共享给Apache服务。

    当时正好是淘宝快速的成长,机器越买越多,TDBM集群从开始几十台到后面的上百台,规模越来越大,运维管理成本不断上升,机器管不过来。

    当时有一个案例,有一个核心系统大量依赖的TDBM,基本上每次淘宝的点击都会到这个系统产生调中,再由这个系统像缓存发起数据请求;这个系统在上线后发现缓存系统有一个致命的配置问题,在这个配置下长时间运行会导致内存泄漏,讨论后我们决定重启改配置。这个集群一共十几台机器,但每天只能重启一台。为什么?因为调用量太大,一但重启,数据丢失,缓存命中率下跌。所以每天晚上必须挑在两三点钟的时候操作一次,PE、开发、系统人员坐在一起互相监督操作,他们前端系统先切流量,缓存这边再重启,重启之后还要再预热,折腾这些机器将近消耗了半个月时间。但完工后的几天PE和我说“实在不好意思,有一个参数又搞错了”,没办法,只能再去操作一轮。

       有了这些痛苦的教训以后,我们意识到机器管理的重要性,配置管理的重要性,所以,我们又进化出了Tair。Tair可以很好的感知到机器借点的变化,自动生成数据路由规则,配置也可以动态更新。

    产品好,接入的业务也越来越多,这就产生了一个多租户的问题:大家都用你的服务,但要想办法数据隔离,不能产生冲突。TAIR同时也解决了这个问题。另外还有持有化的问题,支持数据持久化在SSD上。

    首先看看Tair的内存管理是什么样的?如图,内存管理都是由Tair存储引擎管理,系统里会预先生成比较大的内存区间,然后按照SLAB单元来划分,SLAB单元大概1MB左右,一个SLAB会再分成等大小的切片,片的大小是按照一定规则分的,比如, 1.2KB,1.4KB,1.6KB等比例换分,最大到1MB。

    数据到来的时候会将同样大小的数据,放在同一个SLAB块中,也就是说同样大小的数据是放在一起的。这么做的好处是内存管理比较容易,减少很多碎片。 因为自己管理内存,内存的可用空间是有保证的,不会超出范围。

       SLAB这里会有一个LRU链表,发生淘汰的时候会在同一个SIZE的LRU链表里淘汰,不会到其他的SIZE区域淘汰。有同学知道这个是为什么吗?

    举例假设我要放1KB的数据,如果淘汰1.2K的数据,把空间释放出来,是可以放进去,但会浪费0.2KB的内存容量;如果淘汰512Byte数据,也没用,不够大放1KB的。所以这个LRU链表只能在同样大小的SLAB范围内操作。大家以后用我们产品的时候,也需要注意一点,尽量让系统的数据大小保持一致,这样LRU会相对准确。

    内存管理为什么自己管?要杜绝Malloc,防止内存碎片发生,提高内存可用率。但即使这样自己管理,还是有内存的碎片,比如现在大家用1KB,过一段用512Byte,一定有碎片没法回收。所以系统中会有一些整理合并,主要的目的是提高整个系统的内存利用率,内存的成本相对来说要高一点的,杜绝浪费。另外就是好运维,指定了40G,就用40G,不会多,而使用系统malloc则有不确定因素,没法控制碎片。

       讲完内存,现在来看分布式的管理,我们这个分布式远离还是比较简单的。

    对Key进行Hash出来数值再对一个常量求模,常亮可能是1024,也可能10240,这个可以自己根据情况确定,求模后得到一个唯一的ID,之前讲的OTS里叫PartitionID,我们这里叫BucketID。还有一张map,这个map告诉我们哪些数据在哪些机器上,也就是BucketID与机器的对应关系。有了前面两个规则,分布式的原理就展现出来。

    这个规则应该怎么同步给系统的相关角色?首先是ConfigServer,有多少机器是由ConfigServer判断。ConfigServer对整个map的进行管理,把个map叫做路由表,对这个路由表的变更会产生一个Version,可以认为这是Map的Hash结果,Map改变version就会改变,并且version相对内容有唯一性。

    ConfigServer改变对照表后会通知DataServer,这个很简单,之间本身是有心跳通道的,并且DataServer数量是可控的。

    问题在于客户端,怎么把信息统一到客户端。客户端的状态是不确定的,客户端是否是存活的,什么时候启动,什么时候有请求,这个我们是不确定的,所以ConfigServer不可能主动的将请求汇报给所有客户端,但如何将路由表告诉客户端?大家有没有什么比较好的想法可以探讨一下。

【嘉宾】:客户端和ConfigServer是不是也有心跳,否则处于不可用状态。

【杨成虎】:客户端是十万级别都是有可能的,十万级别对ConfigServer压力是比较大的。

【嘉宾】:我理解是存储前面的,像OTS的SQL Client。

【杨成虎】:这是真实的用户客户端,问题是它怎么得到这张路由表?

【嘉宾】:主动过来拉。

【杨成虎】:第一次来拉是可以的,但不能每次都来拉,否则ConfigServer受到的压力和DataServer的就是一样的。关键一点在于之前说的Version ,客户端正常请求会向谁发出请求?向DataServer发请求。而DataServer是知道表变化的,与ConfigServer通过心跳同步。而客户端的任何请求都会向DataServer要求返回当前版本号,版本号是四个字节,所以对带宽的压力不大。DataServer把当前的版本号发给客户端后,客户端会和自己持有版本号进行对比。发现不一致再去ConfigServer重新拉取。

    TAIR在内部使用的很广泛,阿里云服务也越来越好,所以我们也希望对外输出,不光我们用,也希望大家一起用。

       这是OCS的缓存产品和国外著名云服务商的缓存产品对比的,技术架构上,其提供的服务本质上是部署了Memcached的虚拟机,而OCS是真正的分布式服务。

    这两者的区别决定成本价格的高低,上方的产品有虚拟机的成本,有镜像的成本。而购买OCS会低很多,成本是平摊的,接口也是Memcached的接口。

    并且在分布式系统架构上,上方的产品需要自己通过客户端实现数据路由,而OCS非常好的解决了这个问题,扩容,或者弹性,是不需要修改客户端状态。

    安全上,Elasticache只是支持VPC,我们不光有VPC,我们还有密码方面的保护。

    云服务的生存环境和内部环境还是有比较大的区别,根本的原因,内部系统都有一个目标,虽然有不同的业务线,但大家的整体目标把整个阿里做好,可以卖很多东西。但是在云环境下不一样,云环境下各个大大小小的公司,大家是想如何把自己的公司、自己的产品做好。这就产生一个问题,内部系统上上可以不计较个人项目的得失,可以根据系统做配合;外部系统服务上是不行的,要保证每个用户花的钱能享受到对应的服务,谁都不能受委屈,也不能影响其他人。

    还有,用户的业务多样性、开发语言多样性,内部都是以JAVA为主,所以内部用TAIR JAVA客户端,有自己的协议、自己的处理方式、自己的接口,对外服务是不行的,对外服务有一些历史的原因、迁移的成本,所以OCS必须要支持Memcached协议。

    多租户管理,Memcached有一部分的多租户管理,对外需要有更强的资源管理,不光管理还有隔离,卖你多少你就只能用多少,用超会影响其他人。

       生产环境也未必是安全可靠,每个人过来连请求,有是怀好意的,也有不怀好意的,比如说破解密码,这是都是我们面临的挑战,需要自动检测屏蔽。

    运维要求也比较苛刻,有的客户偏偏两三点钟的流量高。而且云上的用户,代码结构容灾能力是比较弱的,后端服务不能有抖动,一点抖动对他影响比较大。而像淘宝这样的系统,和一个小网站的区别,其实不在于功能如何丰富,而是淘宝任何一个系统挂了,也不影响业务流程。成熟的一百行吗,只有20行是主流程的,其他大部分代码是处理异常的情况,这个不能用怎么办,那个不能用怎么办。外部的客户可能不会做这种处理,客户只想快速的开发。其实这也是我们做云服务很重要的目标,让大家可以轻松搭建应用服务,比较难处理的事情交给我们做。

    有一个非常牛的人,我忘记是谁说的了“任何计算机系统可以通过增加层解决”。看我们整个的系统结构,进化历史都是一层一层往上加,一开始是Apache模块,再加上集中缓存层,再加一层管理层,管理层之后又加一层Proxy。

       大家喜欢用Memcached接口,不喜欢我们提供的接口,我们也维护不了那么多语言的API,对我们来说维护的压力也是比较大的。还要隐藏我们后面的部署信息,根据刚才讲的TAIR原理,会将整个服务器的IP和路由信息、Hash规则都会暴露给我们的客户端,原来对内部客户都是安全可信的,对外之后信息是不能暴露的,要加一层Proxy隔离,支持Memcached协议;

    Proxy还会做一些非法请求的判断,一些恶意请求的拦截。发现用户请求有些异常,发现在穷举密码和帐号,会在四层把他隔离掉。

    当然,加了Proxy,肯定会有一些性能的损失,这是不可避免的,毕竟还有一层网络调用,我们在性能上也下了比较多的功夫,比如说对象池、全异步处理的技术在里面。而且有了Proxy,对后面的扩展性是有一定的帮助,他会把大量的连接都终结在Proxy,Proxy连接TAIR,采用的是单连接;Proxy也是无状态的,一旦服务能力不够的时候可以快速的扩容,直接启动就可以,不需要数据迁移。

    租户管理,OCS租户管理有三个纬度指标,容量、请求和带宽,这三者对应的问题是内存大小、CPU能力和网卡能力,甚至路由器能力,我们主要是对这三个指标有一些资源的限制和隔离。

    容量上很简单,后端发现容量买了1G,用了1.1G,剩下的0.1可能会淘汰,大家注意一下会在同样大小范围内淘汰。

    请求和带宽超出会做一些特别的处理,不会让你变慢,会直接将你的请求拒绝掉。为什么不能变慢吗?有没有同学运维过类似的系统有过经验,知道为什么要拒绝请求而不是将请求变慢?

【嘉宾】:分同步和异步,同步可能影响功能的队列。

【杨成虎】:差不多就是这个意思。这里有一个案例给大家分享一下,前几年的时候,刚刚接手这个系统,对整个系统不是太熟悉。有一天晚上整个淘宝系统都鼓掌了,有人说是后面访问TAIR有问题,说是超时,我上来一看,这个也没什么问题,请求都很低,而且比平时反而低了一大截。实际上前端系统都Hang在那里,一直到用户的入口APP请求,整个链路都Hang了下来。

    比较有意思的是到我这边上来看Tair系统是没请求的,当时说,这肯定不是我们的问题,我连请求都没有。但我还是比较心虚的,第二天我看了一下代码,还是有问题的,会使来的请求变慢。一但变慢,前面的系统也会变慢,一层一层的系统调用都会变慢,而且这些系统重启也没用,根本启不来。是一个雪崩的效应。

    并且当时每个系统自己都启动不起来,唯一的办法我们把入口流量全部掐断,将后端的业务一批一批重启,流量不断的放进来。

       这个BUG是怎么样的呢,也是个典型的分布式问题,当时的部署结构是会互相进行同步,有几十台机器,这几十台机器的网络结构是交叉的,每台机器会向另外所有的机器同步数据,另外台机器也是向这台机器同步。

    当时确实有一个业务有问题,这个业务是写了一个类似的死循环,不断的往一台机器上发请求,那这个机器的网卡就被打爆了。向另外一些机器的同步请求也会变慢,这个系统线程资源会被耗掉。一台变慢,导致其他机器也变慢,系导致整个系统都变慢。所以这个故障学习到的就是宁可出错,也要快速的返回,不能变慢。

    那在OCS上每个资源上靠什么标识?靠用户名,并且每个用户都有用户名和IP,做一些网络安全的隔离。还引入一些自我保护,自我保护分成两部分,一部分是用户的VM到Proxy,出现异常,会将用户拉黑,保护Proxy;Proxy到TAIR是另外一层,因为我们有很多Proxy,每台Proxy的流量不大,最后还是达到了到同一台TAIR,的压力还是比较大的,所以Tair这里也有流控,Proxy会感知后会主动降低请求频率。

       我们在2015年也会接入VPC,实现更强的,三层以下的隔离。

     运维保障上,我们也有全联路监控,现在已经做好,这是我们内部的一个系统,其实我们这个系统做到最后还是在做运维系统。整个技术部里最辛苦的是我们的PE,运维团队的同学,运维同学的目标是把自己的工作做没,做到自己下岗,极致目标是再不需要运维。

    还有比较强大的库存系统,会根据当前的流量判断出是否需要扩容,怎么样扩容,哪些节点需要扩容。

    监控大盘,大促或是运营活动会有比较清晰的数据做日后的分析。现在都讨论大数据,运营数据也要进入大数据的运算中。

    2015年的目标,主要是VPC的接入,2014年主要做的是兼容Memcached,以前Memcached的业务在我们的系统上也能用。

    明年我们需要做更多的努力是超越Memcached,一个是数据的导入到处,可以通过外部导入,甚至我们可以将我们的数据导入ODPS

       动态的伸缩扩容,目前我们有1G、2G、3G、4G的规格,以后希望大家不需要知道自己跑多少,跑多少就给多少资源;但我们可以秋后算帐,超过的话肯定会扣钱的。还有Redis服务,Redis有liset和Hash,都比较有用。

       接下来给大家分享几个比较经典的案例,或者说是缓存系统上不是特别明显,特别容易解决的问题。

    首先是黑白名单,尤其是黑名单系统,大家的网站都有黑名单,有些人比较讨厌就是不让他访问。怎么办呢?这个名单可能是IP,可能是用户名每次登录和请求都会验证一下,这个验证的量是很大的,每个用户不验证前不知道他是白用户还是黑用户,放在缓存里也没用,因为他的量实在是太小了。

    这个问题的解决办法是以容量来换取性能,OCS卖得很便宜,放再多数据都不怕,就怕命中率低。这个案例中,大家可以把黑用户和白用户都放在缓存里,即使他是黑名单或是白名单,这样的话他下次是不会发生缓存击穿。

    还有一个是Session的共享,这个不用过多的解释,OCS作为同步的工具,我们毕竟是缓存服务,我们没有承诺你的数据不丢,数据丢掉了,用户需要重登录。

    首页,头条缓存,这个例子也是蛮经典的,在我运维的经验里也是发生过几次的,主页上写了一个东西算一下访问主页的人数有多少次,每个人都访问一下,他到我们的系统里做一个加加,就一个Key,分布式系统来说是非常致命的,只访问一个Key,分布式系统对Key进行Hash进入唯一一台机器,这个请求无法做任何的负载均衡,扩再多的机器的都没用,最终他都落在一台机器。虽然系统有保护,不会打垮,对业务来说却是有害的,自我保护以后,用户的请求会被拒绝掉。

    解决办法就是通过业务层面去创造Key的副本,比如说新闻的头条,头条变化得并不是很频繁,他可以创建Key1、Key2、Key3多个副本,只要副本量够大,会打散到多个机器,分布式的性能会被充分的发挥出来。

    这个案例是我来之前才收集到的,用起来也是比较有创意的,其实它也是一个云服务商,架在阿里云之上的云服务商,他想做一件事情,他想限制某些接口的访问频率,比如说某些接口、某些用户每秒只可以调用100次,他用OCS自增的实现,Key是API掉入接口名,与User和当前的时间点拼成一个串,Value放访问的次数,每次加加一下,如果大于100,说明每秒大于100次,访问拒绝,否则就通过。他设的一个过期时间,过十秒钟数据会被自动清理掉,不会因为时间越来越久容量越来越大,他可以做到容量的恒定。

       以上是我给大家介绍的OCS产品,如果大家对OCS的服务感兴趣,或是对TAIR感兴趣的,想加入到分布式存储团队的可以给我发邮件。

时间: 2025-01-29 08:07:34

杨成虎:OCS从分布式到缓存服务的进化的相关文章

阿里云上用上了开放缓存服务OCS

你知道在我们使用的云服务器中哪台最贵吗?跑memcached的缓存服务器(12G内存).你知道保证网站访问速度的功臣之一是谁吗?跑memcached的缓存服务器. 用云服务器这么高贵的内存跑memcached实在太奢侈了,我们一直忐忑不安,但也没有其他选择.现在终于等来了阿里云开放缓存服务OCS,今天晚上完成了部署. 下面分享一下我们的部署过程: 我们之前用的Memcached .NET客户端 EnyimMemcached 就是OCS推荐的.NET客户端,所以应用程序无需作任何修改,只需修改一下

CYQ.Data V5 分布式自动化缓存设计介绍(二)

CYQ.Data V5 分布式自动化缓存设计介绍(二) 前言: 最近一段时间,开始了<IT连>创业,所以精力和写的文章多数是在分享创业的过程. 而关于本人三大框架CYQ.Data.Aries.Taurus.MVC的相关文章,基本都很少写了. 但框架的维护升级,还是时不时的在进行中的,这点从开源的Github上的代码提交时间上就可以看出来了. 毕竟<IT连>的后台WebAPI,用的是Taurus.MVC,后台系统管理用的是Aries. 不过今天,就不写创业相关的文章了,先分享篇技术类

12月9日开放缓存服务(OCS)升级公告

尊敬的阿里云用户: 您好,阿里云开放缓存服务(OCS)将于2014年12月9日21:00-24:00进行系统升级,升级期间用户OCS长连接会出现闪断,自动重连后即可恢复.建议您知晓并提前做好准备. 给您带来的不便,敬请谅解!感谢您对阿里云的支持!   阿里云计算 2014年12月4日

从微博看360诉腾讯案庭审花絮:腾讯一律师叫杨奇虎

360诉腾讯案今日上午在广东高院开庭审理 4月18日消息,奇虎360公司诉腾讯"滥用市场支配地位"的http://www.aliyun.com/zixun/aggregation/5678.html">反垄断诉讼今日上午在广东省高院开庭进行公开审理.众多到场媒体通过微博直播现场庭审进展,不过在剑拔弩张的辩论之余,现场还有不少小花絮,在此做一项不完全列举,供读者在密切关注案件进展时稍事放松. 花絮一.原告拿广东高院在腾讯微博平台直播庭审来说明微博自媒体功能,与即时通讯服务

Lind.DDD.Caching分布式数据集缓存介绍

戏说当年 大叔原创的分布式数据集缓存在之前的企业级框架里介绍过,大家可以关注<我心中的核心组件(可插拔的AOP)~第二回 缓存拦截器>,而今天主要对Lind.DDD.Caching进行更全面的解决,设计思想和主要核心内容进行讲解.其实在很多缓存架构在业界有很多,向.net运行时里也有Cache,也可以实现简单的数据缓存的功能,向前几年页面的静态化比较流行,就出现了很多Http的"拦截器",对当前HTTP响应的内容进行完整的页面缓存,缓存的文件大多数存储到磁盘里,访问的时间直

Laravel框架中实现使用阿里云ACE缓存服务

这篇文章主要介绍了Laravel框架中实现使用阿里云ACE缓存服务,本文扩展了一个ACE缓存驱动,以便使用阿里云ACE缓存服务,需要的朋友可以参考下 之前我写了一篇在 Laravel 4 框架中使用阿里云 OCS 缓存的文章,介绍了如何通过扩展 Laravel 4 来支持需要 SASL 认证的阿里云 OCS 缓存服务.有网友问我,ACE 的缓存怎么在 Laravel 4 中使用.我本来觉得应该可以完全用相同的办法,后来自己尝试的时候才发现,ACE 的缓存差别非常大.所以再写一篇,介绍一下如何在

asp.net SAF 中缓存服务的实现第1/5页_实用技巧

复制代码 代码如下: protected void Page_Load(object sender, EventArgs e)     {         webinfo info = new webinfo();         Response.Write("有static的执行结果:" + webinfo.a + "<br />");         Response.Write("没有static的执行结果:" + info.

Laravel框架中实现使用阿里云ACE缓存服务_php技巧

之前我写了一篇在 Laravel 4 框架中使用阿里云 OCS 缓存的文章,介绍了如何通过扩展 Laravel 4 来支持需要 SASL 认证的阿里云 OCS 缓存服务.有网友问我,ACE 的缓存怎么在 Laravel 4 中使用.我本来觉得应该可以完全用相同的办法,后来自己尝试的时候才发现,ACE 的缓存差别非常大.所以再写一篇,介绍一下如何在 Laravel 框架中使用阿里云 ACE 的缓存服务. 如何扩展 Laravel 的缓存驱动 在 Laravel 4 中使用 Cache::get($

阿里云缓存服务降价50% 性能提升三倍

17日消息,刚刚宣布入门级产品半年免费的阿里云,又将其云缓存服务OCS价格全面下调50%,同时将性能提升三倍.这也是继6月6日数据库产品RDS降价88%后,阿里云基础服务又一次大幅降价. 阿里云方面介绍,此次云缓存OCS同时打出了"降价+升级配置+免费"三张牌,进一步降低云计算服务的使用门槛. 降价:此次阿里云对OCS现有各档产品价格全面下调50%. 升配:此次阿里云将各档OCS的峰值吞吐量和峰值QPS在现有基础上提高3倍.举个例子,以往开通1GB缓存容量的用户,其 OCS的峰值吞吐量