当前位置: 首页 > news >正文

《亿级流量系统架构设计与实战》第二章 通用的高并发架构设计

通用的高并发架构设计

    • 一、高并发系统概述
    • 二、高并发读场景(CQRS模式)
      • 1、数据库读/写分离
      • 2、多级缓存
      • 3、搜索引擎
      • 4、数据宽表
    • 二、高并发写场景
      • 1、分库
      • 2、分表
      • 3、数据分片
      • 4、异步写
      • 5、写聚合

内容总结自《亿级流量系统架构设计与实战》

一、高并发系统概述

高并发系统的三大必要条件:

  1. 高性能(PCT99):响应时间PCTn统计方式,表示请求响应时间按从小到大排序后,第n分位的响应时间。即如果100个请求,从小打大排序后,第99分位的响应时间是100ms,则PCT99=100ms。从经验数据来看,平均响应时间200ms,且PCT99=1s的高并发系统基本能够保证高性能的要求;如果请求的响应时间在200ms以内,用户不会感受到延迟;如果请求响应的时间超过1s,用户会明显感受到延迟
  2. 高可用性(服务几个9):一般用N个9来描述系统的可用性如何,高可用系统至少保证3个9或4个9的可用性,实际的系统指标监控中,很多公司会取3个9和4个9的中位数99.95%作为系统可用性监控的阈值
  3. 可扩展性(服务扩容收益):面对突发的流量,来不及对系统做改造,更快捷有效的做法是增加系统集群中的节点来水平扩展系统的服务能力。可扩展性 = 吞吐量提升比例/集群节点增加比例。最理想情况是,集群节点增加几倍,系统吞吐量就能增加几倍,一般来说70%-80%的比例基本能够满足扩展性要求


二、高并发读场景(CQRS模式)

基本的高并发读场景的解决方案,本质都是读/写分离,这也是微服务架构中经常被提及的CQRS模式。将数据读取操作与更新操作分离的模式。Q为query,C为command,指会引起数据变化(增、删、该)的操作的总称
在这里插入图片描述


特点:

  1. 写数据存储要选用写性能高的存储系统,而读数据存储要选用读性能高的存储系统,所以两者往往有不同的存储模型和存储选型。数据库读/写分离只是一个最简单的特例
  2. 读数据有延迟。写数据存储中数据实时变化,而读数据存储中获取到的最新数据,依赖数据传输通道的传输延迟。无论是消息队列还是定时任务都会到来一定的数据延迟,因此写数据存储和读数据存储仅保证数据的最终一致性

1、数据库读/写分离

路由方式

  1. 基于数据库Proxy代理的方式,如MySQL-Proxy和MyCat
  2. 基于应用内嵌的方式,如gorm,sharding-jdbc

主从延迟与解决方案

  1. 同步数据复制:影响数据库吞吐量,低并发请求业务场景中使用
  2. 强制读主节点:针对主从延迟容忍度低的场景,强制将读请求路由到数据库主节点
  3. 会话分离:某会话在数据库执行了写操作,那么在接下来极短的一段时间内,此会话的读请求暂时会被强制路由到数据库Master,保证每个用户的写操作立即对自己可见

2、多级缓存

添加数据缓存,提高数据查询性能,注意数据淘汰策略,以及数据一致性问题

  1. 添加分布式缓存
  2. 添加单机内存缓存

3、搜索引擎

选定读数据存储和写数据存储后,通过消息中间件为两者建立数据关联。创建一个消费者服务并使消息中间件监听数据库的binlog数据变更日志,当数据有变更时,将最新的数据同步更新到搜索引擎中

4、数据宽表

遇到需要多张表join查询时,提前将多张表关联的数据进行聚合计算,把聚合结果单独存储到一个包含全部关联字段的宽表中,查询时直接读取宽表中的聚合结果,而不用执行join语句



二、高并发写场景

1、分库

用户请求并发大,海量用户访问数据库,很快会达到数据库处理能力的上限,无论是数据库的最大请求连接数、CPU资源、内存资源还是网络带宽均有可能成为性能瓶颈。为解决数据库性能问题,一般会进行分库。

拆分策略:

  1. 垂直分库:按照业务归属将单个数据库中的数据表进行分类,与不同业务相关的数据表被拆分到不同的数据库中,其核心是“专库专用”
  2. 水平分库:将同一个数据库中的数据按照某种规则拆分到多个数据库中,这些数据库可以被部署在不同的服务器上。并且每个数据库拥有哪些表,以及每个表的结构都与拆分前的数据库完全一致

2、分表

当业务发展到一定阶段,数据表存储了千万行甚至上亿行数据,查询性能急剧下降。此外,在涉及数据表结构修复的场景下,DDL语句执行完成消耗的时间令人难以接受。为解决但表的读/写效率问题,一般会进行分表操作。

拆分策略:

  1. 垂直分表:将数据表按照字段(字段访问频率、字段容量大小)分为多个表,每个表存储器中一部分字段;
  2. 水平分表:在同一个数据表中的数据按照某种规则(业务id取hash、数据时间范围、一致性hash环分区)拆分到多个表中,每个表的结果都与拆分前的表完全一致

一致性hash环特点:当增加或移除数据分区是,只有被操作的节点的逆时针相邻的数据需要重新分区。由于一致性哈希分区法并不指定每个数据分区的哈希值范围,所以数据分区在哈希环上分布越均匀,各个数据分区的数据量就越均衡。避免出现“数据倾斜”(存的不均匀)和“热点数据”(读的不均匀)


3、数据分片

类比数据库分库分表外,还有其他数据分片形式

  1. Kafka的多Partition:一个Topic的Partition数据越多,越能增加这个Topic的消息写入吞吐量
  2. 秒杀系统分布式锁、ConcurrentHashMap:将目标对象进行分区分段,即而达成并发量提升

4、异步写

将“用户发起写请求并同步等待结果返回”转变为“用户提交写请求后,异步查询结果”两阶段:

  1. 将用户的写请求先以适当的方式快速暂存到一个数据池中,然后立刻响应用户,告知提交成功,以便缩短写请求的响应时间
  2. 真正的写操作由后台任务不断地从数据池中读取请求并真正执行
  3. 写操作结果依靠用户主动查询,有的业务场景为了提高实时性,也会在写操作执行完成之后主要将结果通知给用户

5、写聚合

将若干个写请求,聚合为一个写请求,减少写请求量。如Kafka的Producer批量生产、AliSQL热点数据优化

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • jmeter 重试机制
  • 抽象代数精解【5】
  • 基于配置实现RoaringBitMap的交、差、并集处理
  • JavaSE第11篇:设计模式
  • Servlet(2)
  • C语言 | Leetcode C语言题解之第321题拼接最大数
  • 免费自动化AI视频剪辑工具
  • 深入解析Apache Flink中的事件时间与处理时间
  • 使用TensorRT对YOLOv8模型进行加速推理
  • 解决方案:Cannot write to ‘torch-2.0.1+cu118-cp310-cp310-linux_x86_64.whl.3’ (成功).
  • 我的256天创作纪念日
  • 《学会 SpringMVC 系列 · 剖析初始化》
  • 学习分享:电商平台 API 接入技术要点深度剖析
  • 分享一个简单线性dp
  • 2024 年华数杯全国大学生数学建模竞赛题目B 题 VLSI 电路单元的自动布局完整成品文章分享
  • Babel配置的不完全指南
  • express如何解决request entity too large问题
  • Javascripit类型转换比较那点事儿,双等号(==)
  • javascript从右向左截取指定位数字符的3种方法
  • JavaScript实现分页效果
  • Object.assign方法不能实现深复制
  • python 装饰器(一)
  • v-if和v-for连用出现的问题
  • vue-cli在webpack的配置文件探究
  • vue数据传递--我有特殊的实现技巧
  • 前端面试之闭包
  • 使用 @font-face
  • 小试R空间处理新库sf
  • 用 Swift 编写面向协议的视图
  • 用element的upload组件实现多图片上传和压缩
  • 用jQuery怎么做到前后端分离
  • “十年磨一剑”--有赞的HBase平台实践和应用之路 ...
  • 积累各种好的链接
  • 浅谈sql中的in与not in,exists与not exists的区别
  • #### golang中【堆】的使用及底层 ####
  • $.ajax中的eval及dataType
  • (+4)2.2UML建模图
  • (10)工业界推荐系统-小红书推荐场景及内部实践【排序模型的特征】
  • (LeetCode 49)Anagrams
  • (安卓)跳转应用市场APP详情页的方式
  • (八)Flask之app.route装饰器函数的参数
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (七)Java对象在Hibernate持久化层的状态
  • (七)Knockout 创建自定义绑定
  • (十五)devops持续集成开发——jenkins流水线构建策略配置及触发器的使用
  • (四)TensorRT | 基于 GPU 端的 Python 推理
  • (四)事件系统
  • (原)本想说脏话,奈何已放下
  • (中等) HDU 4370 0 or 1,建模+Dijkstra。
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .NET CORE 2.0发布后没有 VIEWS视图页面文件
  • .NET Framework .NET Core与 .NET 的区别
  • .NET/ASP.NETMVC 深入剖析 Model元数据、HtmlHelper、自定义模板、模板的装饰者模式(二)...
  • .NET/C# 使用反射注册事件
  • .Net6使用WebSocket与前端进行通信