MySQL是流行的开源关系型数据库,广泛应用于各类项目。如需优化其性能,可跟随本实验场景,通过16K原子写和参数调优提升性能。
阿里云也提供了关系型数据库RDS服务,RDS MySQL是基于阿里巴巴MySQL源码分支的在线数据库服务,已默认支持16KB原子写,可以获得更高性能,若需了解更多RDS MySQL信息,请参见16K原子写。
背景信息
MySQL参数
MySQL拥有数百个参数,这些参数覆盖了内存管理、缓存大小、连接处理、日志记录、复制配置、查询优化等方面,具体参数的数量取决于MySQL的版本和安装的存储引擎。正确配置参数可以有效提升MySQL的性能,但参数配置不正确也会影响MySQL的性能,严重情况下甚至会影响数据的准确性。
下面将从MySQL参数的角度,提供优化MySQL性能的建议,可以通过实验室提供的环境去配置这些参数,也可以自行购买实例后按照本文教程配置这些参数。
16K原子写MySQL
16K原子写的MySQL是提升数据库性能的一种方法,可以提升MySQL服务的读写性能,并降低写放大。而要实现16K原子写的特性,不仅需要数据库软件本身的支持,还需要硬件和文件系统层面的支持。
通常情况下,MySQL数据库通过MySQL DoubleWrite机制来确保数据一致性和可靠性,该机制可能导致IO负载和延迟的增加,进而降低MySQL的性能,尤其在高负载的数据库中更为明显。本实验利用ESSD云盘具备的16K原子写能力,通过关闭DoubleWrite参数来减少写入操作的次数和延迟,从而改善MySQL DoubleWrite机制带来的性能问题。需要注意的是,16K原子写能力不仅需要关闭DoubleWrite参数,还需要硬件和文件系统层面的支持,才能确保数据一致性和可靠性,并提供更高性能的MySQL数据存储和访问服务。
计费说明
在部署MySQL服务过程中,会根据使用的阿里云资源(ECS实例、ESSD云盘等)的计费方式进行计费。如果通过实验室一键部署,创建的实验任务本身不会收费。
实验室一键部署过程中使用到的阿里云资源仅支持按量付费。
部署MySQL服务
手动部署(用于生产环境)
实验室部署的一键搭建能力通常用于快速验证和测试新特性,但不适合直接应用到生产环境中。在生产环境中,建议使用手动部署方式,以确保系统的安全和稳定。
手动部署MySQL服务需先购买ECS实例和ESSD云盘,然后在ECS实例中通过命令部署MySQL服务。
操作步骤
-
创建ECS实例。示例的ECS实例情况如下:
-
实例规格ecs.c6.2xlarge。
-
以操作系统CentOS 7.9为例,其余操作系统指令需要根据实际情况调整。
-
挂载ESSD类型的数据盘,以500 GiB的ESSD PL1为例。
-
ECS实例未安装MySQL服务。
具体操作,请参见自定义购买实例。
-
-
远程连接ECS实例。
具体操作,请参见使用Workbench登录Linux实例。
-
安装MySQL。
-
执行以下命令,下载MySQL安装包,以MySQL 8.0为例。
cd /tmp/ wget http://mirrors.cloud.aliyuncs.com/mysql/MySQL-8.0/mysql-8.0.27-1.el7.x86_64.rpm-bundle.tar -
执行以下命令,解压缩安装包。
tar -xf mysql-8.0.27-1.el7.x86_64.rpm-bundle.tar -
执行以下命令,安装MySQL。
sudo yum install -y mysql-community-{server,client,common,libs,devel}-* -
执行以下命令,停止MySQL进程。
sudo systemctl stop mysqld
-
-
初始化云盘。
-
执行以下命令,获取数据盘盘符。
sudo fdisk -l如下所示,表示该数据盘未执行过初始化(没有分区),且盘符为
vdb。[ecs-user@iZxxx Z tmp]$ sudo fdisk -l Disk /dev/vda: 42.9 GB, 42949672960 bytes, 83886080 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk label type: dos Disk identifier: 0x000c2760 Device Boot Start End Blocks Id System /dev/vda1 * 2048 83886046 41941999+ 83 Linux Disk /dev/vdb: 42.9 GB, 42949672960 bytes, 83886080 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes -
执行以下命令,配置全局环境变量。
DEV_LABEL=vdb其中
vdb为数据盘盘符,请根据实际环境替换。 -
执行以下命令,设置MySQL数据保存位置。
MYSQL_HOME=/home/ecs-user/${DEV_LABEL} -
执行以下命令,防止virtio引起分块。
sudo sh -c 'echo 256 >/sys/block/vdb/queue/max_sectors_kb' -
执行以下命令,创建MySQL目录。
if [ ! -d ${MYSQL_HOME} ]; then sudo mkdir -p ${MYSQL_HOME} fi -
(条件必选)执行以下命令,卸载数据盘。
如果数据盘尚未初始化,无需执行该步骤。
sudo umount /dev/${DEV_LABEL} -
执行以下命令,格式化文件系统,启用
bigalloc选项,并设置文件系统的块大小为16 KB。echo y | sudo mkfs.ext4 -O bigalloc -C 16k /dev/${DEV_LABEL} -
执行以下命令,挂载数据盘。
sudo mount /dev/${DEV_LABEL} ${MYSQL_HOME} -
执行以下命令,创建MySQL的日志目录、数据目录等。
sudo mkdir -p ${MYSQL_HOME}/data/dbs sudo mkdir -p ${MYSQL_HOME}/data/mysql sudo mkdir -p ${MYSQL_HOME}/log/mysql sudo mkdir -p ${MYSQL_HOME}/log/redo
-
-
配置MySQL。
-
执行以下命令,创建MySQL配置文件、设置MySQL参数并关闭DoubleWrite。
sudo tee /etc/my.cnf <<EOF [mysqld] port = 3306 back_log = 3000 datadir = ${MYSQL_HOME}/data/dbs log-bin = ${MYSQL_HOME}/log/mysql/mysql-bin.log log-error = ${MYSQL_HOME}/log/mysql/master-error.log innodb_data_home_dir = ${MYSQL_HOME}/data/mysql/ innodb_log_group_home_dir = ${MYSQL_HOME}/log/redo/ innodb_doublewrite_dir = ${MYSQL_HOME}/doublewrite character_set_server = utf8 sync_binlog = 1000 innodb_doublewrite = 0 max_connections=151 max_allowed_packet=64M innodb_buffer_pool_size=128M innodb_buffer_pool_instances=1 innodb_read_io_threads=4 innodb_write_io_threads=4 innodb_buffer_pool_instances=1 innodb_flush_log_at_trx_commit=1 innodb_flush_method=O_DIRECT default_authentication_plugin = mysql_native_password EOFMySQL参数的详细说明,请参见MySQL参数。
-
执行以下命令,初始化MySQL。
sudo mysqld --defaults-file=/etc/my.cnf --initialize
-
-
启动MySQL。
-
执行以下命令,启动MySQL。
sudo mysqld --user=root --daemonize -
执行以下命令,检查MySQL是否正常启动。
ps -aux | grep mysqld如下所示,表示MySQL已正常启动。
[ecs-user@iZbp... ~]$ ps -aux | grep mysqld root 17144 0.1 4.6 1794466 365248 ? S1 14:03 0:01 mysqld --user=root --daemonize ecs-user 17223 0.0 0.8 112816 976 pts/1 S+ 14:18 0:00 grep --color=auto mysqld
-
-
(可选)配置MySQL开机自启动。
-
执行以下命令,进入到目标目录。如果不存在,则通过
mkdir新建。cd /etc/rc.d/init.d -
执行以下命令,创建自启动脚本。
sudo tee /etc/rc.d/init.d/ebs_mysql_16k_auto_start.sh <<EOF #!/bin/bash # chkconfig: 345 20 80 # description: EBS MySQL 16K Auto Start Script start() { DEV_LABEL=vdb MYSQL_HOME=/home/ecs-user/\${DEV_LABEL} echo 256 >/sys/block/vdb/queue/max_sectors_kb umount /dev/\${DEV_LABEL} mount /dev/\${DEV_LABEL} \${MYSQL_HOME} mysqld --user=root --daemonize } stop() { killall mysqld echo "Stopping mysqld..." } restart() { stop sleep 2 start } case "\$1" in start) start ;; stop) stop ;; restart) restart ;; *) echo "Usage: \$0 {start|stop|restart}" exit 1 esac exit 0 EOF -
执行以下命令,为脚本添加可执行权限。
sudo chmod +x /etc/rc.d/init.d/ebs_mysql_16k_auto_start.sh -
执行以下命令,添加脚本开启自启动任务。
sudo chkconfig --add ebs_mysql_16k_auto_start.sh -
执行以下命令,配置脚本开启自启动。
sudo chkconfig ebs_mysql_16k_auto_start.sh on
-
通过实验室一键部署(用于快速验证和测试新特性)
通过块存储EBS的实验室一键式部署MySQL服务,无需手动购买资源和搭建环境。该实验室场景基于资源编排服务的自动编排及部署能力,结合ESSD云盘的16K原子写能力和MySQL的业务场景,提供更加简单易上手的MySQL应用实践。
-
前往实验场景页面。
-
登录块存储EBS控制台。
首次登录EBS控制台时,请根据页面提示创建一个EBS服务关联角色。更多信息,请参见块存储EBS服务关联角色。
-
在左侧导航栏选择实验室 > 实验场景。
-
在顶部菜单栏左上角处,选择地域。
-
在基于EBS部署高性能的MySQL和对比环境实验场景模板中,单击一键创建实验任务。
-
-
在创建实验任务向导页面,设置实验场景的基础信息,然后单击下一步。
参数
说明
实验场景
默认为基于EBS部署高性能的MySQL服务。
实验任务名称
已默认填写,可根据需要修改。
描述
(非必填)设置实验任务的描述信息。
-
在依赖检查界面,检查依赖情况,显示为未发现异常时,单击下一步。
-
在资源参数页面,修改实验任务的参数后,单击下一步。
参数
说明
可用区
选择实例对应的可用区。示例选择
cn-hangzhou-gECS 实例规格
选择需要创建的实例规格,示例选择
ecs.c6.2xlarge,为8核16GB内存实例。实例密码
已默认填写,可根据需要修改。
重要请牢记设置的实例密码,以便后续远程连接ECS实例。
系统盘磁盘类型
选择需要创建的系统盘类型,示例选择
cloud_essd。系统盘大小
按需填写系统盘大小,示例为
40 GiB。数据盘磁盘类型
仅支持cloud_essd,ESSD PL1云盘。
数据盘性能等级
仅支持PL1
数据盘大小
按需添加数据盘大小,示例为
500 GiB。数据库密码
已默认填写,可根据需要修改。
重要请牢记设置的数据库密码,以便后续连接MySQL。
数据库端口
MySQL Server的启动端口3306。
访问MySQL数据库时,还需要在ECS实例的安全组中开放3306端口才能正常访问。具体操作,请参见添加安全组规则。
-
检查确认配置参数以及费用信息后,单击确认。在弹出的创建实验任务对话框中,单击确定。
创建任务成功后,系统会准备资源,并帮助搭建好对应的实验场景,预计需要5分钟,请耐心等待。
实验任务依赖于ROS资源编排能力,一个实验任务对应于一个资源栈,最多允许创建200个实验任务。
-
当任务状态变为创建完成后,可单击实验任务ID,查看任务配置详细信息。
验证与清理
验证方案
验证MySQL服务可用性
-
登录ECS实例。
-
访问ECS控制台-实例。在页面左侧顶部,选择目标资源所在的资源组和地域。
-
进入目标实例详情页,单击远程连接,选择通过Workbench远程连接。根据页面提示登录,进入终端页面。
-
-
(条件必选)执行以下命令,查看MySQL的临时密码。
如果通过实验室一键部署,无需执行本操作查看密码,使用创建实验任务时设置的数据库密码登录MySQL即可。
sudo cat ${MYSQL_HOME}/log/mysql/master-error.log | grep root | grep "temporary password" | awk '{print $13}' -
执行以下命令,登录MySQL。
mysql -uroot -p输入上一步获取的密码,即可登录MySQL。
[ecs-user@iZbpxxx init.d]$ mysql -uroot -p Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 10 Server version: 8.0.27 Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> -
(条件必选)执行以下命令,修改MySQL的root用户密码。 如果通过实验室一键部署,无需执行本操作修改密码。
alter user 'root'@'localhost' identified by '<new_password>'; -
执行以下命令,退出MySQL。
exit -
(条件必选)如果配置了开机重启,执行以下命令重启ECS后,MySQL服务将自动启动。
sudo reboot -
执行以下命令,验证MySQL服务是否正常重启。
ps aux | grep mysqld
测试MySQL性能
如果需要测试MySQL服务的性能,可以参考如下步骤:
-
登录ECS实例。
-
访问ECS控制台-实例。在页面左侧顶部,选择目标资源所在的资源组和地域。
-
进入目标实例详情页,单击远程连接,选择通过Workbench远程连接。根据页面提示使用密码登录,进入终端页面。
-
-
执行以下命令,安装SysBench。
sudo yum install -y sysbench -
执行以下命令后,输入MySQL数据库密码,登录MySQL。
mysql -uroot -p -
执行以下命令,创建sbtest数据库。
create database sbtest; -
执行quit,退出MySQL后,执行以下命令,进行性能测试,包括OLTP读写混合场景压测、OLTP只读场景压测和OLTP只写场景压测。
OLTP读写混合场景
参考如下命令进行测试,参数说明请参考性能测试指导。threads取值受示例规格、云盘以及环境等众多因素的影响,本示例以16为例,请根据实际情况修改。
##准备数据 sysbench --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password=<数据库root密码> --mysql-db=sbtest --table_size=25000 --tables=100 --events=0 --time=300 --threads=16 oltp_read_write prepare ##运行workload sysbench --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password=<数据库root密码> --mysql-db=sbtest --table_size=25000 --tables=100 --events=0 --time=300 --threads=16 --percentile=95 --report-interval=1 oltp_read_write run ##清理数据 sysbench --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password=<数据库root密码> --mysql-db=sbtest --table_size=25000 --tables=100 --events=0 --time=300 --threads=16 --percentile=95 oltp_read_write cleanup本示例数据仅供参考:
-
QPS:40131.20
-
TPS:2006.56
-
时延:12.08 ms
SQL statistics: queries performed: read: 8428364 write: 2408104 other: 1204052 total: 12040520 transactions: 602026 (2006.56 per sec.) queries: 12040520 (40131.20 per sec.) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: 300.0273s total number of events: 602026 Latency (ms): min: 2.78 avg: 7.97 max: 93.89 95th percentile: 12.08 sum: 4798582.91 Threads fairness: events (avg/stddev): 37626.6250/109.14 execution time (avg/stddev): 299.9114/0.01OLTP只读场景
参考如下命令进行测试,参数说明请参见性能测试指导。threads取值受示例规格、云盘以及环境等众多因素的影响,本示例以16为例,请根据实际情况修改。
##准备数据 sysbench --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password=<数据库root密码> --mysql-db=sbtest --table_size=25000 --tables=100 --events=0 --time=300 --threads=16 oltp_read_only prepare ##运行workload sysbench --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password=<数据库root密码> --mysql-db=sbtest --table_size=25000 --tables=100 --events=0 --time=300 --threads=16 --percentile=95 --skip-trx=1 --report-interval=1 oltp_read_only run ##清理数据 sysbench --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password=<数据库root密码> --mysql-db=sbtest --table_size=25000 --tables=100 --events=0 --time=300 --threads=16 --percentile=95 oltp_read_only cleanup本示例数据仅供参考:
-
QPS:51967.26
-
TPS:3711.95
-
时延:6.55 ms
SQL statistics: queries performed: read: 15591072 write: 0 other: 0 total: 15591072 transactions: 1113648 (3711.95 per sec.) queries: 15591072 (51967.26 per sec.) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: 300.0158s total number of events: 1113648 Latency (ms): min: 1.34 avg: 4.31 max: 78.50 95th percentile: 6.55 sum: 4797588.65 Threads fairness: events (avg/stddev): 69603.0000/222.22 execution time (avg/stddev): 299.8493/0.00OLTP只写场景
参考如下命令进行测试,参数说明请参见性能测试指导。threads取值受示例规格、云盘以及环境等众多因素的影响,本示例以32为例,请根据实际情况修改。
##准备数据 sysbench --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password=<数据库root密码> --mysql-db=sbtest --table_size=25000 --tables=100 --events=0 --time=300 --threads=32 oltp_write_only prepare ##运行workload sysbench --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password=<数据库root密码> --mysql-db=sbtest --table_size=25000 --tables=100 --events=0 --time=300 --threads=32 --percentile=95 --report-interval=1 oltp_write_only run ##清理数据 sysbench --db-driver=mysql --mysql-host=127.0.0.1 --mysql-port=3306 --mysql-user=root --mysql-password=<数据库root密码> --mysql-db=sbtest --table_size=25000 --tables=100 --events=0 --time=300 --threads=32 --percentile=95 oltp_write_only cleanup本示例数据仅供参考。
-
QPS:42661.18
-
TPS:7110.20
-
时延:7.84 ms
SQL statistics: queries performed: read: 0 write: 8533300 other: 4266650 total: 12799950 transactions: 2133325 (7110.20 per sec.) queries: 12799950 (42661.18 per sec.) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: 300.0360s total number of events: 2133325 Latency (ms): min: 0.91 avg: 4.50 max: 824.81 95th percentile: 7.84 sum: 9596350.52 Threads fairness: events (avg/stddev): 66666.4062/189.47 execution time (avg/stddev): 299.8860/0.01 -
性能结果对比
通过以下步骤验证本文提供的部署方案与普通部署方案对MySQL性能的提升效果。
-
对比规格
建议普通部署与本文部署使用完全一致的实例规格、云盘规格、MySQL安装方法和参数配置。普通部署也以实例规格是ecs.g7.large、数据盘是500 GiB的ESSD PL1、镜像是CentOS 7、MySQL是8.0为例。
-
部署MySQL步骤
-
测试结果对比
重要测试结果受不同实例、云盘以及环境等众多因素的影响,本示例数据仅供参考。
-
本文部署MySQL性能测试结果
sysbench 写入基准测试完成,事务吞吐量为 7110.20 TPS,查询吞吐量为 42661.18 QPS,95th 百分位延迟为 7.84 ms。
SQL statistics: queries performed: read: 0 write: 8533300 other: 4266650 total: 12799950 transactions: 2133325 (7110.20 per sec.) queries: 12799950 (42661.18 per sec.) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: 300.0360s total number of events: 2133325 Latency (ms): min: 0.91 avg: 4.50 max: 824.81 95th percentile: 7.84 sum: 9596350.52 Threads fairness: events (avg/stddev): 66666.4062/189.47 execution time (avg/stddev): 299.8860/0.01 -
普通部署MySQL性能测试结果
SQL statistics: queries performed: read: 0 write: 4780400 other: 2390200 total: 7170600 transactions: 1195100 (3983.21 per sec.) queries: 7170600 (23899.24 per sec.) ignored errors: 0 (0.00 per sec.) reconnects: 0 (0.00 per sec.) General statistics: total time: 300.0333s total number of events: 1195100 Latency (ms): min: 0.78 avg: 8.03 max: 266.19 95th percentile: 16.12 sum: 9597436.64 Threads fairness: events (avg/stddev): 37346.8750/106.14 execution time (avg/stddev): 299.9199/0.01
通过本文部署MySQL的QPS为42661,而普通部署MySQL的QPS为23899,性能提升约44%,在TPS、时延等方面也会有一些性能提升。
-
清理资源
如果通过实验室一键部署,测试完成后建议及时清理相关资源,避免继续产生费用。
推荐通过实验室一键删除实验任务的相关资源,不建议通过ECS控制台或者EBS控制台释放实例和云盘,避免误操作导致实验任务资源不可用。
-
登录块存储EBS控制台。
-
在左侧导航栏选择实验室 > 实验记录。
-
在顶部菜单栏左上角处,选择地域。
-
在目标实验任务的操作列,单击删除。
也可以选中多个实验任务,在列表底部单击批量删除。
删除实验任务时默认不会释放实验资源,如果选中删除资源,实验任务中的资源,例如ECS实例、数据库实例等均会被释放,请谨慎操作。