• MySQL 5.7 压测结果

    背景

    公司的业务更新,新部门需要用MySQL5.7版本。 本人之前也只是研究和测试过,并没有真的在线上投入使用过5.7版本,所以需要在服务器上进行一系列的压测,得到数据库服务器所能承载的压力。虽然之前曾经用过sysbench压测,但是在实际使用过程中还是遇到了一些问题。

    首先,我压测的目的在于:在现有机器配置下,MySQL5.7所能承受的QPS、线程并发数、IOPS、TPS等基本特性的能力。

    其次,我希望将压测的结果整理成直观的图形界面,方便查看。

    在开始之前,我首先附上MySQL官方对于5.7版本的测试图例:

    yy

    如上,官方测试的结果是 MySQL 5.7 在Point Select 查询测试中,测试成绩可以达到1600000 QPS, 是MySQL 5.6 的3倍多。

    官方的测试环境如下:

    • Intel(R) Xeon(R) CPU E7-8890 v3h
    • 4 sockets x 18 cores-HT (144 CPU threads)
    • 2.5 GHz, 512GB RAM
    • Linux kernel 3.16

    在我们的真实测试的结果可能会和官方的结果有比较大的差距,因为官方的服务器配置还是挺高的。

    将压测结果绘图的方法

    有些时候,我们需要将一些例如压测、数据统计等结果以图形的方式统计出来。下面简单的说一下我的方式,就是用最简单Execl了。

    1. 收集需要绘制成图表的数据

    2. 将数据填入Execl表格,纵向表示多种对比的测试模式、横向表示各个测试模式在不同条件下的测试结果值。

    %e5%b1%8f%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-18-%e4%b8%8b%e5%8d%888-08-55

    如上,将数据写入Execl后,将数据选中后,选择插入—推荐的图标,就会有很多形式的框图供你选择:

    %e5%b1%8f%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-18-%e4%b8%8b%e5%8d%888-11-53

    如上,就可以获得我们想要的图形结果了。

    注: 如果对MySQL不是很了解,或者没有丰富的压测经验,有时候很难去把握压测的基准值和方法,这里附上一篇叶金荣老师的博客,可以来简单做一些参考:

    http://imysql.cn/tag/压测

    内容

    不得不说,我在实际使用中遇到的第一个问题就是sysbench的安装。虽然网上有很多教程,但是中间总是会遇到一些库依赖关系难以轻易解决。虽然我们可以直接通过yum安装的形式很轻易的就安装sysbench,但是一般yum安装默认安装的是0.4版本的sysbench,此版本很多功能不太完善,比如不支持多表压测等。

    因为解决过程因情况和环境而异,这里就不再多做阐述了,只是在这里特提醒自己遇到问题的时候要按部就班的去解决,尝试,戒骄戒躁。

    压测服务器环境

    %e5%b1%8f%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-18-%e4%b8%8b%e5%8d%889-40-37

    注意:我们这里的数据库服务器是有硬件的RAID 缓存的,所以在测试的时候需要将此考虑进去。

    根据上面的服务器环境,我们应该保证在压测过程中照顾到如下几点:

    • 生成的压测数据至少需要大于我们设置的Innodb_buffer_pool_size,否则压测数据被缓存在内存中 。
    • 每轮测试完成后,用下面的方法删除系统cache,释放swap(如果用到了swap的话),如果条件允许最好可以重启MySQL甚至OS。

     压测使用参数

    上面是我在压测运行期间的使用参数,具体含义可以参考官方文档。

    压测的粒度以及影响压测的MySQL主要参数

    %e5%b1%8f%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-09-%e4%b8%8a%e5%8d%8810-45-06

     

     

     

     

     

    %e5%b1%8f%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-09-%e4%b8%8a%e5%8d%8810-46-05

    压测结果

    1. 只读测试的结果,与官方给出的结果差了一个数量级! 当然官方的配置比我的好些,不过我觉得还是我自己的测试过程有误差。

    %e5%b1%8f%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-08-%e4%b8%8b%e5%8d%8810-10-16

    2. 读写测试的结果,此测试结果与实际使用场景误差可能较大,因为我们有接近1G的Raid Cache缓存。并且压测数据量太小。

    %e5%b1%8f%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-08-%e4%b8%8b%e5%8d%889-49-23

    3. TPS 每秒事务数的压测结果,单个事务中可能包含增、删、改、查等操作,比例为  select:update_key:update_non_key:delete:insert = 14:1:1:1:1

    %e5%b1%8f%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-08-%e4%b8%8b%e5%8d%889-03-55

    4. 混合读写的平均响应时间的结果,响应时间纵坐标的单位为ms。因为测试对应的只有5张表,所以热点数据比较集中,真实场景的响应时间应该会低于上图。

    %e5%b1%8f%e5%b9%95%e5%bf%ab%e7%85%a7-2016-12-08-%e4%b8%8b%e5%8d%889-19-16

     

     

  • MySQL测试 —— sysbench

    背景

    sysbench可以执行多种类型的基准测试,它不仅可以用来测试数据库的性能,也可以测试服务器的性能。

    安装

    1. 安装相关具有依赖的软件包:

    yum install automake

    yum install libtool

    yum install zlib

    yum install  gcc glibc-devel  glibc-headers  glibc-kernheaders

    2. 从yum上安装clone源码包:

    git clone https://github.com/akopytov/sysbench.git

    3. 正式安装:

     ./autogen.sh

    ./configure –with-mysql-includes=/usr/local/sae/mysql56/include/mysql/  –with-mysql-libs=/usr/local/sae/mysql56/lib/mysql/

    注: 若不需要测试mysql,则./configure –without-mysql(不编译测试mysql的功能模块)

     

    make

    若报如下错误,则是因为没有安装mysql-shared,在官网下载大于等于当前版本的share库并且安装即可:

    /usr/bin/ld: cannot find -lmysqlclient_r

    collect2: ld returned 1 exit status

    make[2]: *** [sysbench] Error 1

    make[2]: Leaving directory /usr/home/xinyu17/sysbench/sysbench'

    make[1]: *** [all-recursive] Error 1

    make[1]: Leaving directory /usr/home/xinyu17/sysbench/sysbench’

    make: *** [all-recursive] Error 1

    mysql

    rpm  -ivh  MySQL-shared-5.6.29-1.linux_glibc2.5.x86_64.rpm

    编译完成后可以看到在sysbench/sysbench/下又生成一个sysbench可执行文件。

    测试内容:

    测试实例:

    1. CPU测试实例:计算3000 以内的素数的加法

    sysbench –test=cpu  –cpu-max-prime=3000 run

    box

    在30000以内的素数之和用的时间是2.5394 s.

    CPU性能测试有一个需要注意的地方,上面的测试只使用了一个线程,如果在两个cpu processor不同的电脑上做比较,这是不公平的。公平的做法是指定合理的线程数,如下所示:

    在sysbench的测试中,–num-threads取值为”线程数量”即可,再大的值没有什么意义,对测试结果也没有什么影响。

    2. fileio测试

    文件IO(fileio)基准测试可以测试系统在不同IO负载下的性能。这对于比较不同的硬盘驱动器,不同的RAID 卡,不同的RAID 模式,都很有帮助。可以根据测试结果调整IO子系统。文件IO基准测试模拟了很多InnoDB 的IO特性。

    测试的第一步是准备(Prepare)阶段,生成测试用到的数据文件,生成的数据文件至少要比内存大。 如果文件中的数据能完全放入内存中,则操作系统 缓存大部分的数据,导致测试结果无法体现IO密集型的工作负载。首先通过下面的命令创建一个数据集:

    这个命令会在当前工作目录下创建测试文件,后续的运行(run)阶段将通过读写这些文件进行测试。 第二步就是运行(run)阶段,针对不同的IO 类型有不同的测试选项:

    • seqwr 顺序写入
    • seqrewr 顺序重写
    • seqrd 顺序读取
    • rndrd 随机读取
    • rndwr 随机写入
    • rndrw 混合随机读/写

    sysbench –test=fileio –num-threads=16 –file-total-size=1G –file-test-mode=rndrw run

    io

    输出结果中包含了大量的信息。和IO子系统密切相关的包括每秒请求数和总吞吐量。在上述例子中, 每秒请求数是18547.52 Requests/sec , 吞吐量是289.8Mb/sec 。另外,时间信息也非常有用, 尤其是大约95%的时间分布。这些数据对于评估磁盘性能十分有用。

    测试完成以后,运行清除(cleanup)操作删除第一步生成的测试文件。

    sysbench –test=fileio –num-threads=16 –file-total-size=1G –file-test-mode=rndrw cleanup

    3. OLTP 测试

    oltp 基准测试模拟了一个简单的事务处理系统的工作负载。 下面的例子使用的是一张超过百万行记录的表,第一步是先生成这张表:

    ./sysbench –test=tests/db/oltp.lua –mysql-table-engine=myisam –oltp-table-size=1000000 –oltp_tables_count=10 –mysql-socket=/tmp/mysql3307.sock –mysql-user=root –mysql-host=localhost –mysql-password=123456  prepare

    • –test=tests/db/oltp.lua 表示调用 tests/db/oltp.lua 脚本进行 oltp 模式测试
    • –oltp_tables_count=10 表示会生成 10 个测试表
    • –oltp-table-size=100000 表示每个测试表填充数据量为 100000
    • –rand-init=on 表示每个测试表都是用随机数据来填充的

    真实测试场景中,数据表建议不低于 10个 ,单表数据量不低于 500万行 ,当然了,要视服务器硬件配置而定。如果是配备了SSD或者PCIE SSD这种高IOPS设备的话,则建议单表数据量最少不低于 1亿行 .

    数据加载完成以后就可以开始测试了,这个例子采用了16个线程,测试时长为720秒,结果中最最重要的是每秒事务数。

    1.  –max-requests 默认值为10000 ,如果设置了–max-requests 或者使用默认值 ,分析结果的时候主要查看运行时间(total time),一般情况下,都将–max-requests 赋值为0 ,即不限制请求数量,通过–max-time 来指定测试时长,然后查看系统的每秒事务数。

    2.  –oltp-test-mode用以指定测试模式,取值有(simeple,complex,nontrx),默认是complex。不同模式会执行不同的语句。 具体执行语句如下所示:

    Simple 这种模式只是简单的执行selec语句如:

    SELECT c FROM sbtest WHERE id=N

    complex(Advanced transactional) 在事务中,可能包含下列语句如:

    SELECT c FROM sbtest WHERE id BETWEEN N AND M

    SELECT SUM(K) FROM sbtest WHERE id BETWEEN N and M

    SELECT c FROM sbtest WHERE id between N and M ORDER BY c

    SELECT DISTINCT c FROM sbtest WHERE id BETWEEN N and M ORDER BY c

    UPDATE sbtest SET k=k+1 WHERE id=N

    INSERT INTO sbtest VALUES (...)

    DELETE FROM sbtest WHERE id=N

    3. simple模式和在complex模式下开启read-only选项都只包含select语句。但是 simple 模式只包含最简单的select语句,相反地,complex 模式中,如果我们开启read-only 选项,即--oltp-read-only=on,则会包含复杂的SQL语句。如:

    SELECT SUM(K) FROM sbtest WHERE id BETWEEN N and M SELECT DISTINCT c FROM sbtest WHERE id BETWEEN N and M ORDER BY c;

     

    参考:

    http://mingxinglai.com/cn/2013/07/sysbench/