前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >高可扩展性系统的设计

高可扩展性系统的设计

原创
作者头像
JavaEdge
修改2020-10-09 11:27:10
7040
修改2020-10-09 11:27:10
举报
文章被收录于专栏:JavaEdge

文章收录在我的 GitHub 仓库,欢迎Star/fork: Java-Interview-Tutorial https://github.com/Wasabi1234/Java-Interview-Tutorial

架构设计的高可扩展性表示可通过加机器线性提高系统处理能力,承担更高流量和并发。

由于峰值的流量不可控,不可能在系统架构设计初期就考虑好机器数量以支持并发。

一般基于成本考虑,在业务平稳期,会预留30%~50%冗余机器应对运营活动或者推广可能带来的峰值流量,但当有突发事件时,流量可能瞬间提升几倍。莫过于明星公布恋情,大家都会到两人微博下互动,微博流量短时内迅速增长,微博信息流也短暂出现无法刷新消息,系统一时间不可用。

所以如何应对突发的流量呢?

最快的方式就是堆机器。不过能保证扩容三倍机器后,系统也能支撑三倍的流量吗?

系统瓶颈在哪里?

通过在单机系统中增加处理核心,可增加系统的并行处理能力,但当并行任务数较多时,系统会因为争抢资源而达到性能拐点,处理能力不升反降。

集群系统也是这样。不同的系统分层上可能存在一些“瓶颈”,这些瓶颈点制约着统的横向扩展能力。

比如系统流量1000 QPS,对DB也是1000 QPS。若流量增加10倍,虽然系统可通过扩容正常服务,DB却成瓶颈。或单机网络带宽50Mbps,若扩容到30台机器,前端负载均衡带宽就超过千兆带宽限制,也会成为瓶颈点。

所以系统中存在哪些服务会成为系统扩展的瓶颈呢?

无状态的服务和组件很易于扩展,但是MySQL这种存储服务有状态,较难扩展。因为向存储集群中增减机器时,涉及大量数据迁移,一般关系型DB都不支持。

DB、缓存、依赖的第三方、负载均衡、交换机带宽等都是系统扩展时需考虑因素。得清楚系统并发达到某量级后,哪个因素会成为系统瓶颈点,从而对症下药。

高可扩展性设计

拆分,把庞杂系统拆分成独立、单一职责的模块。

注意对不同类型模块,拆分原则不同。假如设计一个知乎,那么会有几个模块呢?至少5个模块。

用户:负责维护社区用户信息,注册,登陆等;

关系:用户之间关注、好友、拉黑等关系的维护;

内容:社区发的内容,就像朋友圈或者微博的内容;

评论、赞:用户可能会有的两种常规互动操作;

搜索:用户的搜索,内容的搜索。

部署方式遵照最简单三层部署架构

  1. 负载均衡负责请求的分发
  2. 应用服务器负责业务逻辑的处理
  3. 数据库负责数据的存储落地

所有模块的业务代码混合,数据也都存在一个库。

存储层的扩展性

无论是存储数据量,还是并发访问量,不同业务模块间量级相差很大。

比如知乎,关系数据量远大于用户数据量,但用户数据的访问量却远比关系数据大。所以假如存储目前的瓶颈点是容量,那只需针对关系模块的数据做拆分,而无需拆分用户模块数据。所以存储拆分首先考虑业务维度。

拆分后,这简单社区系统就有用户库、内容库、评论库、点赞库和关系库。这还能隔离故障,某库挂了不会影响到其它DB。

  • 按DB业务拆分后的部署架构

业务拆分一定程度提升了系统扩展性,但运行久后,单一业务DB在容量和并发请求量上仍会超过单机限制。需针对DB做二次拆分。

这次拆分按照数据特征做水平的拆分,比如给用户库增加俩节点,然后将用户数据拆分库。

水平拆分后,即可突破单机限制。不能随意地增加节点,因为一旦增加节点就需手动迁移数据。所以长远考虑最好一次增加足够节点,避免频繁扩容。

当DB按业务和数据维度拆分后,尽量不要使用事务。因为当一个事务同时更新不同DB,需使用二阶段提交,来协调所有DB要么全部更新成功,要么全部更新失败。

业务层扩展性

一般从三个维度考虑业务层的拆分方案

  • 业务纬度
  • 重要性纬度
  • 请求来源纬度

首先需把相同业务服务拆分成单独业务池,比方知乎,可按业务维度拆分成用户池、内容池、关系池、评论池、点赞池和搜索池。

每个业务依赖独自DB资源,不会依赖其它业务的。这样当某业务接口成为瓶颈时,只需扩展业务池,以及确认上下游依赖方,大大减少扩容复杂度。

还可根据业务接口重要程度,把业务分为核心池和非核心池。比如关系池:

  • 关注、取消关注接口相对重要,可放在核心池
  • 拉黑和取消拉黑的操作就相对不那么重要,可以放在非核心池里面

这可优先保证核心池性能,当整体流量上升时优先扩容核心池,降级部分非核心池的接口,从而保证整体系统的稳定性。

  • 关系池拆分示意图

还可以根据接入客户端类型做业务池拆分。比如服务于

  • 客户端接口的业务可定义为外网池
  • 小程序或者HTML5页面的业务可定义为H5池
  • 内部其它部门的业务可以定义为内网池。

总结

未做拆分的系统虽然可扩展性不强,但简单,无论开发、运维都无需很大精力。拆分后,需求开发需要横跨多系统多团队,排查问题也需要涉及多系统,运维每个子系统都需专人负责,所以大厂招聘也都要求沟通协作能力强。

参考

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 系统瓶颈在哪里?
  • 高可扩展性设计
    • 存储层的扩展性
      • 业务层扩展性
      • 总结
      相关产品与服务
      负载均衡
      负载均衡(Cloud Load Balancer,CLB)提供安全快捷的四七层流量分发服务,访问流量经由 CLB 可以自动分配到多台后端服务器上,扩展系统的服务能力并消除单点故障。轻松应对大流量访问场景。 网关负载均衡(Gateway Load Balancer,GWLB)是运行在网络层的负载均衡。通过 GWLB 可以帮助客户部署、扩展和管理第三方虚拟设备,操作简单,安全性强。
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档