“天下武功出少林”,如果说少林易筋经就是各种武学的内功,各种拳法剑法是外功,那么对于计算机而言,计算机基础知识就是计算机界的内功心法,各种提高能效的框架、中间件则为外功拳法剑术,而其中性能优化和容量评估又是高级工程师和架构设计人员的必备重要外功之一。
1.ATAM
ATAM,即互联网架构权衡分析方法(Architecture Tradeoff Analysis Method),它是评价软件架构的一种综合且全面的方法,它不仅揭示了架构满足特定质量目标的情况,而且可以使我们更清楚的认识到质量和目标之间的制约和权衡。ATAM是一个能够在项目开始实施之前评估架构是否能够满足这些非功能质量的方法论。我们将应用ATAM来评估系统的容量和性能。
2.非功能质量指标
首先,我们了解一下什么是非功能需求。非功能需求包含:高可用性要求、性能要求、可伸缩需求、可扩展性、安全性、稳定性、可测试性、可监控性等等。
高性能、高可用性、可伸缩性、可扩展性、安全性是核心非功能需求:
- 高性能:高性能指单节点服务的吞吐量和响应时间。
- 可用性:持续可用时间,以全年时间减去当年的宕机时间,将计算差值除以全年时间。
- 可伸缩性:主要指横向扩展能力,随着节点增加,服务能力能够随着节点增加而线性增加。
- 可扩展性:主要指架构上的灵活性以及可插拔性。将来可以不断地在系统上叠加新功能和新业务。
- 安全性:系统的安全保护措施,要防止攻击和数据泄露。
其他非功能质量指标包含:
- 可监控性:便于快速发现、定位和解决问题。
- 可测试性:可单元测试、可mock、可灰度。
- 稳定性:容错性、可恢复性。
- 可维护性:便于维护、监控、运营和扩展。
- 可重用性:可移植、可解耦。
- 易用性:可操作性,用户界面友好、方面系统的各类用户使用。
3.服务容量与性能指标
3.1.应用服务器容量和性能指标
应用服务器主要关心每秒请求的峰值和请求的响应时间指标。通过这些指标可以评估我们需要的应用服务器资源的数量。
容量和性能相关指标如下:
- 请求量:主要指每天的请求量。
- 访问峰值:各个接口的访问峰值。
- 平均响应时间。
- 最大响应时间。
- 请求大小。
- 网卡的IO流量。
- 磁盘的IO负载。
- 内存使用情况。
- CPU使用情况。
- 在线用户数。
其他指标:
- 请求内容是否包含大对象。
- GC收集器选型和配置(堆栈设置)。
应用服务器部署结构检查项:
- 负载均衡策略。
- 高可用策略。
- IO模型(NIO/BIO)。
- 线程池模型。
- 线程池中的线程数。
- 是否多业务混合部署。
3.2.数据库的容量和性能指标
数据库容量和性能指标:
- 存量:当前的数据容量。
- 增量:每天的数据增量(预估容量)。
- 读峰值:每秒的读峰值。
- 写峰值:每秒的写峰值。
- 事务峰值:每秒的事务量峰值。
其他相关指标:
- 查询是否走索引。
- 有没有大数据量的查询和范围查询。
- 有没有多表关联,关联是否用到索引。
- 有没有使用悲观锁,是否可以改造成乐观锁,是否可以利用数据库内置行级锁。
- 事务和一致性级别。
- 使用的JDBC数据源类型及连接数等配置。(设置多少合理)
- 是否开启JDBC诊断日志。
- 有没有存储过程。
- 伸缩策略(分区表、自然时间分表、水平分库分表)。
- 水平分库分表的实现方法(客户端、代理、NoSQL)。
数据库的部署结构检查项:
- 复制模型。
- 失效转移策略。
- 容灾策略。
- 归档策略。
- 读写分离策略。
- 分库分表策略。
- 静态数据和办静态数据是否使用缓存。
- 有没有考虑缓存穿透并压垮数据库的情况。
- 缓存失效和缓存数据预热策略。
3.3.缓存容量和性能指标
根据应用层的访问量和访问峰值,通过评估热数据占比,计算缓存资源的大小并估算缓存资源的峰值,由此评估缓存资源的数量、部署结构、高可用方案。
缓存的容量和性能指标包含:
- 大小:缓存内容的大小。
- 数量:缓存内容的数量。
- 过期时间:缓存内容的过期时间。
- 数据结构:缓存的数据结构。
- 读峰值:缓存的读峰值。
- 写峰值:缓存的写峰值。
其他指标:
- 冷热数据比例。
- 是否有可能发生缓存击穿。
- 是否有大对象。
- 是否使用缓存实现分布式锁。
- 是否使用缓存支持的Lua脚本。
- 是否避免了Race Condition。
- 缓存分片方法(客户端、代理、集群)。
缓存部署结构考核项:
- 复制模型。
- 失效策略。
- 持久策略:是否对缓存数据进行了持久化。
- 淘汰策略:比如LRU淘汰策略。
- 线程模型:比如NIO or AIO。
- 预热方法。
- 哈希分片策略。
3.4.消息队列的容量和性能评估
MQ的容量和性能指标:
- 增量:每天平均的数据增量。
- 持久过期时间:消息持久的过期时间。
- 读峰值:每秒的读峰值。
- 写峰值:每秒的写峰值。
- 消息大小:每条消息的大小。
- 平均延迟。
- 最大延迟。
其他指标:
- 消费者线程池模型。
- 哈希分片策略。
- 消息的可靠传递。
- 消费者的处理流程和持久机制。
MQ部署结构考核项:
- 复制模型。
- 失效转移。
- 持久策略。
4.案例分析
我们通过物流系统进行容量评估,给出技术评审大纲。
4.1.现状
4.1.1.业务背景
- 物流系统为了方便用户下单,需维护用户常用地址给外部,并跟踪物流记录。
- 当前现状是用户量较大且有较快的增长,这样也导致物流订单量基数较大,促销期峰值时订单量可能存在上量的风险。
4.2.需求
4.2.1.业务需求
- 维护用户的常用地址,在下单时提供地址列表。
- 对数据存储进行分库分表,并借助消息队列和缓存抗住写和读流量。
- 物流订单和物流记录。
4.2.2.性能要求
选取行业内一线电商平台的量级作为目标进行预估:
- 用户量达两亿,平均每天增长5万个。
- 平时每天的订单量在400万个,下单时段集中在9:00~23:00,促销时日订单量在1400万个,50%下单时间段集中在19:30~20:30和22:00~23:00这两个时间段。
4.3.方案描述
方案1:最大性能方案
由于电商网站刚刚上线,还无法确定数据量级,参考业界电商巨头的数据量级设计最大性能方案。
4.3.1.概述
本方案可以应对行业内电商巨头的各种促销所带来的服务请求峰值。
4.3.2.详细说明
需求1:用户常用地址
- 提供RESTful服务来增加用户的常用地址。
- 提供RESTfult服务来获取用户的常用地址列表。
(具体框图、流程图、中间件架构、逻辑架构等详细说明略)
性能评估
容量和性能评估前我们有必要了解一下性能评估的一些标准。
性能评估标准
通用标准:
容量:按照峰值的5倍进行冗余计算。
用户常用地址容量:按照30年计算。
物流订单容量:由于时效性较强,按照3年计算。
第三方物流查询接口吞吐量:5000/s。
MySQL标准:
单端口读:1000/s。
单端口写:700/s。
单表容量:5000万条。
Redis标准:
单端口读:40000/s。
单端口写:40000/s。
单端口内存容量:32GB。
Kafka标准
单机读:30000/s
单机写:5000/s。
应用服务器请求量峰值:5000/s。
数据库资源评估
(1)读操作吞吐量评估
假设用户每次下单时都要拉去一次地址列表,按照促销单日订单量1400万计算,且50%下单集中在2小时计算。
QPS ≈ (1400万 * 0.5)/ (2 * 60 * 60) = 1000/s
按照5倍峰值计算,读操作吞吐量峰值在 1000/s * 5 = 5000/s,而MySQL标准单端口读为1000/s,因此需要5端口数据库服务读。
(2)写操作吞吐量评估
假设新增的用户都会增加一条常用地址,且在下单时,20%的用户会新增一条常用地址,假设用户增加常见操作主要集中在高峰期2小时,那么
TPS ≈ (5万 + 1400万 * 0.2) / (2 * 60 * 60) = 400/s
按照5倍峰值评估,写操作吞吐量峰值为 400/s * 5 = 2000/s,而MySQL标准单端口写为700/s,因此需要3端口数据库服务写。
通过以上读写吞吐量、如果读写混合部署,我们总共需要8个端口,即8主8备。考虑到读写分离,我们可以改成4主8从是合适的。
(3)数据容量评估
假设平均每个用户有5个常用地址,当前2亿用户,每天增加5万用户,那么30年后数据容量将达到:
2亿 + 5万 * 365 * 30 * 5 = 35 亿
按照5倍容量评估,那么总共会产生 175亿冗余容量。由于单表容量是5000万,那么总共需要350张表即可容纳。
为了和2的指数倍对齐,选择512张表。考虑到将来端口扩展不用拆分数据库,设计成:
4端口 * 4表 * 32库 = 512
数据库设计结果:4端口 * 4表 * 32库,4主8从。
缓存资源评估
假设当天下单的用户均为活跃用户,活跃用户地址缓存时间48小时(即假定下单用户48小时内还会再次购买,如果再次购买则缓存续期),且每天下单用户都为不同用户,每个用户平均有5个常用地址,每个地址大小为1KB,那么需要的缓存大小为:
- 1400万 * 5 * 1KB = 70GB
按照5倍冗余评估,则需要350GB。
假设单台Redis有32GB内存,则需要11台机器。按照单台40000/s的吞吐量,11台机器每秒可接受440000次(44万次)请求,完全可以胜任5000次每秒的请求,所以读写吞吐不是问题。
设计结果:11台,主从架构。
应用服务器资源评估
应用服务器服务能力很大程度受限于数据库的服务能力,从以上分析可知数据库读吞吐量峰值在5000/s,写吞吐量峰值在2000/s,选择单台应用服务器即可,选择两台可避免单点。
设计结果:2台。
需求2:物流订单和物流记录
整体流程
- 订单提交后,通过消息队列产生物流订单,物流订单消息稍后传入物流系统,物流系统消费物流订单消息然后入库。
- 后台任务轮询未完成的物流订单,查询三方物流接口状态,填写物流记录信息。
- 提供RESTful服务获取物流订单信息。
- 提供RESTful服务获取物流记录信息。
如果按照每天1400万单量,订单平均3天到货,三方接口提供5000/s的吞吐量,那么单个物流订单查询的频率在:
1400万 * 3 天 / 5000 = 2小时
即单个物流查询频率是2小时。
数据库资源评估
读操作吞吐量
假设3天内50%用户每天查询一次物流订单和一次物流记录,计算如下:
(1400万 * 3 * 0.5)/ (24 * 60 * 60) = 250/s
按5倍容量评估需要:2500/s,因此需要3端口数据库服务读。
其他指标计算方案参考需求1。
4.3.4.方案优缺点
以上是按照互联网头部公司的峰值计算出来的资源数,若公司服务器资源有限,这样评估资源比较稳妥但其实资源使用并不高,公司从节约成本角度考虑希望系统做成弹性可伸缩,注重资源使用率指标,平时按照最小资源运行,大促期间通过增加机器横向扩展,这样方案是最完美的。
4.4.方案对比
方案1能够充分应对未来的业务发展,但存在资源使用率不高的问题。方案2最小资源方案节约公司成本,但如果系统不够弹性,未来无法应对业务发展,系统也存在宕机风险。弹性是希望应用可以做到无状态,同时DBA可以很方便的通过拆分库到不同的端口来进行数据库横向扩展。
5.系统层性能参考指标
5.1.不同操作的性能指标
为了更直观的感受各类指标,我们先对比一下不同操作的参考指标
寄存器和内存指标
- 寄存器、L2、L3、内存、分支错误预测、互斥量加锁和解锁等耗时为纳秒级别。
- 内存随机读取可达30万次/s,顺序读取可达500万次/s。
- 内存每秒可以读取GB级别的数据。
- 读取内存中1MB的数据为250us,为亚毫秒级。
磁盘IO指标
- 普通的SATA机械硬盘IOPS能达到120次/s。
- 普通的SATA机械硬盘顺序读取数据可达100MB/s。
- 普通的SATA机械硬盘随机读取数据可达2MB/s。
- 普通的SATA机械硬盘旋转半圈需要3ms。
- 普通的SATA机械硬盘寻道时间需要3ms。
- 普通的SATA机械硬盘读取一次数据的真正耗时2ms。
- SSD IOPS能达到百万级别。
- 高端存储设备每秒可达GB级别的数据读取,相当于普通内存的读取速度。
- 固态硬盘访问延迟0.1~0.2ms,为亚毫秒级,和内存速度差不多。
网络IO指标
- 常见的千兆网卡的传输速率为1000Mbit/s,即128MB/s。
- 千兆网卡读取1MB数据为10ms。
数据库指标
- 读取数据库中的一条记录在ms级别,短则几毫秒,多则几百毫秒,大于500ms一般认为超时。
- MySQL在4核、256GB的配置中性价比较高。
IDC指标
- 同一机房网络来回0.5ms。
- 异地机房来回30~100ms。
- 同一机房的RPC服务调用为几个ms,有的为几十ms或者几百ms,一般设置500ms以上为超时。
网站指标
- 网站加载为秒级别。
- UV:每日一共有多少用户来访。
- 独立IP访问:每日有多少独立IP访问。
- PV:每日单独用户在所有页面访问量
据悉某社交媒体平台每秒的写入量上万,每秒的请求量上百万,每天登录的用户上亿,每天产生的数据量上千亿。
5.2.组合计算
- 普通的SATA机械硬盘一次随机读取的时间是
T = 3ms(寻道时间) + 3ms(旋转时间) + 2ms(数据读取延迟) = 8ms
- 普通的SATA机械硬盘每秒随机读取:
1000ms / 8ms = 125次 IOPS
- IOPS代表磁盘每秒的随机寻址次数,随机读取速率取决于数据的存放方式,假设数据按照块存储,块代销4KB,每次读取10块,那么随机读取速率为:
10 * 4KB * 125次 = 5MB/s
- 若1s可以进行30万次内存随机访问,那么一次读取内存的时间为
1000ms / 30万次/s = 3ns
总结
本文较全面的分析了服务化系统进行容量评估需要考虑的常见指标,数据指标数据主要需要考虑峰值的读写吞吐(QPS\TPS)以及响应时间要求(TP99\TP999),在进行资源评估时需要结合现有服务指标数据,对标业界标准标杆(或按照需求性能需求)结合场景进行评估。结合物流场景实践资源评估的方法论,文中最后对常见操作的性能指标给出了参考标准,这样有助于读者结合监控指标判断服务性能。
以上。