架构师小组交流会是由国内知名公司技术专家参与的技术交流会,每期选择一个时下最热门的技术话题进行实践经验分享。
上期我们分享了当前最具颠覆性的开源技术之一—— Docker 的相关实践 。我们邀请了沪江黄凯、滴滴田智伟、蘑菇街张振华、蘑菇街向靖、扇贝丁彦以及七牛云袁晓沛在上期交流会上分享了各自的经验。
本期话题:高可用架构。高可用性对于有海量用户的互联网产品系统架构至关重要,此次我们邀请到滴滴技术负责人彭令鹏、魅族系统架构师何伟、唯品会应用架构负责人张广平、新浪微博技术专家聂永、大众点评交易平台技术负责人陈一方、七牛云首席架构师李道兵,对高可用话题进行交流,欢迎探讨。
大家好,我是彭令鹏,目前在滴滴平台部负责整个专快车业务的稳定性和效率,之前在百度做了5年半的网页搜索部底层架构的工作。现在在滴滴主要在推四个项目,第一个项目是异地多活 ,第二个项目是全链路压测,为了尽快发现线上的一些容量风险,第三个是一键降级的平台,为了加快止损速度。第四个是服务治理,滴滴的业务也比较复杂,机器和服务规模也越来越大,我们在推一个整体的服务治理工作。
异地多活我们分三期,现在第一期差不多做完了。第一期主要是实现一个同城的 active /standby。我们的数据两个机房都有,流量主要在一个机房,另一个机房只有少量流量,这少量流量主要是保证机房不会因为升级或其他原因,导致它不可用。第二期才会 active-active,比如说两个机房分两半各 50%的流量。第三期是支付这一块,现在不考虑双活,第三期我们会去考虑。当前第一期可以认为 99%的流量跑在一个机房,1%的流量跑在另外一个机房,而且另外那个 1%可能随时会切回来。 数据同步有两大块。第一大块在数据存储这一层,比如说用了 MySQL 的主从复制,还有在我们的缓存层次,为了保证命中率,我们也做了一些双写同步复制。第二个层次,对于部分业务系统,特别是像我们分单,它因为状态比较多,并且依赖的存储也比较多,如果在存储层做的话比较麻烦,所以我们直接在业务层做的双写。 滴滴的业务模式异地多活是比较难的,主要是要求的状态比较实时,打不到车立马就有人反馈投诉,不像购物一样。异地多活,我们一共有三大块技术,第一个是前面说的数据同步。第二个就是流量路由,前面说的 99%和 1%的流量的一个分配。第三大块我们在做降级,降级包括一个最小系统,如果数据同步真出了问题,我们会用端上面的一些数据来做补偿,反正整体还是很难的,因为订单状态机这一块还是比较复杂,状态比较多。
我是魅族科技何伟,负责基础架构技术平台。魅族的互联网业务主要是用户数据同步,应用商店,音乐、视频等等,然后是 push 服务,push 服务每天也有几个亿的推送。我们也在做全链路压测、容量管理,后面会准备上容器这一块,现在还是 VM 的。全链路压测我们现在正在做,简单讲一下,在入口时我们会去对流量打标记,就是着色,然后我们就能把流量根据这个着色把它调度到某一个指定的节点,在系统的各个层级我们都可以去做调度。我们不是像 TCPCopy 那样工作。我们的做法是把流量引到某个节点,去压某个节点的极限容量,然后我们就能看到我们的流量到底要多大的集群才能扛得起来。
大家好,我是李道兵,负责七牛存储的技术架构。七牛是多数据中心,在全国有数个存储区域,每个存储区域有多个核心的存储机房,这些机房的规模都比较大,用于存储客户的数据。将数据存放于一个数据中心内的风险很大,如果数据中心断电、断网,会造成数据的不可用,如果一个数据中心发生灾难性事故,还可能会造成数据丢失,所以七牛使用了双数据中心的互备技术。我们将两个数据中心用裸光纤互联,当用户上传文件到某个数据中心时,系统异步将文件数据和相关原数据同步到与之互备的另一数据中心,这样当一个数据中心故障时,我们会根据故障的级别启用不同的应急预案,将请求切换到与之互备的数据中心。
我是来自新浪微博的聂永,现在负责微博客户端 IM 消息下推系统基础设施的维护和优化。前段时间还参与了公司的一个性能测试系统的建设,为系统性能提供完整压测支持,举一个例子,以前做过一个聊天室项目。我们对这个聊天室所有的功能接口都会一一地进行测试,并且会完整的模拟用户从上线到离线这个中间过程之中所有的全链路交互,并且设定每一个交互的执行的次数,这个要先去梳理用户在实际操作的所有行为。比如我们执行一次完整全链路压测,其中每个用户至少能持续 30 多分钟,压测强度还是很大的。同时,我们在做压测的时候,其实完全可以拿手机,和模拟的用户一同参与到压测情景中来,这样就可以以终端用户的角度,去切身体验我们的系统的稳定性,终端操作的流畅程度等。我们当时单机是直接的执行 50 万用户的压力测试,然后线上执行 100 万用户容量压测。
大家好,我是张广平,唯品会应用架构负责人。最近在做一个核心系统的重构。采购的一些商品,怎么去选购到我们销售环节去售卖,这时候就涉及到,怎么把我的库存导进来?怎么把我的商品导到销售环节,让用户能看得到?用户去浏览商品详情页面,怎么去做收藏?还有就包括结算购物车、订单支付、促销,我们把这些项目,作为我们的核心系统重构的第一阶段。这些系统重构了以后,其他的外围的系统,包括采购、物流都做一些调用。
唯品会这几年发展非常快,基本上每年的量都在翻跟头,之前主要还是靠硬件去顶,以前的应用程序主要还是 PHP。通过我们这次的重构,这次 双11 效果非常好,虽然碰到了一个购物车刷单的事件,但我们核心系统还是比较争气,顶下来了。谈一下刷单,刷单是需要综合地去防治,我们是从入口上判断一些请求,这些请求如果发现它是有风险的,我们会去做限流措施。因为我们的系统从入口的地方还没有一个整体的重构设计,所以有些流量进来,比如说流到购物车,购物车要去调用我们目前一些商品查询,包括库存价格之类的,对后台系统压力特别大。
我们当时是针对用户的请求去做一些分析,看看他的 IP 地址,调用我们的风控模块之类的,但是这一次没有防得住,因为量太大。我们系统相对来说比较健康的,这些进来的请求应该还是一些合理的请求,所以没有过多的限制。真要是扛不住,我们会去做系统限流、系统降级之类的。我们的 OSP 框架有一个比较有特色,我们对访问的服务做限流,比如量达到多少以后我们把后面的请求关闭,这样是保证我们正常的应用能运转下去,不然会导致后面的商品查询服务、库存、价格,会瘫掉。
两年半以前我来唯品会的时候,清一色的 PHP,只有个别团队在用尝试 Java 做开发,但是 PHP 是主流,那时候我们面临一个 PHP 在扩展性方面的问题,尤其是它的框架,版本很多,用起来性能很差,基本上 QPS 都是在七八百左右,能上千的都很少,基本上压到 1000 左右就崩掉了。我们投入了大量的一些硬件资源,但是发现问题不断。后来组建了一个基础架构团队,从基本的服务化框架、消息框架、配置中心,还有监控模块、安全一系列都做了开发,两年多以来我们现在基本上产品都有了。尤其是比较有特色的,是我们的 OSP 框架。这个框架主要是基于 thrift,滴滴的那位同学也提到了 thrift。我们 OSP 的框架也是一个 thrift 的长连接,一个 RPC 的框架。我们是作为应用架构在使用 OSP。QPS 从七八百,现在上万是非常轻松,比较简单的查询,可以到五六万级别。我们每次大促都要增加好多机器,但是这次 双11 是省下来了,还把老的系统淘汰了下来。虽然对周边没有重合的一些系统做了扩容,总体省下来了,没有去增加新的资源。我们这个重构还是值得的,我们的 OSP 框架扛到现在,这次 双11 没有出现问题。
我是陈一方,来自大众点评。我原来是交易平台的,主要负责几个团队,优惠团队、订单团队和整个支付团队。现在负责整个点评的团购平台,这几年一直在做高并发的规模化的 C端 系统,B端 系统也做了一些营销系统和结算系统。原来点评美团分别有个支付平台,融合以后,上海的支付也就是我负责的支付平台,会交到北京去。 新美大有一个支付,刚拿到牌照,原来是没牌照,但是我们是有支付团队的,做整个支付后端的能力建设,比如说支付通道、账户体系,还有前端统一支付的。支付后端挺复杂的,后端主要分 3 块,第一块就是支付资金渠道来源,资金渠道这块,比如支付宝,微信或银联或者任何支付通道,我们叫它支付资金渠道,这块是管理资金通道的。第二块是管理用户账户体系,因为支付会有一些资金的往来,所以你必须有明细账户,所以会有账户体系。第三块是面向公司类的业务聚集的,业务网关和支付网关。业务接入我们怎么支付,他只需要接入我们网关就可以了。网关提供能力有两种,有一种是 API 的模式在接入的,现在大部分是以那种组件,前端组件,比如 native 的话,我们就直接有收银台,你只需嵌进去就行,什么都不需要做。早期我们是 Call API,因为那时候没有客服端的开发,后期的话,我们 iOS 逐渐成熟了,我们后面 API 全部都上了,用那种产品化平台化的模块来接,因为这样的话自动挂了我们切支付,或者是做支付上的营销,那时候他非常好做,产品化的一个过程。
Q: 关于全链路压测大家是怎么做的,数据是怎么处理的?生产的数据和测试的数据是放一起还是隔离的?
滴滴彭令鹏: 魅族的全链路压测是压单个节点的极限,这与我们稍微有点不同,其实我们也有一个类似的做法,就是常态我们在调度的时候,可能会在地图那种业务上面放置一个哨兵节点,这个哨兵结点的流量会比别人高一点,以便提前去发现一些问题,这点和魅族类似,但是我们的压测不是这样的,我们的压测是真正直接打到整个集群,就是线上集群,和正常业务是一样的。我们的用户行为也尽可能和正常用户一致,只是打上了特殊的标记,但是其他处理行为是完全一致的,除了发券等那些和钱相关的。测试的是生产集群,这样做的目的是想真正去看这个生产集群的一个容量水平。这个和看单个节点的极限我觉得可能有点不一样。以前我在百度的时候,因为每个模块都很大,全系统的模块没几个,所以可以通过单模块的情况直接去推导整个系统,是不是全链路容量都是够的。但是来了滴滴以后,因为滴滴的业务,每一类小的接口都独立成了服务,这就导致它的服务特别多,整个全链路下来可能有几十个,所以不直接去压一压其实还是有很多问题是看不出来的。
大众点评陈一方: 我的经验跟滴滴是一样的。我们也是压测单机的容量,在线生产环境的时候不一定是按等比例放大的,所以你压一台机子它支持 1000 QPS,但是你 10 台不一定能支持 1 万的 QPS,确实有这个问题,因为它的链路太长,无法用。比如说一个节点是 10,第二个加入集群中它不是不是线性扩大 。
滴滴彭令鹏: 我们这边的做法,第一我们在流量的模拟方面也是基于用户的历史数据去回放,打上特殊的标记,这个标记会从链路的最前端到最后端,全部染色上。针对标记的流量,我们的数据有几类处理:第一数据库这块我们是在一个 proxy 这样的中间件里面,直接把数据写到了一个影子表里面,相当于表级别隔离。第二个是缓存这块,因为缓存数据都会以司机的 ID、用户的 ID、订单的 ID、坐标,作为 key 的组成部分,我们所有的测试数据对这些 ID 做了一个偏移,比如对于坐标,我们可能直接把这个坐标偏移到太平洋上面的一个地方,不会是真正的一个城市,这样保证我们的缓存调用者不用改,数据就可通过 key 直接隔离开。第三个是消息队列,我们会通过 kafka 订阅和消费消息,我们会改造生产者,让他们将消息写到一些虚拟的 topic 上去。压测完了以后,我们可能需要做数据清理,但是因为滴滴现在存储空间这一块其实并不是特别瓶颈,所以清理我们基本上不用做,当前是这样子。
Q: 我们在谈压测,很多系统有第三方服务的,比方说第三方支付,对接外部的银行,没办法要求第三方服务配合你,那这个时候你们怎么办?
大众点评陈一方: 第三方有两种做法,一种做法就是,如果它不是一个强依赖的话,你就直接把它关掉,最高峰的时候肯定不够用,你就把他降级。这是第一个,第二个像支付,他强依赖的话,系统第三服务方会给你 SLA,你根据它的极限值往下压就行了,如果他那个值没达到,你找他去,他达到了,你那就算了。
滴滴彭令鹏: 我们是这样子的,因为有一种场景,虽然支付那边会给你承诺 SLA,但我们的系统容量可能是高于它的。那这个时候怎么压呢?我们本身的压测是分为两期的。第一期,是在分单以前的压测,第二个是整个全链路。分单以前压测,是当流量到了分单系统以后,直接把它截断,从而保证这样的一些流量,不会走到下游去,对于支付也是一样的,你可以在支付模块的上游那里做一个截断。
Q: 做高可用有一个指标,就是要达到五个 9。但最后在落地时,在多一些场景上面这些指示有实际测量吗,后面有没有一个定论去达到这个要求,或者没有达到这个要求?
滴滴彭令鹏: 滴滴现在这边,当前是三个 9 多一点点。我们未来 2017 年的一个目标也就是三个 9 一个 5。对消息交易系统来说做到四个 9 很难。落实这一块第一是我们有一个专门的第三方组织,来整体评比各个部门的稳定性指标,做得还是比较严的。第二个是老大们对这一块特别重视。
大众点评陈一方: 我们跟滴滴挺像的,我们也是第三方的,比如运维部部或者质量部,他会给你出报表,因为它的报表是一周或者一个月的,我们现在交易系统,要求四个 9,但是我们其实达到三个 9 多一点。高层管理会看这个指标,中层也会看这个指标,然后这样叠在每个基层,他也会看这个指标,所以这样已经形成一个机制了。