前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >大厂如何打造可扩展的高并发系统?

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

作者头像
JavaEdge
发布2022-12-13 16:32:43
3700
发布2022-12-13 16:32:43
举报
文章被收录于专栏:JavaEdge

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

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

一般基于成本考虑,业务平稳期会预留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分表时的索引表
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-12-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

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

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1 提升扩展性会很复杂
  • 2 高可扩展性的设计思路
  • 3 存储层扩展性
    • 3.1 业务维度
      • 3.2 数据特征水平拆分
      • 4 业务层扩展性(服务拆分)
        • 4.1 业务
          • 4.2 业务接口的重要程度
            • 4.3 接入客户端类型的不同
            • 5 DB 扩展性
            相关产品与服务
            对象存储
            对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档