MyCAT 的性能测试主要是通过使用 MyCAT 自带的性能测试工具 testtool 来完成。本文将介绍该工具的使用。
环境介绍
数据库服务 mysql 运行在 192.168.2.201 (host:workstation)机器上,操作系统 Ubuntu 14.04;MyCAT 服务运行在 192.168.2.202 (host:reg-server)机器上,操作系统 Centos 7;testtool 运行在一台虚拟机上,虚拟机的主机是 192.168.2.201。
由于 Centos 7 上使用了 iptables 防火墙,在安装完成之后,还需要使用 iptables -F
清空一下防火墙规则,防止 MyCAT 的 8806 端口被阻挡。
建立测试表
测试表的表结构描述如下,
person表: * Id,主键,Mycat自增主键 * name,字符串,16字节最长 * school,毕业学校,数字,1-1000范围,是学校编号 * age,年龄,18-60 * addr,地址,32字节,建议为 gz-tianhe(城市-地区两级 枚举的仿真数据) * zcode,邮编, * birth,生日,为日期类型, 1980到2010年之间随机的日期 * score,得分,0-100分
建表语句如下,
1 2 3 4 5 6 7 8 9
| create table person ( id bigint not null primary key, name varchar(16), school smallint, age tinyint, addr varchar(32), zcode varchar(6), birth DATE, score tinyint);
|
MyCAT 中也需要配置,schema.xml
配置采用 murmur 分片算法,该算法默认在3个分片中采用一致性哈希的方法分片,如下
1 2
| <table name="person" primaryKey="ID" autoIncrement="true" dataNode="dn1,dn2,dn3" rule="sharding-by-murmur" />
|
注意,person 表启用了自增主键,需要配置 MyCAT sequence。在 server.xml
中配置使用表的方式来管理 MyCAT sequence,
1
| <property name="sequnceHandlerType">1</property>
|
在 sequence_db_conf.properties
中增加一行,表示 person 表的 sequence 管理表是来自 dn1 节点,
在 dn1 节点中,新增管理 sequence 需要的相关表和函数,如下,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| CREATE TABLE MYCAT_SEQUENCE ( NAME VARCHAR (50) NOT NULL, current_value INT NOT NULL, increment INT NOT NULL DEFAULT 100, PRIMARY KEY (NAME) ) ENGINE = INNODB; INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES ('PERSON', 100000, 100); INSERT INTO MYCAT_SEQUENCE(name,current_value,increment) VALUES ('GLOBAL', 100000, 100); DROP FUNCTION IF EXISTS mycat_seq_currval; DELIMITER CREATE FUNCTION mycat_seq_currval(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf-8 DETERMINISTIC BEGIN DECLARE retval VARCHAR(64); SET retval="-999999999,null"; SELECT concat(CAST(current_value AS CHAR),",",CAST(increment AS CHAR)) INTO retval FROM MYCAT_SEQUENCE WHERE name = seq_name; RETURN retval; END DELIMITER; DROP FUNCTION IF EXISTS mycat_seq_setval; DELIMITER CREATE FUNCTION mycat_seq_setval(seq_name VARCHAR(50),value INTEGER) RETURNS varchar(64) CHARSET utf-8 DETERMINISTIC BEGIN UPDATE MYCAT_SEQUENCE SET current_value = value WHERE name = seq_name; RETURN mycat_seq_currval(seq_name); END DELIMITER; DROP FUNCTION IF EXISTS mycat_seq_nextval; DELIMITER CREATE FUNCTION mycat_seq_nextval(seq_name VARCHAR(50)) RETURNS varchar(64) CHARSET utf-8 DETERMINISTIC BEGIN UPDATE MYCAT_SEQUENCE SET current_value = current_value + increment WHERE name = seq_name; RETURN mycat_seq_currval(seq_name); END DELIMITER;
|
其他采用默认配置即可。配置完成之后,重启 mycat 进程。如果配置成功,那么以下 sql 可以在 mycat 上运行成功,
1 2
| insert into person(name, school, age, addr, zcode, birth, score) values('qwertyuioasdfg', 1000, 60, 'gz-tianhe', 123323, '20000131', 100);
|
testtool 介绍
testtool 主要包含以下工具,
- test_globaltable_insert_perf.sh,全局表插入测试
- test_stand_merge_sel_perf.sh,分片表聚合查询测试
- test_stand_update_perf.sh,标准单表更新测试
- test_stand_insert_perf.sh,标准单表插入测试
- test_stand_select_perf.sh,标准单表查询测试
本次测试主要使用的是单表测试工具,使用 testtool 需要先建立仿真测试文件,person-insert.sql
文件内容如下,
1 2 3 4
| total=4000 sql=insert into person(name, school, age, addr, zcode, birth, score) values('${char([a-f,0-9]8:10)}', ${int(1-1000)}, ${ int(18-60)}, '${char([a-f]2:2)}-${char([a-f]4:29)}', ${int(100000-999999)}, '${date(yyyyMMdd-[2000-2001]y)}', ${int(0-10 0)})
|
可以简单运行一下 testtool 予以验证,
1
| ./test_stand_insert_perf.sh jdbc:mysql://workstation:8066/TESTDB test test 10 "file=person-insert.sql"
|
如果运行不报错,说明测试工具可以正常使用。
测试脚本和监控工具
为了比对 mysql 单表和 mycat 分片不同情况下的对比,因此为此次测试编写了测试脚本,脚本如下,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| #!/bin/bash for p in $*; do echo "========================================================================" echo "Step Size: $p"; mysql -hworkstation -Ddb1 -uroot -P3306 -p111111 -e "update MYCAT_SEQUENCE set increment = $p where name = 'PERSON';" mysql -hreg-server -utest -DTESTDB -P8066 -ptest -e 'create table person ( id bigint not null primary key, name varchar(16), school smallint, age tinyint, addr varchar(32), zcode varchar(6), birth DATE, score tinyint);' ./test_stand_insert_perf.sh jdbc:mysql://reg-server:8066/TESTDB test test 5 "file=person-insert.sql" mysql -hreg-server -utest -DTESTDB -P8066 -ptest -e 'drop table person' sleep 5 done
|
以上脚本放在 mycat 的 bin 目录下,可以如下使用,
1
| ./mycat-perf-test.sh 10 100 100010000 > result.txt
|
表示,分别按10、100、1000、10000 为步长增加主键,并 mycat 进行插入数据测试,测试的输出写入 result.txt 文件中。每次执行插入之后,暂停5秒。
监控工具采用Nmon,监控参数如下,
1
| ./nmon_x86_64_ubuntu13 -s 1 -c 3600 -f
|
每1秒监控一次,最多监控3600次。监控在安装 mysql 的 Ubuntu 服务器上进行。
监控结果
最终的 result.txt 内容如下,
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| // 省略部分log ======================================================================== Step Size: 10 check JAVA_HOME & java create jobs ... total record 4000 batch size:100 autocomit false success ful created connections ,total :5 create jobs finished ,begin run test... success create job count: 5 teset threads: 5 06 15:55:20 finished records :0 failed:0 speed:0.0 ...... 06 15:56:18 finished records :3800 failed:0 speed:66.5918968176083 finishend:4000 failed:0 used time total:58seconds tps:68.84681583476764 ======================================================================== Step Size: 100 check JAVA_HOME & java create jobs ... total record 4000 batch size:100 autocomit false success ful created connections ,total :5 create jobs finished ,begin run test... success create job count: 5 teset threads: 5 06 15:56:26 finished records :0 failed:0 speed:0.0 ...... 06 15:56:52 finished records :3600 failed:0 speed:138.24884792626727 finishend:4000 failed:0 used time total:27seconds tps:147.60147601476015 ======================================================================== Step Size: 1000 check JAVA_HOME & java create jobs ... total record 4000 batch size:100 autocomit false success ful created connections ,total :5 create jobs finished ,begin run test... success create job count: 5 teset threads: 5 06 15:57:01 finished records :0 failed:0 speed:0.0 ...... 06 15:57:11 finished records :3500 failed:0 speed:349.23169028138096 finishend:4000 failed:0 used time total:11seconds tps:360.36036036036035 ======================================================================== Step Size: 10000 check JAVA_HOME & java create jobs ... total record 4000 batch size:100 autocomit false success ful created connections ,total :5 create jobs finished ,begin run test... success create job count: 5 teset threads: 5 06 15:57:19 finished records :0 failed:0 speed:0.0 ...... 06 15:57:31 finished records :3600 failed:0 speed:299.2269969246114 finishend:4000 failed:0 used time total:13seconds tps:305.3435114503817
|
可以发现,随着 step 的增大,tps在显著增长;但是在 step 增大到一定范围的时候,tps 不再有显著增长。原因是,由于自增的 sequence 是在表中存放的,每次插入数据的时候,取序号都受到这张表的访问速度限制。所以,在 step 比较小的时候,访问表的次数较多,因此 tps 比较低;在 step 比较大的时候,访问表的次数较少,因此 tps 比较高;在 step 超过一定值之后,访问表的次数已经很少,因此 tps 的值不再有显著变化。