欢迎关注公众号(通过文章导读关注:【11来了】),及时收到 AI 前沿项目工具及新技术的推送!

在我后台回复 「资料」 可领取编程高频电子书

在我后台回复「面试」可领取硬核面试笔记

部署后的压测

在选好数据库的硬件配置之后,如果在比较规范化的公司中,会交给专业的 DBA 进行 MySQL 数据库的部署,DBA 就会根据以往的经验,使用 MySQL 生产调优的参数模板去部署 MySQL

可能还会对 Linux 中的一些 OS 参数进行调整,比如最大文件句柄的参数,通过调大最大文件句柄,可以让 Linux 接收更多的 TCP 连接,因为 Linux 中一切皆文件,但实际中不仅仅只简单地调大最大文件句柄就可以了(需要多个参数配合调整)

拿到 MySQL 数据库的第一步

在 MySQL 数据库部署好之后,先不要直接进行开发,而是先通过压测软件对数据库进行压测,观察数据库的 CPU、磁盘 IO、网络 IO、内存负载情况,判断数据库每秒可以处理多少的请求

那么通过对数据库进行压测就可以清楚数据库每秒处理任务的性能,心里有个底

这样在以后压测 Java 系统时,如果每秒并发量不理想,需要进行调优,就可以判断到底是 Java 系统出现了性能瓶颈还是数据库出现了性能瓶颈

因为有可能数据库每秒可以抗下 2000 个请求,但是 Java 应用每秒只可以抗下 500 的请求,如果事先没有对数据库进行压测,那你只知道 Java 应用每秒只可以处理 500 个请求,但是并不知道具体是 Java 应用的问题,还是数据库的问题!

数据库压测工具

这里推荐一个数据库压测工具:sysbench

通过 sysbench 可以在数据库中构建大量数据进行性能压测

Linux(CentOS) 安装命令:

curl -s https://packagecloud.io/install/repositories/akopytov/sysbench/script.rpm.sh | sudo bash
sudo yum -y install sysbench
# 如果看到了版本号证明安装成功
sysbench --version

sysbench 压测数据构造

使用以下命令基于 sysbench 对数据库进行压测:

sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=test_user --mysql-password=test_user --mysql-db=test_db --tables=20 --table_size=1000000 oltp_read_write --db-ps-mode=disable prepare

参数解释:

  • db-driver:指定数据库引擎,例如 pgsql(PostgreSQL)或 mysql
  • time:测试持续时间。
  • threads:并发线程数。
  • report-interval:报告输出周期。
  • mysql-host:数据库服务器的地址。
  • mysql-port:数据库服务器的端口。
  • mysql-user:数据库用户的用户名。
  • mysql-password:数据库用户的密码。
  • --mysql-db= test_db --tables=20 --table-size=1000000:这一行命令的意思是在 test_db 数据库里,构建 20 张测试表,每个测试表里 100 万条测试数据
  • oltp_read_write:执行 oltp 数据库的读写测试
  • --db-ps-mode=disable:禁止 ps 模式
  • prepare:表示根据上边的命令设置去构造对应的数据,也就是创建 20 张测试表,每张测试表 100 万条数据

sysbench 压测命令

在进行压测的时候,命令最后的 prepare 变为了 run,表示运行压测

  • 使用 oltp_read_write 模式测试数据库的综合读写 TPS
sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=test_user --mysql-password=test_user --mysql-db=test_db --tables=20 --table_size=1000000 oltp_read_write --db-ps-mode=disable run
  • 使用 oltp_read_only 模式测试数据库的只读性能
sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=test_user --mysql-password=test_user --mysql-db=test_db --tables=20 --table_size=1000000 oltp_read_only --db-ps-mode=disable run
  • 使用 oltp_delete 模式测试数据库的删除性能
  • 使用 oltp_update_index 模式测试数据库的更新索引字段性能
  • 使用 oltp_update_non_index 模式测试数据库的更新非索引字段性能
  • 使用 oltp_insert 模式测试数据库的插入性能
  • 使用 oltp_write_only 模式测试数据库的写入性能

通过指定不同模式来测试数据库不同操作的性能,只需要将命令中的 oltp_read_only 字段换成对应的模式即可!

  • 清除压测数据:完成压测之后,可以清除数据
sysbench --db-driver=mysql --time=300 --threads=10 --report-interval=1 --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=test_user --mysql-password=test_user --mysql-db=test_db --tables=20 --table_size=1000000 oltp_read_write --db-ps-mode=disable cleanup

sysbench 压测结果分析

sysbench 每秒会输出如下的中间结果:

# thds 4:有 4 个线程在压测
# tps: 374,每秒执行了 374 个事务
# qps:7533,每秒执行了 7533 个请求
# r/w/o 表示 qps 中读、写、其他请求的占比
# lat:表示 95% 的请求延迟都在 17.95 ms 以内
# err、reconn:每秒错误、网络重连的次数
[ 1s ] thds: 4 tps: 374.23 qps: 7533.43 (r/w/o: 5280.08/977.98/1275.36) lat (ms,95%): 17.95 err/s: 0.00 reconn/s: 0.00

最后压测完成后,会输出一个统计结果:

SQL statistics:
    queries performed:
        read: 49084 # 压测期间执行的读请求数量
        write: 9513 # 压测期间执行的写请求数量
        other: 11523 # 压测期间执行的其他请求数量
        total: 70120 # 压测期间执行的总请求数量
    transactions: 3506 (350.33 per sec.) # 执行的事务数量
    queries: 70120 (7006.63 per sec.) # 执行的请求数量
    ignored errors: 0 (0.00 per sec.)
    reconnects: 0 (0.00 per sec.)
General statistics:
    total time: 10.0062s # 10 s 的压测,执行了 3506 个事务
    total number of events: 3506
Latency (ms):
         min: 4.56 # 请求中,最小延迟 4.56
         avg: 11.41 # 平均延迟
         max: 39.24 # 最高延迟
         95th percentile: 19.65 # 95% 请求延迟都小于 19.65
         sum: 39997.58 
Threads fairness:
    events (avg/stddev): 876.5000/5.22
    execution time (avg/stddev): 9.9994/0.00

观察机器负载情况

在压测时,要观察机器的负载情况,通过不断增加压测的线程数去让数据库承载更高的 QPS,看数据库在极限情况下可以抗下多少的 QPS

接下来说一下压测中评估数据库 QPS 的标准:

比如说,在实际压测中,机器在抗下 2000 的 QPS 时,机器整个负载水平是比较高的,但是还能再增加少许请求,那么可以说这台数据库可以抗下 2000 的 QPS

但是如果机器在抗下 2000 的 QPS 时,机器的整个负载几乎都爆满了,再多一些请求打进来,就把机器给打垮了,那就不能说这台数据库可以抗下 2000 的 QPS 了

接下来说一下压测期间可以通过哪些命令来观察机器的负载情况:

  • 观察机器 CPU、内存 负载

使用 top 命令来观察 CPU 负载,使用 top 命令会输出:

load average: 0.06, 0.03, 0.05 # 指标说明
# 三个值分别为:1分钟负载、5分钟负载、15分钟负载

对于不同核的 CPU 来说,load average 的含义也不同:

单核 CPU:

1、Load < 1,系统不繁忙

2、Load = 1,已经没有资源应对更多请求(所有资源都在被使用,也没有请求在阻塞)

3、Load > 1,已经有很多请求阻塞,等待处理

双核 CPU:

1、Load < 2,系统不繁忙

2、Load = 2,已经没有资源应对更多请求(所有资源都在被使用,也没有请求在阻塞)

那么如果是 4 核 CPU,Load < 4 表示系统不繁忙

并且通过 top 命令还可以查看内存的使用率,这个比较清晰,通过 Mem 这一行的数据就可以看出来

  • 观察机器磁盘 IO 负载

1、通过 dstat -d 命令查看磁盘 IO

输出磁盘 IO 的吞吐量,每秒钟读取 以及 每秒钟写入的数据

普通的机械硬盘每秒钟可以读取上百 MB 的数据量

[root@localhost ~]# dstat -d
-dsk/total-
 read  writ
 879k   69k
   0     0 
   0     0 
   0  1557k^C

2、通过 dstat -r 命令查看系统 IO 情况

输出磁盘的 每秒随机读取次数 以及 每秒随机写入次数

磁盘的随机读写每秒在两三百次以内都是可以接受的

[root@localhost ~]# dstat -r
--io/total-
 read  writ
6.89  4.07 
   0     0 
   0     0 
   0  68.0 ^C

3、通过 dstat -n 查看网卡的流量情况

查看每秒钟网卡 接收的流量 以及 发送的流量 大小

如果机器使用千兆网卡,每秒网卡的总流量就在 100MB 左右

[root@localhost ~]# dstat -n
-net/total-
 recv  send
   0     0 
3327B  705B
1820B 1118B^C