>本章内容摘自《高性能MySQL第三版》第二章节,并不是完全摘抄,按照本人的一些理解进行了删改,如有不理解地方,请阅读原文。
### 第1章 为什么需要基准测试
测量系统在给定的工作负载下会发生什么。
观察系统在不同压力下的行为,评估系统容量。
观察系统如何处理不同数据。
验证基于系统的一些假设,确认这些假设是否会符合实际情况。
重现系统中的某些异常行为,以解决这些异常。
测试系统当前的运行情况。如果不清楚当前系统的性能,就无法确认某些优化的效果如何。
模拟比当前系统更高的负载,以找出系统对着压力增加而可能遇到的扩展性瓶颈。
规划未来的业务增长。评估在项目未来的负载下,需要什么样的硬件,需要多大容量的网络,帮助降低系统升级和重大变更的风险。
测试应用适应可变环境的能力。可以发现系统在随机的并发峰值下的性能表现,或者不同配置的服务器之间的性能表现。也可以测量系统对不同数据分布的处理能力。
测试不同硬件、软件、操作系统配置。比如RAID 还是和RAID10更合适当前系统?从本地磁盘存储升级到SAN存储,对于随机写性能有什么帮助?Linux 2.4系列内核回避2.6系列的可扩展性更好么?升级软件版本能改善性能么?
证明新采购的设备是否配置正确。发现服务器硬件的错误配置。
### 第2章 测试何种指标
#### 2.1 基准测试的策略
基准测试有两种主要的策略:一是针对整个系统的整体测试,另外是单独测试。这两种策略被称为集成式(full-stack)和单组件试(single-component)基准测试。
- 针对整个系统做集成式测试,原因主要有以下几点:
- 测试整个应用系统,包括Web服务器、应用代码、网络和数据库是非常有用的,因为用户关注的并不仅仅是某个应用本身的性能,而是应用整体的性能。
- 数据库并非总是应用的瓶颈,通过整体测试可以揭示这一点。
- 只有对应用做整体测试,才能发现各个部分之间的缓存带来的影响。
- 整体应用的集成式测试更能揭示应用的真实表现,而单独组件的测试很难做到这一点
有时候不需要了解整个系统的情况,而只需要关注单独应用的性能,至少项目初期可以这样做。
#### 2.2 测试何种指标
开始基准测试甚至是设计基准测试之前,需要先明确测试的目标。测试决定选择什么样的测试工具和技术,以获取精确而有意义的测试结果。可以将测试目标细化为一些列问题,比如“增加缓存是否能够带来性能提升?”
有时候需要用不同的方法测试不同的指标,比如针对延迟(latency)和吞吐量(throughput)就需要采用不同的测试方法
##### 吞吐量
吞吐量指的是单位时间爱你内的事务处理数量。主要针对在线事务的吞吐量,非常适合多用户的交互式应用。常用测试单位是每秒事务数(TPS)和每分钟事务数(TPM)
##### 响应时间或延迟
这个指标用于测试任务所需的整体时间。根据具体应用,测试渐渐单位可能是微秒、毫秒、秒或分钟。根据不同的时间单位,可以计算出平均响应时间、最小响应时间、最大响应时间和所占百分比。最大响应时间通常意义不大,因为测试时间越长,最大响应时间可能越大。而其结果不可重复,每次测量可能得到不同的最大响应时间。因此,通常可以使用百分比响应时间(percentile response time)来代替最大响应时间。例如,如果95%的响应时间都是5毫秒,则表示人物的95%的时间都可以在5毫秒内完成。
使用图标有助于理解测试结果。
##### 并发性
并发性是一个非常重要又经常被被误解和误用的指标。例如,它经常被表示成多少用户在同一时间浏览一个Web站点,经常使用的指标是有多少个回话。然而,HTTP协议是无状态的,大多数用户只是简单的读取浏览器上显示的信息,这并不等同于Web服务器的并发性。而且,Web服务器的并发性也不等同于数据库的并发性,而仅仅只表示回话存储机制可以处理多少数据的能力。Web服务器的并发性更准确的度量指标,应该任意时间有多少同时发生的并发请求。
在应用的不同缓解,都可以测量响应的并发性。Web服务器的高并发,一般会导致数据库的高并发,但服务器采用的语言和工具集对此都会有影响。注意不要将创建数据库链接和并发性搞混淆。
一个设计良好的应用,可以同时打开成百上千个数据库链接,但可能只有少数连接在执行。所以说,一个Web站点”同时有50000个用户“访问,却可能只有10~15个并发请求道数据库。
换句话说,并发性基准测试关注的是正在工作中的并发操作,或者是同时工作中的线程数或者连接数。当并发性增加时,需要测试吞吐量是否下降,响应时间是否边长,如果是这样,应用可能就无法处理峰值夜里。
并发性的测试完全不同于响应时间和吞吐量。它不想一个结果,而更像是设置基准测试的一种属性。并发测试通常不是为了测试应用能达到的并发度,而是为了测试应用在不同并发下的性能。
##### 可扩展性
在系统的业务压力可能发生变化的情况下,测试可扩展性就非常重要了。简单的说,可扩展性指的是,给系统增加一倍的工作,在理想情况下,能够获得两倍的结果(即吞吐量增加一倍)。或者说,给系统增加一倍的资源(比如两倍的CPU),就可以获得两倍的吞吐量。当然,同时吸能(响应时间)也必须在可以介绍的范围内。大多数系统无法做到如此理想的线性扩展。随着压力的变化,吞吐量和性能都可能越来越差。
可扩展性指标对于容量规划非常有用,它可以提供其他基准测试无法系统的信息。比如系统是基于单个用户的响应时间测试(这是一个很糟糕的测试策略)设计的,虽然测试的结果很好,但并发度增加时,系统的性能有可能变得非常糟糕。而一个不断增加爱用户连接的情况下的响应时间测试则可以发现这些问题。
归根结底,应该测试那些对用户来说最重要的指标。因此应该尽可能的收集一些需求,比如,什么样的响应时间是可以介绍的,期待多少并发性,等等。然后基于这些需求来设计基准测试,避免目光短浅的只关注部分指标,忽略其他指标。
### 第3章 基准测试方法
#### 3.1 如何避免一些常见错误
- 使用真实数据的自己而不是全集。例如应用需要处理几百GB的数据,但测试只使用1GB数据;或者只使用当前数据进行测试,却希望模拟未来业务大幅增长后的情况。
- 使用错误的数据分布。例如使用均匀分布的数据测试,而系统的真实数据有很多热点区域(随机生成的测试数据通常无法模拟真实的数据分布)。
- 使用不真实的分布参数,假定所有用户的个人信息都会平均的读取。
- 在多用户的场景中,只做单用户的测试。
- 在单服务器上测试分布式应用。
- 与真实用户行为不匹配。例如Web页面中的”思考时间“。真实用户在请求道一个页面后,会阅读一段时间,而不是不停顿的一个接一个点击相关链接。
- 反复执行同一个查询。真实的查询时不尽相同的,这可能导致缓存命中率降低。而繁芜执行同一个查询,在某种程度上,会全部或者部分缓存结果。
- 没有检查错误。如果测试的结果无法得到合理的解释,比如一个本应该是很慢的查询突然变快了,就应该检查是否是有错误产生。基准测试后,一定要检查一下错误日志,这是基本要求。
- 忽略了系统预热(warm up)的过程。例如系统重启后马上进行测试。有时候需要了解系统重启后需要多长时间才能达到正常的系统容量,需要特别留意预热的时间。反过来说,如果想分析正常的性能,需要注意,基准测试在重启后马上启动,则缓存是冷的,没有数据,这时候即使测试的压力相同,得到的结果和缓存已经装满数据时是不同的。
- 使用默认的服务器配置。
- 测试时间太短。基准测试需要持续一定时间
只有避免了上述错误,才能走上改进测试质量的漫漫长路。
如果其他条件相同,就应该努力使测试尽可能的真实应用的情况。当然,有时候和实际情况晒为有些出入问题也不打。例如,实际应用服务器和数据库服务器分别部署在不同的机器。如果采用和实际部署完全相同的配置当然更真实,但也会引入更多变化,比如网路负载和速度。在单一节点上运行测试相对容易,在某些情况下结果也可以介绍,那么就在单一节点上进行测试。当然,这样的选择需要根据实际情况来分析是否合适。
#### 3.2 设计和规划基准测试
规划基准测试的第一步是提出问题并明确目标。然后决定是采用标准的基准测试,还是设计专用的测试。
建立测试和结果文档化的规范,每轮测试都必须进行详细记录。文档规范可以很简单,可以采用电子表格或记事本,也可以是复杂的自定义数据库。需要记住的是,经常需要写一些脚本来分析结果,因此如果能够不用打开电子表格或者文本等额外操作是最好的。
#### 3.3 获取系统性能和状态
执行基准测试时,需要尽可能的多手机测试系统的信息。最好为基准测试建立一个目录,并且没执行议论测试,都创建单独的子目录,将测试结、配置文件、测量指标、脚本和其他相关说明保存在其中。及时有些结果目前不需要,也应该保存下来。多余一些数据总比缺乏重要的数据摇号,二多余的数据以后或许用得着。需要记录数据包括系统状态和性能指标,诸如CPU使用率、磁盘I/O、网络流量、应用状态。
#### 3.4 获得准确的测试结果
获得准确测试结果的最好办法,是回答一些基准测试的基本问题
- 是否选择了正确的基准测试?
- 是否为问题收集了相关主句?
- 是否采用了错误的测试标准(比如是否对一个I/O密集型应用,采用了CPU密集型测试标准)
接着,确认测试结果是否可重复性。每次重新测试前,确保系统状态是一致的。如果是非常重要的测试,需要每次测试都重启系统。如果测试过程修改数据或者schema,那么每次测试前,需要利用快照还原数据。在表中插入1000条和插入100万条记录,测试结果肯定不同。数据碎片度和磁盘上的分布,都可能导致测试时不可重复的。
要注意的因素很多,包括外部的压力、性能分析和监控系统、详细的日志记录、周期性作业。例如,测试过程中突然有cron定时作业启动,或者RAID卡启动了定时的一致性检查。需要确保基准测试过程中所需要的资源是专用于测试的。如果有其他额外的操作,会消耗网络带宽,或者测试基于的是其他服务器共享的SAN存储,那么得到的结果可能是不准确的。
每次测试中,修改的参数应该尽量少。如果必须要一次修改多个参数,那么可能会丢失一些信息。有些参数依赖其他参数,这些参数无法单独修改。有时候甚至没有意识到这些依赖,这给测试带来了复杂性。
#### 3.5 运行基准测试并分析结果
基准测试通常需要运行多次。具体需要运行多少次看对结果的计分方式,以及测试的重要程序。一般取最好值或平均值,亦或5次测试中最好的三个值的平均值。
获得测试结果后,需要对结果进行分析,也就是把数字变成知识。最终的目的是回答在设计测试是的问题。理想情况下,莪可以一获得诸如”升级4核CPU可以在保持响应时间不变的情况下,获得超过50%的吞吐量增加“或者”增加索引可以使查询更滑“的结论。
#### 3.6 绘图的重要性
简单有效的图形,就是将性能指标按照时间顺序绘制。通过图形可以理解发现一些问题,而这些问题再原始数据中却很难被注意到。或许你会坚持看测试工具打印出来的平均值或其他汇总过的信息,但平均值有时候是没有用的,他会掩盖掉一些实际情况。
### 第4章 基准测试工具
#### 4.1 集成测试工具
- ab
只能测试单一域名
- http_load
可以测试多个域名,并随机选择进行测试
- JMeter
更复杂,可以设置参数众多,能够更加灵活的monitor真实用户访问,并有绘图接口、还可以对测试进行记录,离线重演测试结果。支持压测多种不同应用。
- siege
能够模拟比http_load更大的负载,并支持延迟、随机等特性,可以更好的模拟真实用户请求,仅用于Web服务测试。
#### 4.2 单组件式测试工具
- TPCC-MySQL
Percona出品,主流MySQL压测
- sysbench
主流MySQL压测,支持Lua脚本,同时还支持操作系统和硬件的硬件测试。
### 第5章 总结
基准测试并不是仅仅用来解决业务问题的一种时间,也是一种很好的学习方法。学习如何将问题分解成可以通过基准测试来获得答案的方法,就和数学课上从文字题目中推到出方程式一样。首先正确的描述问题,然后选择合适的基准测试来回答问题。设置基准测试的持续时间和参数,运行测试,收集数据,分析结果数据。
如果经常执行基准测试,那么指定一个原则很有必要。选择合适的测试工具深入的学习。可以建立一个脚本库,用于配置基准测试,收集输出结果、系统性能和状态,以及分析结果。使用一种熟悉的绘图工具gnuplot或者R,不用浪费时间使用电子表格,他们即笨重,速度又慢。尽量早和多的使用绘图的方式,来发现基准测试和系统中的问题和错误,你的眼睛是比任何脚本和自动化工具都更有效的发现问题的工具。
- 献给乐于奉献的你
- 一、工作感悟
- 1.1 工作感悟
- 1.2 数据库工作总结
- 二、运维专题(非技术)
- 2.1 公有云运维
- 2.1.1 阿里云采坑记.md
- 三、运维专题(技术类)
- 3.1 Linux(操作系统)
- 3.1.1 常见工作总结
- 3.1.2 常见服务使用和部署
- 3.1.3 操作系统优化
- 3.1.4 常用命令(Centos8)
- 3.2 Docker & K8s(容器技术)
- 3.2.1 Docker
- 1. Docker
- 1-1 容器基础
- 1-2 部署和加速
- 1-3 常用命令
- 1-4 Dockerfile编写
- 1-5 容器网络
- 1-6 数据持久化
- 2. docker-compose
- 2-1 基础
- 3.2.2 kubernetes
- 1. 导读-请先看我
- 2. kubeadm部署集群
- 1-1 k8s-1.14-基于calico
- 1-2 k8s-1.17-基于flanne
- 3. 二进制部署集群
- 4. 日常工作及故障处理
- 4-1 常用命令
- 4-2 故障处理
- 3.2.3 依赖服务部署
- 1. Harbor(镜像仓库)
- 1-1 harbor-2.1.0(单节点)
- 3.3 CICD(持续集成/部署)
- 3.3.1 GitLab
- 1. 服务部署
- 1-1 Gitlab-CE-13.3.4(单节点)
- 2. Git基础
- 3.3.2 Ansible
- 1. 服务部署
- 1-2 ansible-2.5(pip部署)
- 3. ansible-playbook
- 3-1 基于Roles的Playbook
- 3-3 循环语法
- 3.3.3 Jnekins
- 1. Jenkins部署
- 1-1 Jenkins-2.65部署
- 1-2 Jenkins-2.249部署
- 2. Jenkins项目初始化
- 3. Jenkins集成
- 3-1 Jenkins-2.65集成Sonar
- 3.4 LB/HA(负载均衡,反向代理)
- 3.4.1 LVS+Keepalive
- 1. LVS为MySQL读提供负载均衡
- 3.4.2 Pacemaker(HA)
- 1. 常用命令(转)
- 3.5 Runtime(代码运行环境)
- 3.5.1 Tomcat(Web中间件)
- 1. Tomcat部署手册
- 1-1 Tomcat-7.0.76部署
- 2. Tomcat常用脚本
- 3.6 NoSQL(非关系型数据库)
- 3.6.1 redis(非关系数据库)
- 1. Redis 基础
- 2. Redis 4.0变化
- 3. Codis实现Redis的集群
- 4. Redis故障处理
- 5. redis安全第一步
- 6. Redis集群搭建
- 7. CacheCloud部署
- 3.6.1 Redis挑战
- 3.6.2 MongoDB(文档数据库)
- 1. Mongodb基础
- 1-1 Mongodb4.0新特性
- 1-2 支持多大数据量
- 2. Mongodb安装
- 2-1 Mac OS安装Mongodb
- 2-2 Yum安装Mongodb
- 2-3 二进制安装Mongodb
- 2-4 docker容器安装Mongodb
- 2-5 Mongodb 配置文件详解
- 2-6 Mongodb 生产安全清单
- 2-7 用户身份认证和授权
- 3. Mongodb副本集
- 3-1 副本集搭建
- 3-2 用户身份认证与授权
- 4. 日常维护工作
- 4-1 Mongodb磁盘回收
- 4-2 Mongodb备份恢复到任意时间点
- 4-3 Mongodb慢查询分析
- 4-4 Mongodb版本升级
- 4-5 Mongodb副本集成员状态
- 4-6 Mongodb备份恢复工具使用
- 4-7 Mongodb服务启动和停止
- 4-8 修改副本集成员oplog大小
- 4-9 Mongodb 副本集Oplog
- 3.7 MQ(消息队列)
- 3.7.1 Zookeeper(分布式协调系统)
- 1. ZooKeeper基础
- 2. ZooKeeper集群搭建
- 2-1 ZK-3.4.10部署
- 3.2 RabbitMQ(消息队列)
- 1. 服务部署
- 1-1 RabbitMQ-3.8部署
- 2. 常用命令
- 3.8 Monitor(数据收集,监控)
- 3.8.1 Zabbix(运维监控)
- 1. 服务部署
- 1-1 服务端部署
- 1-2 客户端部署
- 2. 监控服务
- 2-1 监控Apache
- 2-2 监控IIS
- 2-3 监控Ningx
- 2-4 监控Tomcat(6/7/8)
- 2-5 监控WebSphere 7
- 2-6 监控MySQL
- 2-7 监控Oracle
- 2-8 监控SQL Servre
- 2-9 监控Weblogic
- 2-10 监控Windows
- 2-11 自定义监控项
- 3. 告警推送
- 3-1 邮件告警
- 3-2 短信告警
- 3-3 告警推到Syslog
- 4. 日常工作
- 4-1 数据库优化(TokuDB)
- 4-2 数据库优化(分区表)
- 4-3 前端定制(Grafana)
- 5. 与Grafana结合
- 3.8.2 ELKBstack(日志收集展示)
- 1. 服务部署
- 1-1 ELK 5.5部署及配置
- 1-1-1 ELKBstack介绍
- 1-1-2 Elasticsearch部署
- 1-1-3 Logstash部署
- 1-1-4 Kibana部署
- 1-1-5 X-pack部署
- 1-1-6 Filebeat部署
- 2. ELK高级配置
- 1. Elasticsearch实战
- 2. Logstash实战
- 3. Filebeat实战
- 5. 引入队列
- 3.9 Virtualization(虚拟化)
- 3.10 Basic(基础服务)
- 3.10.1 Piwik-Matomo(用户行为分析)
- 1. Piwik前期分析
- 2. Piwik介绍和部署
- 2-1 Piwik-3.x版本(早期)
- 3. Piwik 功能配置
- 4. Piwik 模拟数据和压测
- 5. Piwik运转原理
- 6. Piwik数据库模式(一)
- 6-1 第一部分
- 6-2 第二部分
- 3.10.2 Cobbler(系统自动部署)
- 1. Cobbler 可以干什么?
- 2. Cobbler 基础原理
- 3. Cobbler 安装
- 3-1 Cobbler-2.8部署
- 4. Cobbler 基础配置
- 5. Cobbler 配置文件
- 6. 一键优化脚本
- 3.10.3 Rsync(数据同步服务)
- 1. Rsync基础
- 2. 案例:页面部署(服务端拉取)
- 3.10.4 NFS(共享存储)
- 1. NFS部署手册
- 2. 客户端NFS备份脚本
- 3.10.5 Grafana(可视化)
- 1. 安装(8.2.x)
- 3.11 Tools(软件工具)
- 3.11.1 基准测试
- 1. 基准测试方法论
- 2. 压测工具 - Siege
- 3. 压测工具 - http_load
- 3.12 DB(关系型数据库)
- 3.12.1 MySQL(关系数据库)
- 1. MySQL部署
- 1-1 MySQL-5.7部署
- 1-2 Percona-5.7 + TokuDB 部署
- 2. MySQL复制
- 2-1 MySQL异步复制
- 3. MySQL备份恢复
- 3-1 xtrabackup 备份恢复
- 4. MySQL 高可用
- 4-1 MHA(HA)
- 4-1-1 MHA 架构介绍和原理
- 4-1-2 MHA日常管理
- 4-1-3 MHA 自动Failover
- 4-1-4 MHA常用参数
- 4-1-5 MHA 报错
- 4-1-6 MHA相关配置文件和脚本
- 4-2 MyCAT
- 4-2-1 MyCAT 介绍和部署
- 4-1-3 MyCAT读写分离案例解析
- 5. MySQL 常用脚本
- 5-1 MySQL常用统计语句
- 5-2 MySQL性能分析脚本
- 6. MySQL 日常及故障处理
- 6-1 MySQL死锁排查
- 6-2 复制故障
- 6-3 MySQL 升级注意事项
- 6-3 MySQL授权
- 3.12.2 Oracle(关系数据库)
- 1. Oracle部署
- 1-1 Oracle11g单实例部署
- 1-2 Oracle12c单实例部署
- 2. Oracle常用脚本
- 3. Oracle 知识点
- 六、Ansible开源项目
- 6.1 项目初始化手册
- 6.1.1 Ansible错误处理
- 6.1.2 一种预先判断是否操作的方法
- 6.2 System初始化
- 6.3 Nginx/Tnginx部署
- 6.4 Python部署
- 6.5 PHP部署
- 6.6 MySQL部署
- 6.7 Docker部署
- 6.8 Haproxy部署
- 6.9 Redis部署
- 1. 变量和tags信息
- 3. Redis主从部署
- 4. Redis集群部署
- 5. 清理数据
- 6.10 Software软件部署
- 6.11 Zabbix部署
- 6.12 Elastic部署
- 6.13 Tomcat
- 6.14 Kafka部署
- 6.15 Zookeeper部署
- 6.16 Etcd集群部署
- 6.17 M3DB部署
- 6.18 Pormetheus部署
- 七、学习资源推荐
- 八、从瞎搞到放弃
- 8.1 CodeQL(语义代码分析引擎)
- 8.1.1 背景及计划
- 8.1.2 CodeQL概述
- 8.1.3 简单部署和使用
- 8.1.4 后续
- 8.2 dbdeployer(轻松部署MySQL)
- 归档笔记
- 三、常用服务部署(迁移中)
- 3.4 Nginx & PHP(Web服务)
- 3.4.1 Nginx(Web)
- 1. Nginx基础和部署
- 2. Nginx 我的一些思考
- 3. Nginx(Web)配置
- 4. Nginx(Proxy)配置
- 5. Nginx日常管理
- 3.4.3 PHP
- 1. PHP 7.1 部署
- 2. PHP5.6 部署
- 4. PHP原理
- 5. PHP 常用模块
- 二、运维项目实战(迁移中)
- 2.1 标准化 & 工具化项目
- 2.1.1 系统部署和优化
- 2.1.5 全网日志收集展示平台项目
- 1. 项目需求
- 2. 整体方案规划
- 3. 日志收集配置
- 4. 消息缓冲队列
- 5. 日志处理转发
- 6. 日志数据展示(待补充)
- 7. ELK安全配置(上)
- 8. ELK安全配置(下)
- 9. 项目总结
- 2.2 高性能Web项目
- 2.2.1 网站需求(完善中)