大厂如何打造可扩展的高并发系统?

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

架构设计之初,为什么不预先考虑好使用多少台机器,支持现有并发呢?因为峰值流量不可控。

一般基于成本考虑,业务平稳期会预留30%~50%冗余,以应对运营活动或推广可能带来的峰值流量,但当有个突发事件,流量可能瞬间2~3倍甚至更高。如明星出事,其微博下或围观,或互动,微博流量短时间内增长迅速,微博信息流也短暂出现无法刷新。

架构改造已来不及,最快的就是堆机器。不过需保证,扩容三倍机器后,相应的我们的系统也能支撑三倍流量。

1 提升扩展性会很复杂

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

集群系统也如此。集群系统中,不同系统分层上可能存在一些“瓶颈点”,这些瓶颈点制约系统横向扩展能力。如:

  • 你系统的流量QPS1000,对数据库请求量也是1000qps。若流量增加10倍,虽然系统可扩容正常服务,DB却成瓶颈
  • 单机网络带宽是50Mbps,如果扩容到30台机器,前端负载均衡的带宽就超过千兆带宽限制,也成为瓶颈

无状态的服务和组件易于扩展,而MySQL这种存储服务有状态,难扩展。因为向存储集群中增加或者减少机器时,会涉及大量数据的迁移,而一般传统的关系型数据库都不支持。所以提升系统扩展性很复杂。

需要站在整体架构的角度,而不仅仅是业务服务器的角度来考虑系统的扩展性 。所以说,数据库、缓存、依赖的第三方、负载均衡、交换机带宽等等都是系统扩展时需要考虑的因素。我们要知道系统并发到了某一个量级之后,哪一个因素会成为我们的瓶颈点,从而针对性地进行扩展。

2 高可扩展性的设计思路

拆分,提升系统扩展性最重要思路,把庞杂系统拆分成独立、单一职责模块。 相对于大系统,考虑一个个小模块扩展性更简单。复杂问题简单化就是思路。

不同类型模块,拆分原则不同。如设计一个社区,可能5个模块:

  • 用户 负责维护社区用户信息,注册,登录
  • 关系 用户之间关注、好友、拉黑等关系维护
  • 内容 社区发的内容,就像朋友圈或微博内容
  • 评论、赞 用户可能会有的两种常规互动操作
  • 搜索 用户搜索,内容搜索

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

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

这时,所有模块的业务代码都混合在一起了,数据也都存储在一个库里。

3 存储层扩展性

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

  • 成熟社区的关系的数据量>>用户数据量
  • 但用户数据访问量>>关系数据

所以,假如存储目前瓶颈点是容量,只需针对关系模块的数据做拆分,无需拆分用户模块的数据。所以存储拆分首先考虑的维度是

3.1 业务维度

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

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

这次拆分按

3.2 数据特征水平拆分

如给用户库增加两个节点,然后按算法将用户数据拆分到这三个库。

水平拆分后,即可让DB突破单机限制。但不能随意增加节点,因为增加节点就需手动迁移数据,成本很高。

长远考虑,最好一次性增加足够数量节点,避免后续频繁扩容。

当DB按照业务、数据维度拆分后,尽量不要使用事务。因为当一个事务中同时更新不同数据库时,需使用二阶段提交。协调成本随资源扩展不断升高,最终无法承受。

4 业务层扩展性(服务拆分)

如下维度考虑业务层拆分:

4.1 业务

相同业务的服务拆成单独业务池,如社区系统按业务维度拆分成:

  • 用户池
  • 内容池
  • 关系池
  • 评论池
  • 点赞池
  • 搜索池

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

4.2 业务接口的重要程度

把业务分为:核心池,非核心池。

如关系池:

  • 关注、取消关注接口相对重要,放在核心池
  • 拉黑和取消拉黑操作相对不重要,可放在非核心池

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

4.3 接入客户端类型的不同

如:

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

5 DB 扩展性

传统关系型数据库可扩展性很差,NoSQL如何解决扩展性?

  • memcached没有提供集群特性,一般第三方会使用一致性哈希算法负载均衡,实现集群扩展
  • redis集群选择把数据根据K来哈希分配到固定数量的 slot,然后把 slot 再分配到具体redis实例,来实现集群。需扩展时,只需把 slot 分配一些到新加入的 redis 实例。这种多加一层来实现集群扩展的方式,类似DB分表时的索引表

原文地址:https://cloud.tencent.com/developer/article/2192099

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


学习编程是顺着互联网的发展潮流,是一件好事。新手如何学习编程?其实不难,不过在学习编程之前你得先了解你的目的是什么?这个很重要,因为目的决定你的发展方向、决定你的发展速度。
IT行业是什么工作做什么?IT行业的工作有:产品策划类、页面设计类、前端与移动、开发与测试、营销推广类、数据运营类、运营维护类、游戏相关类等,根据不同的分类下面有细分了不同的岗位。
女生学Java好就业吗?女生适合学Java编程吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练
Can’t connect to local MySQL server through socket \'/var/lib/mysql/mysql.sock问题 1.进入mysql路径
oracle基本命令 一、登录操作 1.管理员登录 # 管理员登录 sqlplus / as sysdba 2.普通用户登录
一、背景 因为项目中需要通北京网络,所以需要连vpn,但是服务器有时候会断掉,所以写个shell脚本每五分钟去判断是否连接,于是就有下面的shell脚本。
BETWEEN 操作符选取介于两个值之间的数据范围内的值。这些值可以是数值、文本或者日期。
假如你已经使用过苹果开发者中心上架app,你肯定知道在苹果开发者中心的web界面,无法直接提交ipa文件,而是需要使用第三方工具,将ipa文件上传到构建版本,开...
下面的 SQL 语句指定了两个别名,一个是 name 列的别名,一个是 country 列的别名。**提示:**如果列名称包含空格,要求使用双引号或方括号:
在使用H5混合开发的app打包后,需要将ipa文件上传到appstore进行发布,就需要去苹果开发者中心进行发布。​
+----+--------------+---------------------------+-------+---------+
数组的声明并不是声明一个个单独的变量,比如 number0、number1、...、number99,而是声明一个数组变量,比如 numbers,然后使用 nu...
第一步:到appuploader官网下载辅助工具和iCloud驱动,使用前面创建的AppID登录。
如需删除表中的列,请使用下面的语法(请注意,某些数据库系统不允许这种在数据库表中删除列的方式):
前不久在制作win11pe,制作了一版,1.26GB,太大了,不满意,想再裁剪下,发现这次dism mount正常,commit或discard巨慢,以前都很快...
赛门铁克各个版本概览:https://knowledge.broadcom.com/external/article?legacyId=tech163829
实测Python 3.6.6用pip 21.3.1,再高就报错了,Python 3.10.7用pip 22.3.1是可以的
Broadcom Corporation (博通公司,股票代号AVGO)是全球领先的有线和无线通信半导体公司。其产品实现向家庭、 办公室和移动环境以及在这些环境...
发现个问题,server2016上安装了c4d这些版本,低版本的正常显示窗格,但红色圈出的高版本c4d打开后不显示窗格,
TAT:https://cloud.tencent.com/document/product/1340