大咖连载|可扩展性设计(一)

没关注?伸出手指点这里---

作者|华为云微服务架构师 王启军

本文节选自《持续演进的 Cloud Native 云原生架构下微服务最佳实践》

可扩展性的重要程度在很多系统中往往被低估,扩展性是衡量系统架构优劣的一个非常重要的判断指标,但是也不能盲目追求扩展性,还要兼顾成本,以下的示例将会告诉我们可扩展性设计的重要程度。

Facebook在2009年每天产生3千万张照片;2013年每天产生3.5亿张照片;2015年产生20亿张照片。

阿里巴巴2009年首个双十一一天内销售额为5000万;2012年双十一一天内销售额为191亿;2017年双十一一天内销售额为1682亿元,11秒内即破亿。

看到这两组数据,我们仅仅通过增加机器就能解决问题吗?

加机器能解决问题吗

任何一个系统,随着业务的快速发展,都需要考虑或解决扩展性的问题。系统是否可以做到流量来临的时候通过扩展避免宕机,甚至不降低用户体验,很多互联网公司在用户规模增长速度比较快,技术积累不足的阶段都发生过宕机事件。比较典型的例子是聚美优品为了庆祝三周年,做了大量宣传、广告,受到了大量关注。为了应对流量的爆发聚美方面多次为服务器扩容,并制定了详细的技术应对方案,老板陈欧在微博中写道:“我们的后台已经准备好了宕机出现,如果真的出现宕机就给技术人员每人发一把刀切腹”。 但是当促销真正开始的时候,出现了大量宕机事故,网页无法打开、永远都在排队中,用户戏称:“我终于明白了聚美优品三周年,打破低价你想不到的折扣这句广告词的真谛,就是价格多低我也进不去看不见”,甚至有的用户认为宕机是阴谋,为了“少赔点儿”,对于用户来说宕机是难以理解的。

另外一个例子,京东初期,和当当网、苏宁、国美频频发生“价格战”,京东商城CEO刘强东通过微博宣称:“京东商城所有大家电将在未来三年内保持零毛利,并保证比国美、苏宁连锁店便宜至少10%以上。”苏宁易购立即开始进行反击,苏宁易购执行副总裁李斌通过微博宣称:“包括家电在内的所有产品价格必然低于京东。”活动开始不到10分钟,由于服务器瞬间流量暴增,苏宁官网和苏宁易购就出现访问困难和无法登录的情况,整个促销伴随的是服务器频频宕机、网站打不开。

从上面的两个例子能够看出,扩展性是多么重要。到了关键时刻绝不仅仅是加机器这么简单。

横向扩展

我们也可以把加机器得到的性能提升叫做横向扩展。

横向扩展(scale out)也叫水平扩展,指用更多的节点支撑更大量的请求。例如1台机器支撑10000TPS,两台机器是否能支撑20000TPS?

纵向扩展(scale up)也叫垂直扩展,扩展一个点的能力支撑更大的请求。通常通过提升硬件实现,例如把磁盘升级为SSD。

横向扩展通常是为了提升吞吐量,响应时间一般要求不受吞吐量影响即可。因为本身在访问量比较小的时候,响应时间就是可接受的范围,例如去分布式缓存get一条数据的响应时间在毫秒级,理想情况如图5-1所示,只要在吞吐量不断提升的情况下保持这个响应时间就可以。当然,响应时间和吞吐量在资源一定的情况下,通常是互斥关系,如果要降低响应时间,可以通过纵向扩展,提升单机能力,或者改变数据存储结构,压缩等方式。

 

图 5-1 响应时间和吞吐量随节点数变化关系图

AKF扩展立方体

提到可扩展性,就不得不提著名的AKF扩展立方体(Scalability Cube),AKF是ebay前副总裁Martin Abbott在《The Art of Scalability》一书中的经典理论,作者把系统在架构上的扩展性按照三个维度进行说明,如图5-2所示。

 

图 5-2 AKF扩展立方体

下面我们通过表格5-1简单说明一下三个轴适用的场景、优势及挑战。

表格 5‑1 AKF扩展立方体

下面我们可以用一个例子来说明,系统是如何从初期一步步扩展的。假设,我们现在要开发一个微博系统。

第一阶段。产品初期,可能我们只有十人左右的团队,还没有用户,需求也不确定。如图5-3所示,此时我们只需要通过单体架构实现,为了容灾,我们可以在前端放置一个负载均衡服务,后端采用两个服务。数据库为了容灾也可以采用Master-Slave的架构。

图 5-3 单体架构,按X轴扩展

随着用户访问的快速增长,当系统出现性能瓶颈的时候,我们此时采用的是X轴的扩展方式,通过不断的克隆service,增加service的数量来应对。当数据库出现瓶颈的时候,我们可以做读写分离。这就是按照X轴扩展的思路。

第二阶段。用户快速增长,产品需求快速增加,研发团队可能会接近百人,沟通效率越来越低,数据库主从延迟问题开始暴漏,磁盘压力逐步加大。为了缓解这些问题,首先,作为过渡阶段,可以再增加业务服务实例的数量,数据库可以通过提升硬件的性能暂时抵抗压力。另一方面,我们开始按照业务领域拆分服务,如图5-4所示,每个服务独享一个数据库,接口是服务与外部联系的唯一通道。这样既降低了耦合度,提升了沟通效率,又可以缓解数据库的压力,实现分库操作。但是,在数据库中,单表的数据量持续增长,假设我们用MySQL,随着数据量的增加,响应时间变长,吞吐量下降,此时我们首先会进行垂直分表,例如用户表有100个字段,但是我们常用的可能是10个字段,我们会按照一对一的方式拆分为两张表。可以参考微服务架构拆分的相关内容。这就是按照Y轴扩展的思路。

 

图 5-4 微服务架构,按Y轴扩展

第三阶段。随着用户规模的快速增长,数据库成为了性能瓶颈,如图5-5所示,我们会通过MQ削峰填谷,解决写的性能瓶颈,通过分布式缓存解决读的性能瓶颈。在数据库一侧,我们会对表进行水平拆分,例如,我们有3千万用户数据,可以根据用户ID拆分为4张表,每张表750万条数据。为了解决拆分带来的复杂性,可以通过数据库中间件屏蔽底层分表细节。当然,这时候很可能会遇到数据中心的容量瓶颈,促使我们去建立多数据中心,按照用户的地域去切分数据,让数据离用户更近一些。这就是按照Z轴扩展的思路。

 

图 5-5 Z轴扩展

如何扩展长连接

在微服务章节,我们已经了解到服务无状态的意义。但是有时候并不是所有的状态都可以外置,例如长连接。当长连接遇到负载均衡的时候就会变得非常复杂。

首先,应该尽量减少长连接,实际上并不是每个应用都需要那么及时。大部分都可以通过短连接搞定。例如电商的App,所有的浏览、下单都可以基于短连接实现,极少需要长连接。

如图5-6所示,我们假设要设计一个微博App客户端和服务端的交互。当我关注的人发了一条微博,此时如果我不在线,并不需要马上收到,完全可以当我上线的时候通过短连接去拉取消息。但是,如果我正在看微博,应该提醒我有几条新消息,这个通知是需要及时性的。

 

图 5-6 微博App客户端和服务端的交互

当然,及时性消息也不一定非得是长连接,也可以采用定时轮询的方式。实际上,在真实的生产环境,为了保证到达率,通常需要长连接和短连接配合,因为长连接在网络条件不好的情况下,经常会出现各种各样的问题,导致不能及时到达,通过轮询心跳的方式可以定时拉取消息,缓解长连接推送失败的问题。

那么,问题来了,当其中一个push服务挂掉的时候,客户端应该作何反应?

常用的方案有两种:反向代理和注册中心。

反向代理

如图5-7所示,可以在client和push之间增加一层反向代理服务,client并不知道具体的push服务,通过反向代理服务转发,另外反向代理也兼具负载均衡的作用。

图 5-7 反向代理

注册中心

如图5-8所示,如果现在存在一个注册中心,就可以client在连接push服务的时候,先到注册中心获取可以连接的列表,然后再根据push服务的地址去连接push服务,这样,如果一个push服务挂掉,就可以让client连到另外一个push服务了。

图 5-8 注册中心

如果需要推送的消息量太大,可能会导致雪崩,我们需要限流,业界普遍会在推送服务前增加MQ以削峰填谷。

还有另外一个问题,当推送消息的时候,肯定要知道通过哪个push服务去推送,因为client不可能和所有的push服务建立长连接,单机的连接数是有限的,如何记录client和push的对应关系呢?

方法一、记录client和pushserver的映射关系。如图5-9所示,将关系数据放入缓存。

优势:扩容可以不用影响现有节点连接。假设现在有两个节点,扛不住压力了,扩容到3个节点,此时我们只需要把新的连接连到新的节点,已经存在的连接可以不用断开重连。

劣势:需要维护client和pushserver的映射关系。

图 5-9 消息推送映射关系

方法二、根据节点总数计算映射关系。

优势:简单。只需要知道现在一共有几个pushserver,根据ClientID对总节点求余、一致性哈希或者根据用户ID的范围,就应该知道应该推送到哪个节点。

劣势:首先,如果扩容需要断开一批连接,重新连到新的pushserver节点,有中断的可能。其次,如果根据范围计算,有可能存在热点,某个pushserver压力很大,而其他节点比较轻松。最后,如果一旦push节点挂掉,就要重新建立连接。有时成本是比较高的,假设我们一共有4个节点,监控到一个节点故障,此时要把这个节点的连接转移到其他三个节点,一旦故障节点恢复,因为三个节点压力较大,我们又要再让客户断开连接,连到新的节点。如图5-10所示,如果我们建立几个冗余节点,一旦发生故障,迅速把back节点顶上来,后面故障节点恢复后可以作为back节点。

图 5-10 备份节点

End

本文为作者原创文章,未经作者允许不得转载。

分布式事务实现方案阿里巴巴fescar、华为servicecomb-pack对比分析

浅谈服务化和微服务化(上)

浅谈服务化和微服务化(下)

为什么总觉得微服务架构很别扭?看看命中几条

《持续演进的 Cloud Native 云原生架构下微服务最佳实践》正在热卖中!快来抢购哟~

当当:

http://product.dangdang.com/25577028.html

京东:

https://item.jd.com/12452009.html

点击下方“阅读原文”给ServiceComb加个Star吧!☺

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值