RDS MySQL高并发访问下的系统稳定性
1. 安装压测工具,准备模拟数据
您需要在ECS上安装压测工具,并准备模拟数据。本案例以8 vCPU 16 GiB规格的ECS实例为例。
登录ECS。
1)登录ECS控制台,左侧菜单选择实例,点击开通的实例ID名称。
2)单击远程连接。
3)可选择Workbench远程连接方式,单击立即登录。
在ECS上依次执行如下命令,完成压测工具SysBench的安装。
1)安装所需依赖。
yum install gcc gcc-c++ autoconf automake make libtool bzr mysql-devel git mysql
2)下载SysBench。
git clone https://github.com/akopytov/sysbench.git 或者 git clone git://github.com/akopytov/sysbench.git
3)进入SysBench目录。
cd sysbench
4)运行autogen.sh。
./autogen.sh
5)编译。
./configure make -j make install
6)执行如下命令配置SysBench Client,使内核可以使用所有的CPU处理数据包(默认设置为使用2个CPU),同时减少CPU之间的上下文切换。
sudo sh -c 'for x in /sys/class/net/eth0/queues/rx-*; do echo ff>$x/rps_cpus; done' sudo sh -c 'echo 32768 > /proc/sys/net/core/rps_sock_flow_entries' sudo sh -c 'echo 4096 > /sys/class/net/eth0/queues/rx-0/rps_flow_cnt'
说明:ff表示使用8个CPU(1个f表示4个CPU)。请根据实际配置修改,例如本案例中ECS为8核CPU,因此输入ff。
登录RDS 控制台,在RDS MySQL中创建一个名为dbfortest的空数据库。
在ECS中,执行如下命令,准备压测数据。
sysbench --threads=512 --table-size=10000 --tables=250 --events=0 --time=90 --mysql-db=xxx --mysql-user=xxx --mysql-password=xxx --mysql-host=xxx --mysql-port=xxx oltp_read_write prepare
涉及到的参数说明如下:
参数 |
说明 |
threads |
测试线程数,可设置为8、16、32、64、128、256、512等。 |
table_size |
要准备的表的大小。 为达到测试效果,建议按照示例代码中的10000进行设置。 |
tables |
要准备的表的数量。 为达到测试效果,建议按照示例代码中的250进行设置。 |
events |
测试请求数量。建议设置为0。 |
time |
测试时间。 为达到测试效果,建议按照示例代码中的90进行设置。 |
mysql-db |
压测数据要注入的数据库名称。 本示例中即为RDS MySQL中预先创建的dbfortest数据库。 |
mysql-user |
RDS MySQL实例账号。 |
mysql-password |
RDS MySQL实例账号对应的密码。 |
mysql-host |
RDS MySQL实例连接地址。 可进入实例的数据库连接页面获取。 |
mysql-port |
RDS MySQL实例连接端口。 可进入实例的数据库连接页面获取。 |
例如:
sysbench --threads=512 --table-size=10000 --tables=250 --events=0 --time=90 --mysql-db=dbfortest --mysql-user=accountfortest --mysql-password=***** --mysql-host=rm-*********.mysql.rds.aliyuncs.com --mysql-port=3306 oltp_read_write prepare
该命令会自动在RDS MySQL预先创建的dbfortest数据库中创建N个名为sbtest1、sbtest2……sbtestN的表(N为tables参数指定的表数量),其表结构如下,供您了解:
CREATE TABLE `sbtestN` ( `id` int(11) NOT NULL AUTO_INCREMENT, `k` int(11) NOT NULL DEFAULT '0', `c` char(120) NOT NULL DEFAULT '', `pad` char(60) NOT NULL DEFAULT '', PRIMARY KEY (`id`), KEY `k_100` (`k`) ) ENGINE=InnoDB AUTO_INCREMENT=25001 DEFAULT CHARSET=utf8
2. 开启RDS MySQL线程池
模拟数据准备完后,我们先开启RDS MySQL线程池,然后模拟压测,观察开启线程池后的性能变化。
前往RDS 控制台,进入实例详情页。
左侧导航栏进入参数设置页面。
Ctrl+F找到如下参数,并配置对应的值。
参数名 |
说明 |
参数值 |
loose_thread_pool_enabled |
开启或关闭实例的线程池功能。 |
ON(默认值) |
loose_thread_pool_size |
线程池中线程分组的数量。线程池中的线程被平均分到多个组中进行管理。 |
4(默认值) |
loose_thread_pool_oversubscribe |
每个线程分组中允许的活跃线程(正在执行SQL语句的线程)的数量。 |
32(默认值) |
说明:loose_thread_pool_size和loose_thread_pool_oversubscribe建议保持默认值,随意改动易造成性能衰减。
设置完成后,点击提交参数。
3. 模拟压测并监测性能
开启RDS MySQL实例的线程池后,可通过本步骤,运行压测程序,向准备好的表中注入数据,模拟RDS MySQL流量。压测过程中,您可观察实例的性能监控视图,观察TPS(平均每秒事务数)/QPS(平均每秒SQL语句执行次数)随着连接数增大的变化。
说明:本步骤提供了在ECS中通过命令行的方式执行压测的方法。
在ECS中,执行如下命令,运行压测程序(32个并行线程)。
sysbench --threads=32 --db-driver=mysql --mysql-host=XXX --mysql-port=XXX --mysql-user=XXX --mysql-password=XXX --mysql-db=xxx --table_size=10000 --tables=250 --events=0 --time=90 --percentile=95 --report-interval=1 --db-ps-mode=disable oltp_read_write run
可以看到程序已经开始运行:
进入RDS实例的自治服务 > 一键诊断 > 实时性能页面,观察QPS | TPS图。
可以看到,在32个并行线程的情况下,QPS差不多稳定在64000左右,TPS稳定在12700左右。
再次进行压测,此时将并行线程(--threads)提升至64。
sysbench --threads=64 --db-driver=mysql --mysql-host=XXX --mysql-port=XXX --mysql-user=XXX --mysql-password=XXX --mysql-db=xxx --table_size=10000 --tables=250 --events=0 --time=90 --percentile=95 --report-interval=1 --db-ps-mode=disable oltp_read_write run
观察QPS | TPS图,可以看到,在64个并行线程的情况下,QPS差不多稳定在62500左右,TPS稳定在12500左右。
重复以上步骤,在其他并行线程数的情况下压测,并观察QPS | TPS图,记录数据。
说明:TPS和QPS的值与RDS实例的规格、CPU使用率有关。如下表格中的数据由RDS MySQL 8.0高可用版,通用规格8CPU16GB,100% CPU使用率的情况下测试得出,仅供参考。
线程数 |
TPS |
QPS |
8 |
4350 |
22000 |
16 |
8300 |
41500 |
32 |
12700 |
64000 |
64 |
12500 |
62500 |
128 |
12300 |
61500 |
256 |
12200 |
60500 |
512 |
12200 |
60500 |
1024 |
12200 |
60500 |
2048 |
12200 |
60500 |
4000 |
12200 |
60500 |
整个过程中,也可以看到,连接数在不断提升的情况下,活跃连接数保持在较低水平,且较平稳。
4. 关闭线程池,再次模拟压测并监测性能
观察到开启线程池后的性能效果后,我们可以关闭线程池功能,再进行压测,对比线程池功能开启前后的性能。
将loose_thread_pool_enabled参数设置为OFF。
重复步骤③的压测步骤,观测并记录线程池关闭情况下,不同并发线程数量下稳定后的TPS和QPS的值。
说明:TPS和QPS的值与RDS实例的规格、CPU使用率有关。如下表格中的数据由RDS MySQL 8.0高可用版,通用规格8CPU16GB,100% CPU使用率的情况下测试得出,仅供参考。
同时,可以观察到,连接数在不断提升的情况下,活跃连接数保持在较高水平。
5. 结论
从两轮模拟压测的数据,我们可以看到:
TPS和QPS变化趋势
在大量并发访问的基础下,随着请求数(线程数)的增加,数据库性能会呈现先增长后衰减的趋势。开启线程池后,因为数据库资源得到了有效保障,避免了大量请求造成的资源踩踏。TPS和QPS会在微降后,进入到平稳状态,保障了突发流量下的数据库稳定运行,为实例扩容、问题定位争取了宝贵的时间。
活跃连接数变化趋势
从活跃连接数也可以看到,未开启线程池时(左),活跃连接数很高,几乎达到总连接数。开启线程池后(右),活跃连接数保持在一个较低的水位。
从这个趋势我们可以看出,线程池功能使得RDS MySQL在高并发下,只需要少量线程完成活跃会话的任务即可,避免突发流量导致的业务稳定性问题。
互联网场景下,非预期突发流量对业务系统的稳定性,特别是数据库的稳定性提出了非常高的要求。大量请求下,线程池功能可以有效防止数据库击穿,避免因为大量连接导致的资源争抢,保障数据库稳定高性能运行。
实验链接:https://developer.aliyun.com/adc/scenario/a9c7567194fe470ab870a4876ead9fec