系统容量评估和性能保障

系统容量评估和性能保障

  • 非功能质量需求的概述
  • 非功能质量需求的具体指标
    • 应用服务器
    • 其他相关指标如下表所示:
    • 数据库
    • 缓存
    • 消息队列
  • 典型的技术评审提纲
    • 现状
    • 需求
    • 方案描述
    • 方案对比
    • 风险评估
    • 工作量评估
  • 性能相容量评估经典案例
    • 项目背景
    • 目标数据量级
    • 量级评估标准
    • 方案
      • 方案1:最大性能方案
        • 需求1. 用户常用地址
        • 需求2. 物流订单和物流记录
      • 方案 2. 最小资源方案
  • 性能评估参考标准
    • 常用的应用层性能指标参考标准
    • 常用的系统层性能指标参考标准
    • 性能测试方案的设计和最佳实践
    • 压测场景设计和压测方案制定
    • 准备压测环境
    • 压测的执行
    • 有用的压测工具

非功能质量需求的概述

核心非功能质量指标,主要体现在高性能、高可用、可伸缩、可扩展、安全性等方面,并讲解其他非功能质 量指标, 例如:可测试性、可监控性等。

核心非功能质量指标如下表所示:

核心非功能质量指标 描述
高性能 运行效率高、性价比高
可用性 持续可用性、缩短岩机时间、出错恢复、可靠性
可伸缩性 垂直伸缩、水平伸缩
可扩展性 可插拔、组件重用
安全性 数据安全、加密、熔断、防攻击

这里,对于一个生产服务,高性能通常指单节点服务的吞吐量和响应时间:可用性以全年 时间减去当年的岩机时间,并用得到的差值除以全年时间计算得出,通常是表明服务质量的最 核心的指标;可伸缩性指横向扩展的能力,也就是随着节点的增加,服务能力能够随着节点增 加而线性增加,如果不能,则也可以使用百分比来衡量;可扩展性通常指架构上的灵活性及可 插拔性,将来可以不断地在系统上叠加新业务和新功能,我们一定要区分可伸缩性和可扩展性 : 安全性指系统 的安全保护措施,要防止攻击和数据泄露等 。

其他非功能质量指标如下表所示:

其他非功能质量指标 描 述
可监控性 快速发现、定位和解决
可测试性 可灰度、可预览、可 Mock、可拆解
鲁棒性 容错性、可恢复性
可维护性 易于维护、监控、运营和扩展
可重用性 可移植性、解耦
易用性 可操作性

这里,可监控性是非常重要的,一个线上服务如果没有监控系统,那么系统的可用性就没 法保障,监控系统可以帮助开发人员和应急人员快速发现问题:可测试性指我们开发的服务 一 定要在不同的阶段有相应的方法和途径来测试,包括 QA 测试、准生产测试和生产测试等 ; 对 于不具备测试条件的系统使用 Mock 等方式来解决;鲁棒性表明系统的容错性、健壮性和可恢 复性:可维护性指系统要易于监控、运营和扩展;可重用性指系统具有模块化、可移植、可通 过迭代增加新功能的特性:易操作性指系统对用户友好,方便系统的各类用户使用 。

非功能质量需求的具体指标

非功能质量需求的具体指标针对不同的系统主要分为 4 部分:应用服务器、数据库、缓存 和消息队列。

应用服务器

应用服务器是服务的入口,请求流量从这里进入系统,数据库、缓存和消息队列的访问量取决于应用服务器的访问量。对应用服务器的访问量进行评估至关重要,应用服务器主要关心 每秒请求的峰值及对请求的响应时间等指标,通过这些指标可以评估我们需要的应用服务器资 源的数量。

部署结构的相关指标如下表所示:

序号 部署结构
1 负载均衡策略
2 高可用策略
3 I/O 模型( NIO/BIO)
4 线程池模型
5 线程池中的线程数量
6 是否多业务混合部署

容量和性能的相关指标如下表所示:

序号 容量和性能
1 每天的请求量
2 各接口的访问峰值
3 平均的请求响应时间
4 最大的请求响应时间
5 在线的用户量
6 请求的大小
7 网卡的l/O流量
8 磁盘的I/O负载
9 内存的使用情况
10 CPU 的使用情况

其他相关指标如下表所示:

序号 其他指标
1 请求的内容是否包含大对象
2 GC收集器的选型和配置

数据库

根据应用层的访问量和访问峰值,计算出需要的数据库资源的吞吐量、每天的数据总量等, 由此来评估所需数据库资源的数量和配置、部署结构等。

部署结构的相关指标如下表所示:

序号 部署结构
1 复制模型
2 失效转移策略
3 容灾策略
4 归档策略
5 读写分离策略
6 分库分表(分片)策略
7 静态数据和半静态数据是否使用缓存
8 有没有考虑缓存穿透 并压垮数据库的情况
9 缓存失效和缓存数据预热策略

容量和性能的相关指标如下表所示:

序号 容量和性能
1 当前的数据容量
2 每天的数据增量(预估容量)
3 每秒的读峰值
4 每秒的写峰值
5 每秒的事务量峰值

其他相关指标如下表所示:

序号 其他指标
1 查询是否走索引
2 有没有大数据量的查询和范围查询
3 有没有多表关联,关联是否用到索引
4 有没有使用悲观锁,是否可以改造成乐观锁,是否可以利用数据库内置行级锁
5 事务和一致性级别
6 使用的数据库连接(如PDO、mysqli等)类型及连接数等配置
7 是否开启诊断日志
8 有没有使用存储过程
9 伸缩策略(分区表、自然时间分表、水平分库分表)
10 水平分库分表实现方法(客户端、代理、 NoSQL)

缓存

根据应用层的访问量和访问峰值,通过评估热数据占比,计算缓存资源的大小并估算缓存资源的峰值,由此来计算所需缓存资源的数量 、部署结构、高可用方案等。

部署结构的相关指标如下表所示:

序号 部署结构
1 复制模型
2 失效转移
3 持久策略
4 淘汰策略
5 线程模型
6 预热方法
7 哈希分片策略

容量和性能的相关指标如下表所示:

序号 容量与性能
1 缓存内容的大小
2 缓存内容的数量
3 缓存内容的过期时间
4 缓存的数据结构
5 每秒的读峰值
6 每秒的写峰值

其他相关指标如下表所示:

序号 其他指标
1 冷热数据比例
2 是否有可能发生缓存穿透
3 是否有大对象
4 是否使用缓存实现分布式锁
5 是否使用缓存支持的加班(Lua)
6 是否避免了 Race Condition
7 缓存分片方法(客户端、代理、集群)

消息队列

根据应用层的平均访问量和访问峰值,计算出需要消息队列传递的数据量,从而计算出所需的消息队列资源的数量、部署结构、高可用方案等。

部署结构的相关指标如下表所示:

序号 部署结构
1 复制模型
2 失效转移
3 持久策略

容量和性能的相关指标如下表所示:

序号 容量与性能
1 每天平均的数据增量
2 消息持久的过期时间
3 每秒的读峰值
4 每秒的写峰值
5 每条消息的大小
6 平均延迟
7 最大延迟

其他相关指标如下表所示:

序号 其他指标
1 消费线程池模型
2 哈希分配策略
3 消息的可靠投递
4 消费者的处理流程和持久机制

典型的技术评审提纲

前面介绍了架构设计中非功能质量需求分析、整理的内容,并给出了非功能质量相关的指标列表,然而,业务项目千差万别,没有一个统一的方法论可指导架构设计和技术评审,架构设计只需要从某些关键点来表达系统,即从大量的需求中识别出核心需求和特色需求,然后针对核心需求和特色需求来设计系统,最后,使用其他需求来验证系统。这里,我们给出非功能质量设计和评审的提纲, 该提纲用于做架构评审,帮助大家整理思路并形成可实施的方案,在做系统设计时,可选择性地参考本提纲,根据业务的特点来完成一个可实现的有效的架构设计 。 下面提供了一个通用的技术架构评审提纲,内容包含需求的业务背景、技术背景及方案的对比 和决策,对于每个方案给出了需要考虑的一些重要的设计点 。

现状

  1. 业务背景
    1:项目名称
    2:业务描述

  2. 技术背景
    1:架构描述
    2:当前的系统容量(系统调用量的平均值、请求响应时间的平均值等)
    3:当前系统调用量的峰值、最小和最大的请求响应时间

需求

  1. 业务需求
    1:要开发或优化的内容
    2:要实现的新需求

  2. 性能需求
    1:预估系统容量(预估系统调用量的平均值、预估请求响应时间的平均值)
    2:预估系统调用量的峰值、最小和最大的请求响应时间
    3:其他非功能质 量 ,例如: 安全性、可伸缩性等

方案描述

整个方案需要参考 非功能质量需求 相关指标来满足系统的非功能质量需求

1:概述

一句话概括方案的亮点,例如 : 双写、迁移、 主从分离、分库分表、扩容、归档、 接口开发或改造等。

2:详细说明

对方案的具体描述, 文字描述不清楚的话可以结合图(指任何图: UML、概念图、框图等)来说明 ,如果是改造方案 ,则最好突出有变动的地方 。 以下列举了描述的角度

  • 中间件架构(应用服务器、数据库、缓存、消息队列等)
  • 逻辑架构(模块划分、模块通信、信息流、时序等)
  • 数据架构(数据结构、数据分布、拆分策略、缓存策略、读写分离策略、查询策略、数据一致性策略)
  • 异常处理、容灾策略、灰度发布、上线方案、回滚方案等

3:性能评估

给出方案的基准数据,并按性能需求评估需要使用的资源数量

  • 单机并发量
  • 单机容量
  • 单机吞吐量的峰值
  • 按照预估的性能需求,预估资源数量(应用服务器、缓存、存储、队列等)、伸缩方式和功能

4:方案的优缺点

  • 列出方案的优缺点,优缺点要具有确定性,不要有“存在一定风险”这种描述,即要量化,有明确的目标和结果

方案对比

对比可选方案,选择倾向的方案,并给出选择这种方案的理由

风险评估

标识所选方案的风险,提出此风险发生时的应对策略,例如上线失败时的回滚策略

工作量评估

描述使用所选方案时需要做的具体工作,并评估开发、测试等细化任务需要的时间,形成可实施的任务计划表,计划表一般从项目计划和人员分配两个角度来管理项目,推荐采用简单的 Excel 表,以减少工具使用和学习的曲线及成本。

性能相容量评估经典案例

我们通过一个互联网物流系统容量评估的案例,应用上面给出的技术评审提纲,来详细介绍互联网容量评估的分析过程。

项目背景

物流系统包含如下两个质量优先需求:

  • 维护用户的常用地址,在下单时提供其地址列表
  • 下单时异步产生物流订单,物流系统后台通过第三方物流轮询拉取物流状态,己下单用户可查询订单的物流订单和物流记录

由于用户量较大且可能有较快的增长速度,同时物流订单量基数较大,促销期峰值时的订单量可能存在上量的情况,因此对这两个需求的业务模块的数据存储需要进行分库分表,并借助消息队列和缓存抗住写和读的流量,本方案主要对这两个业务的容量和性能进行评估。

目标数据量级

选取行业内一线电商平台的量级作为目标

  • 用户量达两亿 , 平均每天增长 5 万个
  • 平时每天的订单量为400万个,下单时段集中在9: 00~23:00,促销时日订单量为1400万个, 50%的下单时段集中在19:30~20:30和22: 00~23:00

量级评估标准

这里列出容量评估的一些通用标准, 需要澄清的是, 这些标准都是在一些老型机器上测试 得出的结果,指标有可能偏小,但是考虑到本节主要是体现容量评估的方法和过程, 而不是关注数据本身的绝对值, 我们保留这些指标数据。

  1. 通用标准

    容量:按照峰值的 5 倍进行冗余计算

    用户的常用地址容量:按照 30 年计算

    数据物流订单的容量:时效性较强,按照 3 年计算

    第三方物流查询接口:吞吐量为 5000/s

  2. MySQL

    单机读:1000/s

    单机写:700/s

    单表容量:5000 万条

  3. Redis

    单机读:40000/s

    单机写:40000/s

    单机内存容量:32GB

  4. Kafka

    单 机 读:30000/s

    单机写:5000/s

  5. 应用服务器

    请求量的峰值: 5000/s

方案

方案1:最大性能方案

由于整个电商网站刚刚上线,还无法清晰地确定数据量级,所以我们根据行业内知名电商的当前数据量级来设计最大性能方案,本方案可以应对行业内电商巨头的各种促销所带来的服务请求峰值,井且拥有最快的响应时间,达到服务性能的最大化。

需求1. 用户常用地址

  1. 整体流程

    提供RESTful服务来增加用户的常用地址

    提供 RESTful 服务来获取用户的常用地址列表

  2. 数据库资源评估

    1. 读操作吞吐量
      在用户每次下单时拉取一次用户的地址列表 ,按照促销时日订单量 1400 万且 50%的下单时段集中在两个小时内计算 :

       (1400万 * 0.5)/ (2 * 60 * 60) = 1000/s (实际结果是972,向上取整)
      

      容量评估按照 5 倍冗余计算

       1000/s * 5 = 5000/s 
      

      读操作吞吐量峰值为 5000/s,则需要 5台数据库服务读。

    2. 写操作吞吐量

      假设每天新增的用户全部增加一次常用地址,并且在高峰期有 20%的用户在下单时会增加一条常用地址:
      (1400万 * 0.2 + 5万)/ (2 * 60 * 60) = 400/s (实际结构是395,向上取整)

      容量评估按照 5 倍冗余计算

       400/s * 5 = 2000/s 
      

      mysql的单机写是700/s,那么我们需要 3台数据服务写。

    3. 数据容量

      当前有两亿用户,每天增长 5万用户, 平均每个用户有 5个常用地址, 30年后用户的常用地址表数量计算如下:

       (2亿+5万*365*30)* 5 = 35亿
      

      容量评估按照 5 倍冗余计算:

       37亿 * 5 = 175亿
      

      Mysql单张表的容量是5000万,则需要350张表存储:

       175亿 / 5000万 = 350
      

      根据以上读操作吞吐量、写操作吞吐量的评估 ,如果读写混合部署 ,则我们共需要 8台数据库服务,可以使用 8主 8备; 考虑使用读写分离, 我们需要做主从部署, 需要 3主 6从, 与两倍数对齐,使用 4主 8从即可。

      据表容量,我们需要 350 张表,和 2 的指数对齐,选择 512 张表 ,上面计算需要主库为 4台,考虑到将来端口扩展时不用拆分数据库,尽量设计更多的库,比如使用 32个库。

      设计结果: 4台机器 x32库 x4表, 4主8从

  3. 缓存资源评估

    为了提升用户下单的体验,需要使用 Redis 缓存活跃用户的常用地址。

    定义当天下单的用户为活跃用户,将活跃用户的地址缓存 24 小时,假定每天下单的用户均为不同的用户,每个用户有 5 个常用地址,每个地址大小为 1KB 左右 ,则缓存大小的计算如下:

     1400万 * 5 * 1KB = 70GB
    

    容量评估按照 5 倍冗余计算

     70GB * 5 = 350GB
    

    单台redis内存容量为32GB,则需要 350GB / 32GB = 11台机器。根据数据库对数据存取的吞吐量的设计,11 台机器完全可以满足 5000/s 的读操作吞吐量和 2000/s 的写操作吞吐量。

    设计结果: 11台,主从

  4. 应用服务器资源评估

    根据数据库的读操作吞吐量( 5000/s)峰值和写操作吞吐量( 2000/s)峰值计算,选择单台应用服务器 即可,选择两台可避免单点。

    设计结果: 2 台

需求2. 物流订单和物流记录

  1. 整体流程

    • 订单提交后,通过消息队列产生物流订单,物流订单消息稍后传入物流系统,物流系统消费物流订单消息然后入库。
    • 后台任务轮询未完成的物流订单,查询第三方物流接口状态,填写物流记录信息 。按照每天产生 1400 万个订单,订单平均 3 天到货,第三方查询接口提供 5000/s 的吞吐量, 则每次进行状态查询需要的时间计算如下: 1400 万 × 3 天 / 5000 = 2 小时,即将任务 定为两小时查一次。
    • 提供RESTful服务获取物流订单信息
    • 提供RESTful服务获取物流记录信息
  2. 数据库资源评值

    • 读操作吞吐量
      在用户下单后三天到货 , 三天内 50%的用户每天会查询一次物流订单和一次物流记录,计算如下:
      (1400万 * 3 * 0.5)/(24 * 60 * 60)= 250/s

      容量评估按照 5 倍冗余计算:

      2 * 250 * 5 = 2500

      Mysql单台读取峰值是1000/s 则需要 3 端口数据库服务读操作。

    • 写操作吞吐量
      用户每次下单时产生一次物流订单 ,按照促销时日订单量为 1400 万,且 50%的下单时段集中在两个小时内计算:

        (1400万 * 0.5 ) / (2 * 60 * 60) = 1000/s
      

      按照每天产生 1400 万个订单,每个订单平均 3 天到货,每条物流订单产生 8 条物流记录,并且 8 条物流记录在 3 天内均匀产生,则物流记录写操作的吞吐量计算如下:

        (1400万 * 3 * 8) / (3 * 24 * 60 * 60) =  1300/s
      

      容量评估按照 5 倍冗余计算:

        (1000/s+1300/s) * 5 = 11500/s
      

      Mysql单台写峰值是700/s,则需要 11500/700=17 台机器来提供数据库服务写。

    • 数据容量

      当前有2亿条物流订单积累,每天增加 400 万订单,则 3 年订单量计算如下:

        2亿+ 400万* 3 * 365 = 46亿
      

      容量评估按照 5 倍冗余计算

        46亿 * 5 = 230亿
      

      则需要 460张表即可容纳。 物流记录表是物流订单的 8倍,为 460×8=3680张表

      根据以上读操作吞吐量和写操作吞吐量,如果读写混合部署,则我们共需要20台机器, 以及 20主 20备: 如果考虑读写分离, 则我们需要 17主 17从。

      根据表容量,我们需要 3680 张表,和 2 的指数对齐后选择 4096 张表 。上面 的计算 需要主库机器为 16,考虑到将来机器扩展时不必拆分数据库 ,我们应尽量设计更多的库,即使用 32 个库 。

      设计结果: 16台 x32库×8表, 16主16从

  3. 消息队列资源评值

    为了让系统能够应对峰值的突增,我们采用消息队列 Kafka接收物流订单。

    根据上面对物流订单写操作吞吐量的计算,考虑 5 倍冗余后峰值为 5000/s,通过单台 Kafka和单台处理机即可处理,考虑到单点,所以至少使用两台 Kafka服务器。

    如果峰值发生突增,则可以增加 Kafka 集群的节点来抗住写流量 ,处理机根据后端入库的性能来决定 。 例如写峰值增加 10 倍,达到 50000/s,则 需要 10 台 Kafka,每台 Kafka 的读吞吐 量可达到30000/s, 理论上需要两台处理机 ,然而,处理机的瓶颈是后端入库的写操作,根据上面 的计算,入库的写操作的峰值按照 5000/s设计,因此,采用单台处理机即可。在这个场景下会 有消息的堆积,但是最终会处理完毕井达到消峰的效果,考虑到单点,至少使用两台 Kafka 处 理机。

    设计结果:两台 Kafka,两台处理机。

  4. 应用服务器资源评估

    根据数据库的读操作吞吐量( 2500/s)峰值和写操作吞吐量(11500/s)峰值计算 ,单台应用服务器峰值是5000/s,则使用 3台应用服务器即可。

  5. 第三方物流查询接口资源评估

    用于查询第三方接口的后台任务服务器,由于受到第三方接口 5000/s吞吐量的限制,使用单台机器即可,为了避免单点 ,使用两台处理机即可。

    设计结果: 2 台

方案 2. 最小资源方案

由于当前系统的线上数据量不多 ,增长量也不大,读操作吞吐量和写操作吞吐量时使用单台机器完全可以处理, 暂时不考虑使用缓存和消息队列,但是保留使用缓存和消息队列时的接 口,如果缓存和消息队列的 资源可用 ,则可以通过开关进行切换 。

当前的数据量使用单库单表即可处理,然而,考虑到将来扩容方便,暂时使用一个数据库机器,但是保留我们在最大性能方案中对数据库的分库分表 。当读操作和写操作突增时, DBA 可 以把库重新拆分到多台机器来抗住写请求流量。

方案如下:

  • 用户常用地址

    设计结果: 1台机器×128库×4表, 1主1从

  • 物流订单和物流记录

    设计结果: 1端口 x512库×8表, 1主1从

性能评估参考标准

设计一个系统时,最重要的非功能质量就是高性能,不但需要进行性能测试,而且需要在设计系统时就对系统各方面的容量进行合理评估,因此,我们需要对一些常用的计算机操作所 需要的时间有个大体的评估,这样才能设计出一个合理且易于实现的系统,从而减小线上系统失败所带来的风险。

常用的应用层性能指标参考标准

以下标准是使用一台测试机的经验值,并不代表使用线上生产机器的经验值,仅供参考,评审时应该根据机器的不同进行调整。

  1. 通用标准

    • 容量按照峰值 的 5 倍冗余计算
    • 分库分表后的容量一般可存储 30 年的数据
    • 第三方查询接口吞吐量为 5000/S
    • 单条数据库记录占用大约 1KB 的空间
  2. MySQL

    • 单机读:1000/s
    • 单机写:700/s
    • 单表容量:5000 万条
  3. Redis

    • 单机读:40000/s
    • 单机写:40000/s
    • 单机内存容量:32GB
  4. Kafka

    • 单 机 读:30000/s
    • 单机写:5000/s

常用的系统层性能指标参考标准

  1. 寄存器和内存

    • 寄存器、 L2、 L3、 内存 、 分支预测失败、 互斥量加锁和解锁等耗时为纳秒级别
    • 内存随机读取可达 30 万次/s,顺序读取可达 500 万次/s
    • 内存每秒可以读取GB级别的数据
    • 读取内存中lMB的数据为250ns,为亚毫秒级
  2. 硬盘 I/O

    • 普通的SATA机械硬盘IOPS能达到120次/s
    • 普通的 SATA 机械硬盘顺序读取数据可达 100MB/s
    • 普通的 SATA 机械硬盘随机读取数据可达 2MB/s
    • 普通的 SATA 机械硬盘旋转半圈需要 3ms
    • 普通的 SATA 机械硬盘寻道需要 3ms
    • 普通的 SATA 机械硬盘在己经寻道后(找到了要读取的磁道,也找到了要读取的扇区) 开始读取数据,读取一次数据真正的耗时为 2ms
    • FusionIO 卡( 一种高的 SSD 硬盘套件〉可达到百万级别的 IOPS
    • 高端机器如 IBM、华为等的服务器配上高端的存储设备,可以达到每秒 GB 级别的数据读取,相当于普通内存的读取速度
    • 固态硬盘访问延迟: 0.1~0.2ms,为亚毫秒级别,和内存速度差不多
  3. 网络I/O

    • 常见的千兆网卡的传输速度为 lOOOMbi的,即 128Mbit/s
    • 千兆网卡读取IMB数据: 10ms
  4. 数据库

    • 读写数据库中的 一条记录在毫秒级别,短则几毫秒,多则几百毫秒,大于 500ms 一般认为超时
    • MySQL 在 4 核心、 256GB 内存的 CPU 中性价比最好,继续垂直扩展时由于体系结构的限制,成本开始增加,提升的性能开始减少,性价比开始降低
  5. IDC

    • 同 一 机房网络来回: 0.5ms
    • 异地机房来回: 30~ 100ms
    • 同一机房的 RPC 服务调用为几个毫秒,有的为几十毫秒或者几百毫秒, 一般设置 500ms 以上为超时。
  6. 网站

    • 网页加载为秒级别
    • UV:每日一共有多少用户采访,用 Cookie Session 跟踪
    • 独立 IP 访问:每日有多少独立IP来访,同 一个局域网可看到同一个 IP
    • PV:每日单独用户的所有页面访问量。如果每日 UV 为 50 000 000,那么每秒的平均在 线人数为50 000 000 / 24 / 60 / 60= 578人,还要知道这一秒内每个用户都在做什么,如果 每秒内都在做一次查询操作,那么需要有一个能承受 578/s 吞吐量的机器
    • 某社交媒体平台每秒的写入量上万,每秒的请求量上百万,每天登录的用户上亿 ,每天 产生的数据量产千亿。
  7. 组合计算和估算

    • 普通的 SAIA 机器硬盘一次随机读取的时间为 : 3ms (磁盘旋转) + 3ms (寻道) + 2ms (存取数据延迟) = 8ms
    • 普通的 SAIA 机器硬盘每秒随机读取 : 1000ms / 8ms = 125 次 IOPS
    • IOPS 代表磁盘每秒可随机寻址多少次,随机读取速度取决于数据是如何存放的,如果数据按照块存放,每块 4KB,每次读取 10 块,那么随机读取速度为: 10 × 4KB × 125 次/s = 5MB/s
    • 一次读取内存 的时间: 1000ms I 30 万次/s= 3ms
    • CPU 速度= 10 倍×内存速度= 100 倍 × I/O 速度
    • 顺序读取普通SATA机械硬盘1MB的数据: 20ms
    • 请记住: 2^10 =1KB, 2^20 = 1MB, 2^30 = 1GB, 2^32 = 4GB

性能测试方案的设计和最佳实践

  1. 明确压测目标

    在做任何事情之前,我们都要先明确目标和目的。对于压测,我们要明确测试目标, 并且尽量让测试目标有量化的标准。

    对于一个系统,最核心的性能指标莫过于响应时间和吞吐量了。响应时间指的是一个请 处理从发送请求到接收响应的总体时间 : 吞吐量指的是单位时间内系统可以处理的请求数量, 这两个指标之间有一定的内在关系,假设系统资源恒定,则它们之间是互斥的。

    假设我们的系统为单线程处理,则响应时间和吞吐量的计算公式如下:

     吞吐量= 1s / 响应时间	
    

    这里,吞吐量是系统每秒处理请求的个数,使用1s除以每个请求的平均响应时间,可得出系统每秒能够处理的请求数量,也就是吞吐量。这个公式是我们后续计算压测模型的重要基础。

    然而,我们所使用系统的 CPU 有多个核心,多个核心的 CPU 通过 Linux 多线程技术可以并行地处理任务,因 此,上面的公式可以扩展为:

     吞吐量=(1s / 响应时间) ×并发数
    

    也就是在并发系统中要达到相同的吞吐量 ,每个请求的响应时间可以延长,但是并发数会增加,这是因为多个 CPU 核心可以同时为不同的请求服务 。

    对一个通用的接口进行性能测试时 ,我们通常关注接 口的响应时间 、吞吐量和并发数, 需要通过测试方法找到系统响应时间、吞吐量和并发数的最佳指标。对于 Web 类型的应用,我们还会关注同时在线的用户数、最大并发的用户数等。

    对于不同的业务场景,我们除了对响应时间、吞吐量和并发数指标有需求,还对系统的可伸缩性、稳定性及异常情况下系统的健壮性等有特殊需求。

    另外,性能测试团队应该与业务团队明确测试范围 ,梳理测试系统的依赖关系,井确定测 试系统 的范围,以及需要对哪些系统使用挡板等。

压测场景设计和压测方案制定

有了压测目标和压测范围以后,我们需要制定压测场景和压测方案。

  1. 业务模型分析

    首先,我们需要对业务模型进行分析,选择日常请求量比较大且路径覆盖范围较广的典 型交易,建立性能测试的业务模型,确定各接口请求量的占比。

  2. 确定测试类型

    在确定了测试的业务模型以后 ,我们需要确定测试类型 。 测试类型根据目标的不同, 一般分为以下 几种方式:

    • 基准测试

      基准测试指对单线程下单接口的测试,主要用于调试测试脚本的正确性,以及查看每个接 口在无压力情况下对每个请求的 响应时间,这个数据作为后续复杂压测场景的基础数据。基准测试一般在几分钟内完成。

    • 容量测试

      容量测试指检查系统能处理的最大业务量,在测试过程中采用梯度加压的方式不断增加并发用户量 ,监控响应时间和系统资源的变化情况,响应时间曲线出现拐点时的业务量就是系统 能处理的最大业务量。容量测试一般在几十分钟内 完成。

    • 负载测试

      负载测试用于测试单个接口在不产生任何错误的情况下能够提供的最佳的系统性能,从而得出单个接口在响应时间满足用户需求时的最大吞吐量和并发数 。压力测试的目的是检查系统能够支持的最大的用户并发量,在测试过程中采用梯度加压的方法,不断增加并发数,监控接口响应时间和状态,当 出现连接数平稳且系统开始超时或出现错误时,便会出现系统性能指标 的衰退点。负载测试一般在几十分钟内完成。

    • 混合业务测试

      混合业务测试指按照业务流程的要求对接口调用按照比例进行编排,并采用一定的测试加压方式进行加压,获取系统对业务流程的最大处理能力,以及每个接口单独的处理能力。混合业务测试一般在几十分钟内完成。

    • 稳定性测试

      高并发的互联网系统,尤其是金融、支付、银行系统,对稳定性的要求比较高,因此需要对这些系统进行稳定性测试 。在稳定性测试的过程中,按照混合测试的业务流程对系统施加 合 理的压力,并持续执行一定时间 。 针对系统的运行情况,判断系统是否健壮、是否存在内 存泄 漏、是否存在较多的上下文切换。最重要的是经过一定时间的稳定性测试,可以发现系统程序 内隐藏的具有时间积累效应性质的 Bug。稳定性测试一般在 12~24小时完成。

    • 异常测试

      异常测试指在依赖服务中断、网络中断、硬件故障等异常情况下,系统对业务的影响情况,例如系统对业务流程的处理是否产生不 一致、系统设计的失效转移是否生效等。

      异常测试没有时间的要求和标准 , 只要看到测试效果即可。

  3. 确定加压后式

    我们使用测试工具模拟系统真实的负载并对系统进行加压时, 一般有如下加压方式:

    • 瞬间加压

      瞬间加压指通过测试工具模拟大量的并发请求,同时将全量负载加压到目标系统的接口,主要考验系统对突发流量的处理能力,也考验系统是否设计了消峰功能和对瞬间大量负载的熔断、限流、隔离、失效转移、降级功能 ,主要应用于类似秒杀、抢购、抢红包等场景中。

    • 逐渐加压

      逐渐加压指模拟通用的线上系统 的压力 。线上系统的压力在一定周期内大体为抛物线的趋势,例如在一天内,从早上开始,系统 的压力会逐渐增加,直到晚上的黄金时间达到最大,然 后逐渐下降。逐渐加压可以最大限度 地模拟这种负载压力的分布情况。

    • 梯度加压

      梯度加压与逐渐加压类似,但是加压目的不同,梯度加压的目的是通过逐渐增加用户并发 量,并观察系统的输出能力,找到最佳或者最大的系统负载。具体指在响应时间满足业务要求 的情况下达到的最优或者最大的吞吐量和并发数。

  4. 确定延时方式
    我们通过测试工具模拟系统的真实负载 , 并对系统进行加压,实际上就是在客户端机器上 发送大量的请求到目标系统,那么我们如何发送请求呢?一般有以下三种方式:

    • 一个请求发送完毕立即发送下一个请求
    • 一个请求发送完毕后间隔固定 的时间再发送下 一个请求
    • 以一定的时间间隔均衡地发送请求

准备压测环境

准备压测环境时,我们需要搭建和配置系统的软硬件,编写和调试测试脚本,以及进行前期的数据准备。

  1. 压测环境的软硬件

    我们秉着与线上软硬件环境相同的原则搭建环境,如果因为某种原因不能与线上软硬件环 境完全一致,则也需要尽量保持与其相似或者相近。这里要注意,压测环境的硬件配置不能高 于线上生产环境,否则测试数据不具备参考意义 。

    另外,不推荐在一台机器上压测,推荐在多个客户端机器上同时对一台或者多台测试 机施压,这样才能达到压测的真正效果。

  2. 压测脚本

    业务方的压测接口多种多样,由于压测时需要使用与接口兼容的客户端进行调用,因此需要开发脚本调用压测接口,并构建测试流程,在构建测试流程的过程中可能需要串联服务或者 聚合服务 ,也可能需要对一些常量的参数进行配置,例如:用户名、密码等,这些都需要在测 试脚本中实现。推荐一个测试脚本包含一个单独的业务流程,便于统计性能结果及在以后重用 。

  3. 数据准备

    根据实际生产情况或者在前面进行的系统容量评估,我们可以确 定测试的数据集大小。

压测的执行

压测的执行指根据我们制定的压测方案,执行各个压测场景的测试用例,并通过观察和 监 控系统资源、数据库、缓存和消息队列的使用情况,判断系统是否满足既定目标,井对测 试过 程中的数据进行记录和分析,形成最终的压测报告 。

我们可以从以下几方面来观察系统的资源占用情况:

  • 系统层面的指标: CPU、内存、磁盘 I/O、网络带宽、线程数、打开的文件句柄、 线程切换和打开的 Socket数量等。
  • 接口的吞吐量、响应时间和超时情况等。
  • 数据库的慢 SQL、 SQL 行读、锁等待、死锁、缓冲区命中情况和索引的使用情况等。
  • 缓存的读写操作的吞吐量、缓存使用量的增加数量、响应时间和超时情况等。
  • 消息列队的吞吐量变化情况、响应时间和超时情况等 。

压测报告主要包含以下内容:

  • 压测过程中记录的压测数据。
  • 分析是否满足既定的压测目标。
  • 指出系统存在的瓶颈点。
  • 提出系统存在的潜在风险。
  • 对系统存在的瓶颈点和潜在风险提出改进意见。

有用的压测工具

  1. ab

    ab 是一款针对 HTTP 实现的服务进行性能压测的工具,它最初被设计用于测量 Apache 服 务器的性能指标 ,特别是测试 Apache 服务器每秒能够处理多少请求及响应时间等,但此命令也 可以用来测试一切通用的 HTTP 服务器的性能。

  2. jmeter

    jmeter 是 Apache 开发的基于 Java 的性能压力测试工具,用于对 Java 开发的软件做压力测试,它最初被设计用于 Web 应用测试,但后来扩展到通用的性能测试领域 。它可以用于测试静 态和动态资源,例如静态文件、 JavaApplet、 CGI脚本、 Java类库、数据库、 FTP服务器, HTTP 服务器等。 jmet巳r是一个性能强大的具有扩展性的测试工具和平台,开发者可以在自己的平台下集成 jmeter,并且根据需求开发和定制 jmeter 的测试用例,可通过阅读 jmeter 主页的文 档对其进行学习。

    jmeter 可以用于对服务器、网络或对象模拟巨大的负载,在不同类别的压力下测试其强度 并分析整体性能。另外, jmeter可以对应用程序做功能测试和回归测试,通过创建带有断言的 脚本来自动化验证程序是否满足要求。为了灵活性 , jmeter 允许使用正则表达式创建断言。

  3. mysqlslap

    mysqlslap 是 MySQL 自带的一款性能压测工具,通过模拟多个并发客户端访问 MySQL 来执行压力测试 ,同时提供了详细的数据性能报告。 此工具可以自动生成测试表和数据,并且可 以模拟读、写、混合读写、查询等不同的使用场景 ,也能够很好地对比多个存储引擎在相同环境的并发压 力下的性能差异。

  4. sysbench

    对系统CPU、磁盘、线程、内存、MySQL 事务性操作 测试

    • CPU 性能测试
    • 线程锁性能测试
    • 磁盘随机1/0性能测试
    • 内存性能测试
    • MySQL 事务性操作测试
  5. dd

    dd 可以用于测试磁盘顺序 110 的存取速度。在应用场景中,打印日志通常表现为顺序 I/O 的写操作,而数据库查询多为磁盘的随机 I/O。

  6. LoadRunner

    LoadRunner 是惠普的一款商业化性能测试工具,通过模拟成千上万的用户同时对目标系统 实施高并发负载 , 井实 时监测系统资源的使用情况及表现的性能指标等方式来发现和定位问题, 是一款专业 的性能和负载压力测试工具 。

  7. hprof

    hprof 是 JDK 自带的分析内存堆和 CPU 使用 情况的命令行工具。实际上, hprof 并不是 一 个可执行的命令,而是一个 JVM 执行时动态加载的本地代理库,力日载后运行在 只币f进程中 。 通过在 NM 启动 时配置不同的选项,可以让 hprof监控不同的性能指标,包括堆、 CPU 使用情 况、械和线程等。 hprof会生成二进制或者文本格式的输出文件,对二进制格式的输出可以借助 命令行工具 HAT 进行分析,开发者可以通过分析输出文件来找到性能瓶颈。

你可能感兴趣的:(架构设计,1024程序员节,架构,软件架构,架构师)