mysql+mycat压力测试一例【转】
前言
有很多人担心生产系统上新东西的程序怕压力跟不上和稳定性不行,是的,大家都怕,所以领导要求做一次压力测试,我个人也觉得是有必要的.
如果按原理来说,mycat如果不做分片,纯粹只是代理的话,他所做的事情,其实更多的是数据转发,而这个转发能力,当然就是看他能有多强.
既然理论上转发能力很强,那么是不是就可以忽略不计呢,当然不是,所以需要用直连mysql的测试数据来做对比.
测试前准备
服务器配置为32核cpu(虚拟化后的数值,算上超线程),120G内存,16000iops的存储设备,具体分配情况:
10.21.128.156:mycat1.6.5,sysbench0.4
10.21.128.157:mysql5.7.20主库
10.21.128.158:mysql5.7.20从库1
10.21.128.159:mysql5.7.20从库2
简单说明拓扑关系:
第一步当然是安装好mysql,这里就不详细介绍怎么安装了,但是,my.cnf的参数是有些变化的,主要原因是要适应高并发压测环境,不然就被参数限制,然后程序退出.当然了,如果你想尽量模拟线上环境,那这些限制你得思考在内,更改就需要谨慎一些,我这里只是给出一例来参考.
1
2
3
4
5
6
7
8
9
|
#首先,就是要把系统的连接数和打开文件数搞起来 ulimit -SHn 65535 #想永久生效就要这样 echo " * soft nofile 65535 * hard nofile 65535 root soft nofile 65535 root hard nofile 65535 " >> /etc/security/limits .conf |
然后,更改mysql配置文件参数,其他buffer_pool什么的就不列出来了,请各自看情况设置,这里只说明涉及压测相关的参数.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
#打开配置文件 vim /usr/local/mysql/my .cnf #其他参数我们暂时忽略,只看这些关乎压测的参数 [mysqld] #每台机都需要不一样的ID,主从环境下 server- id = 128157 #全局最大打开文件数,不可以超过系统设定的最大文件数,不然无效 open_files_limit = 65530 #innodb引擎限制一次打开表空间文件.ibd的文件描述符数量 innodb_open_files = 65530 #允许存到缓存里的表的句柄数量,压测自然要打开很多表,设大一点就对了,受系统limit和上面两个参数一起限制 table_open_cache = 65000 #实例可用最大连接数,必须设置足够大,不然连接数超出限制,测着报错不通就麻烦了,最少也比你实际要用到的多三分一 max_connections=30000 #最大每用户连接数,限制每个用户最大连接数,一定要比上面少一点 max_user_connections=20000 #最大数据包大小,做压测改大一点还是有必要 max_allowed_packet = 128M #限制了同一时间在mysqld上所有session中prepared 语句的上限,平时不用理这个参数,但是压测就需要调大一点 max_prepared_stmt_count=100000 |
其他参数我就不一一列举,自己看情况来设置就行,然后,重启生效待命.
软件安装
先说说压测工具的选择问题,在MySQL协议上Mycat不兼容tpcc,所以放弃tpcc。然后sysbench1.0对mycat兼容也比较欠佳,不明原因压测失败次数多,所以也只能放弃.
最后选定sysbench0.4和0.5来使用,可以顺利测出结果,而且从压测的原理来说也比较客观.
所以,我们需要安装的软件有:mysql(默认已装),mycat,sysbench0.4或0.5
mysql怎么安装和授权什么的,这里就不细说了,还请各位自己搭建好,配置文件就上面提到的要加上一下.
安装mycat:
1)搭建jdk环境
由于mycat是java程序,所以需要安装JDK,版本至少要jdk1.6以上,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#下载好安装包后,解压创建软连接 tar xf jdk-8u144-linux-x64. tar .gz mv jdk1.8.0_144/ /usr/local/ ln -sf jdk1.8.0_144/ jdk #创建环境变量 vim /etc/profile .d /java .sh export JAVA_HOME= /usr/local/jdk export JRE_HOME= /usr/local/jdk/jre export CLASSPATH=.:$JAVA_HOME /lib/dt .jar:$JAVA_HOME /lib/tools .jar:$JRE_HOME /lib export PATH=$PATH:$JAVA_HOME /bin #重载环境变量 source /etc/profile #验证安装 java -version java version "1.8.0_144" Java(TM) SE Runtime Environment (build 1.8.0_144-b01) Java HotSpot(TM) 64-Bit Server VM (build 25.144-b01, mixed mode) |
安装完成,可以使用.
2)配置mycat
了解java程序的同学应该知道,java程序只要配置好,直接启动就能用,所以没有安装的概念,直接将mycat配置做好就可以用.
因为sysbench的测试没有涉及分库分表,所以mycat只需要设置server.xml和schema.xml即可,具体mycat存放路径没规定,我将他放在/usr/local了.
ps:有意向做分库分表压测的就要把数据做一些处理,按照sysbench原理来说是可行的,他测试的表的数量是可控的,你把带数字编号的表通过逻辑库处理可以集合成一个新的逻辑表.
先看基本环境设置server.xml,大部分设置都可以不动,注意添加修改的是<system>标签下面配置就可以了,每创建一个用户<user>是要另外起标签:
vim /usr/local/mycat/conf/server.xml
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
|
< system > < property name = "idleTimeout" >2880000</ property > <!--设置超时时间为28800秒 --> < property name = "maxPacketSize" >134217728</ property > <!--设置最大网络包为128M --> < property name = "charset" >utf8</ property > <!--设置默认字符集为utf8 --> < property name = "txIsolation" >2</ property > <!--设置隔离级别为RC --> < property name = "sqlExecuteTimeout" >600</ property > <!--设置sql执行的超时时间为600秒 --> </ system > <!--下面是设置mycat的用户名/密码和权限控制,和mysql的用户名密码无关 --> < user name = "root" defaultAccount = "true" > < property name = "password" >mycat123</ property > < property name = "schemas" >sbtest,testppp</ property > </ user > < user name = "sysbench" > < property name = "password" >sb123</ property > < property name = "schemas" >sbtest</ property > </ user > < user name = "test" > < property name = "password" >test</ property > < property name = "schemas" >sbtest</ property > < property name = "readOnly" >true</ property > < privileges check = "false" > < schema name = "sbtest" dml = "0001" > < table name = "sbtest11" dml = "1111" ></ table > </ schema > </ privileges > </ user > |
设置了一些相关压测的项目参数,和创建了三个用户root,sysbench,test.这三个用户和数据库的用户没有关联,是独立的,即使这个用户密码被破解,数据库的密码依然安全.其中root有完全控制权限,sysbench只能控制sbtest库,test也只能控制sbtest库,而且限制了读写权限.
然后设置逻辑库配置文件schema.xml,这里改动比较多,所以直接贴上整个文件:
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
|
<? xml version = "1.0" ?> <!DOCTYPE mycat:schema SYSTEM "schema.dtd"> < mycat:schema xmlns:mycat = "http://io.mycat/" > < schema name = "sbtest" checkSQLschema = "false" sqlMaxLimit = "100" dataNode = "dn1" > </ schema > < schema name = "testppp" checkSQLschema = "false" sqlMaxLimit = "100" dataNode = "dn2" > </ schema > <!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743" /> --> < dataNode name = "dn1" dataHost = "10.21.128.157" database = "sbtest" /> < dataNode name = "dn2" dataHost = "10.21.128.157" database = "testppp" /> <!--<dataNode name="dn4" dataHost="sequoiadb1" database="SAMPLE" /> <dataNode name="jdbc_dn1" dataHost="jdbchost" database="db1" /> <dataNode name="jdbc_dn2" dataHost="jdbchost" database="db2" /> <dataNode name="jdbc_dn3" dataHost="jdbchost" database="db3" /> --> < dataHost name = "10.21.128.157" maxCon = "3000" minCon = "20" balance = "0" writeType = "0" dbType = "mysql" dbDriver = "native" switchType = "-1" slaveThreshold = "100" > < heartbeat >select user()</ heartbeat > <!-- can have multi write hosts --> < writeHost host = "hostM1" url = "10.21.128.157:3306" user = "root" password = "128157" > <!-- can have multi read hosts --> < readHost host = "hostS2" url = "10.21.128.158:3306" user = "root" password = "128157" /> < readHost host = "hostS3" url = "10.21.128.159:3306" user = "root" password = "128157" /> </ writeHost > <!-- <writeHost host="hostM2" url="localhost:3316" user="root" password="123456"/> --> </ dataHost > </ mycat:schema > |
设置了两个逻辑库sbtest和testppp(和真实库同名,其实可以不同),指向的真实数据库的主从环境dn1和dn2,里面有一主两从三台真实服务器地址,并开启读写分离.但是要注意的是,事务只走主库,所以读写分离最优方案还是由程序做好一点,用中间件做难免就有点鸡肋了,毕竟现在很多开发框架都走事务的.
3) 启动mycat,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
#启动mycat Mycat start #重启mycat Mycat restart #关闭mycat Mycat stop #而Mycat默认的连接端口是8066,管理端口是9066,可以在server.xml修改. ss -ntplu | grep java tcp LISTEN 0 100 :::9066 :::* users :(( "java" ,pid=115779,fd=168)) tcp LISTEN 0 100 :::8066 :::* users :(( "java" ,pid=115779,fd=172)) #看到端口起来了,就可以使用了,因为mycat支持mysql原生协议,所以连上8066端口是不会和一般mysql有什么区别,直接就能使用了. #如果更改了任何配置文件,可以登录进管理端口执行下列命令实时热刷新配置,相当方便. mysql -uroot -pmycat123 -h10.21.128.156 -P9066 #更改server的配置可以 Mysql>reload @@config #如果改了schema的配置,需要这个命令 Mysql>reload @@config_all |
加载完成就可以使用新配置了,哪怕是改了登录用户名也能热加载.
搭建sysbench
下载下来后,只要有c运行库就能编译安装,但是要创建mysql库文件的软连接,不然会报错找不到库文件,
1
2
3
4
5
6
7
8
9
10
11
|
#先创建mysql库文件的软连接 ln -sf /usr/local/mysql/lib/ * /usr/lib64/ #然后执行: cd /tmp/sysbench-0 .4.12-1.1 . /autogen .sh . /configure --with-mysql-includes= /usr/local/mysql/include --with-mysql-libs= /usr/local/mysql/lib Make #如果 make 没有报错,就会在 sysbench 目录下生成二进制命令行工具 sysbench cd /tmp/sysbench-0 .4.12-1.1 /sysbench ls -l sysbench -rwxr-xr-x 1 root root 3293186 Sep 21 16:24 sysbench |
在此,环境就搭建完毕了.
开始测试
环境准备好了,就开始测试了,测试前要先准备测试数据,需要使用命令来制造出来,要比较长的时间(可能大半天),重点是要关注硬盘空间是否足够:
1
2
3
4
5
6
7
8
9
|
#避免不必要的错误,直连数据库操作 mysql -uroot -p128157 -h10.21.128.157 -P3306 #创建测试数据库,sysbench默认测试库名是sbtest,也可以指定库名 mysql> create database sbtest; #进入sysbench程序目录 cd /tmp/sysbench-0 .4.12-1.1 /sysbench #开始造数据, . /sysbench --mysql-host=10.21.128.157 --mysql-port=3306 --mysql-user=root --mysql-password=128157 -- test =tests /db/oltp .lua --oltp_tables_count=15 --oltp-table-size=40000000 --mysql-table-engine=innodb --rand-init=on prepare #再次强调,时间可能很长,需要耐心等待 |
参数解析:
--test=tests/db/oltp.lua 表示调用 tests/db/oltp.lua 脚本进行 oltp 模式测试,oltp是啥就不解析了
--oltp_tables_count=15 表示会生成 15 个测试表,数量越多,自然花费时间越长
--oltp-table-size=40000000 表示每个测试表填充数据量为 40000000行 ,数量越多也是越时间长
--rand-init=on 表示每个测试表都是用随机数据来填充的,这样才客观
--mysql-table-engine=innodb 表示表的引擎是innodb
prepare 用于准备测试需要的数据,准备完后执行run来测试,测试完成后如果需要清理数据就用cleanup来清除测试数据
所以这里创造了15个表,里面每个表有4000万行的数据,数据为随机输入,这个数据量大概需要150G硬盘空间,估计可以涵盖大部分情况了吧,当然,你也可以创建更多数据.
然后就可以进行正式测试了,我们先进行测试普通主从架构:
1
2
3
4
5
|
#进入sysbench程序目录 cd /tmp/sysbench-0 .4.12-1.1 /sysbench #执行测试命令 . /sysbench --mysql-host=10.21.128.157 --mysql-port=3306 --mysql-user=root --mysql-password=128157 -- test =tests /db/oltp .lua --oltp_tables_count=15 --oltp-table-size=40000000 --mysql-table-engine=innodb --num-threads=1024 --oltp- read -only=off --report-interval=10 --rand- type =uniform --max- time =3600 --max-requests=0 --percentile=99 run >> /tmp/sysbench_oltpX_32_20171113-1 .log #我们设定的是3600秒,在此之前终止,也就是测试失败,需要分析报错 |
参数解析:
--num-threads=1024 表示发起1024个并发连接
--oltp-read-only=off 表示不要进行只读测试,也就是会采用读写混合模式测试
--report-interval=10 表示每10秒输出一次测试进度报告
--rand-type=uniform 表示随机类型为固定模式,其他几个可选随机模式:uniform(固定),gaussian(高斯),special(特定的),pareto(帕累托)
--max-time=3600 表示最大执行时长为3600秒,测试将在这个时间后结束
--max-requests=0 表示总请求数为 0,因为上面已经定义了总执行时长,所以总请求数可以设定为 0;也可以只设定总请求数,不设定最大执行时长
--percentile=99 表示设定采样比例,默认是 95%,即丢弃1%的长请求,在剩余的99%里取最大值
根据上面的解析,最后输出到一个文件,毕竟需要记录下来.
然后到mycat代理环境:
1
|
. /sysbench --mysql-host=10.21.128.156 --mysql-port=8066 --mysql-user=sysbench --mysql-password=sb123 -- test =tests /db/oltp .lua --oltp_tables_count=15 --oltp-table-size=40000000 --mysql-table-engine=innodb --num-threads=1024 --oltp- read -only=off --report-interval=10 --rand- type =uniform --max- time =3600 --max-requests=40000000 --percentile=99 run >> /home/logs/sysbench_oltpX_32_20171113-2 .log |
和上面一样,设定了并发为1024个线程,测试时间为3600秒即1小时,同时也是用到刚才制造出来的15个4000万行的表,设定取值采样平均值为99%的数据,输出到另一个log文件.
阅读测试报告
测试完了,就来看结果了,我们拿其中一个结果来解析说一下:
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
|
#忽略掉一些每10秒统计值,只看最后的统计值 vim /tmp/sysbench_oltpX_32_20171113-1 .log sysbench 0.5: multi-threaded system evaluation benchmark Running the test with following options: Number of threads: 1024 Report intermediate results every 10 second(s) Random number generator seed is 0 and will be ignored Threads started! -- 每10秒钟报告一次测试结果,tps、每秒读、每秒写、99%以上的响应时长统计 [ 10s] threads: 1024, tps: 364.69, reads /s : 6324.66, writes /s : 1765.66, response time : 4292.46ms (99%) [ 20s] threads: 1024, tps: 475.80, reads /s : 6037.91, writes /s : 1640.10, response time : 4088.05ms (99%) [ 30s] threads: 1024, tps: 439.40, reads /s : 6349.45, writes /s : 1808.89, response time : 3248.44ms (99%) [ 40s] threads: 1024, tps: 487.70, reads /s : 6438.46, writes /s : 1879.72, response time : 4385.98ms (99%) [ 50s] threads: 1024, tps: 395.70, reads /s : 6498.99, writes /s : 1849.00, response time : 3845.88ms (99%) . . . [3560s] threads: 1024, tps: 385.80, reads /s : 4949.60, writes /s : 1503.80, response time : 19827.73ms (99%) [3570s] threads: 1024, tps: 249.70, reads /s : 3679.90, writes /s : 1009.40, response time : 12016.58ms (99%) [3580s] threads: 1024, tps: 328.90, reads /s : 4511.40, writes /s : 1301.40, response time : 7419.06ms (99%) [3590s] threads: 1024, tps: 196.40, reads /s : 3058.90, writes /s : 815.30, response time : 12092.35ms (99%) [3600s] threads: 1024, tps: 386.60, reads /s : 5282.74, writes /s : 1537.78, response time : 13614.18ms (99%) OLTP test statistics: queries performed: read : 16913554 -- 读总数 write: 4832444 -- 写总数 other: 2416222 -- 其他操作总数(SELECT、INSERT、UPDATE、DELETE之外的操作,例如COMMIT等) total: 24162220 -- 全部总数 transactions: 1208111 (335.29 per sec.) -- 总事务数(每秒事务数) deadlocks: 0 (0.00 per sec.) -- 发生死锁总数 read /write requests: 21745998 (6035.29 per sec.) -- 读写总数(每秒读写次数) other operations: 2416222 (670.59 per sec.) -- 其他操作总数(每秒其他操作次数) General statistics: total time : 3603.1388s -- 总耗时 total number of events: 1208111 -- 共发生多少事务数 total time taken by event execution: 3688348.3797s -- 所有事务耗时相加(不考虑并行因素) response time : min: 28.41ms -- 最小耗时 avg: 3052.99ms -- 平均耗时 max: 48667.93ms -- 最长耗时 approx. 99 percentile: 12708.40ms -- 超过99%平均耗时 Threads fairness: events (avg /stddev ): 1179.7959 /29 .07 execution time (avg /stddev ): 3601.9027 /1 .01 |
所以,每秒事务数Tps达335.29,每秒查询数Qps达6035.29,平均延时3052.99ms.
看完解析,来看结果,下面是直接测主从环境的结果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
OLTP test statistics: queries performed: read : 19215238 write: 5490068 other: 2745034 total: 27450340 transactions: 1372517 (381.03 per sec.) deadlocks: 0 (0.00 per sec.) read /write requests: 24705306 (6858.48 per sec.) other operations: 2745034 (762.05 per sec.) General statistics: total time : 3602.1538s total number of events: 1372517 total time taken by event execution: 3688254.2686s response time : min: 18.33ms avg: 2687.22ms max: 55386.15ms approx. 99 percentile: 12444.89ms Threads fairness: events (avg /stddev ): 1340.3486 /33 .85 execution time (avg /stddev ): 3601.8108 /0 .44 |
每秒事务数Tps达381.03,每秒查询数Qps达6858.48,平均耗时2687.22ms,毕竟总数据量是6亿,还是应该要接受.
下面是通过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
|
OLTP test statistics: queries performed: read : 18078326 write: 5165236 other: 2582618 total: 25826180 transactions: 1291309 (358.40 per sec.) deadlocks: 0 (0.00 per sec.) read /write requests: 23243562 (6451.19 per sec.) other operations: 2582618 (716.80 per sec.) General statistics: total time : 3602.9883s total number of events: 1291309 total time taken by event execution: 3687715.5739s response time : min: 22.45ms avg: 2855.80ms max: 50326.08ms approx. 99 percentile: 13264.21ms Threads fairness: events (avg /stddev ): 1261.0439 /33 .56 execution time (avg /stddev ): 3601.2847 /0 .96 |
每秒事务数Tps达358.40,每秒查询数Qps达6451.19,平均耗时2855.80ms,同样是总数据量6亿.
从结果对比计算,使用mycat后,tps,qps,和耗时都损耗了6%-7%,在我个人看来还是可以接受,因为使用了mycat做代理层,可以很方便的管理后端数据库,任何切换都可以手动来秒切,使用上触发脚本后就是一个HA框架了.
题外说明
测试结果示例说明的例子,其实是加上了高可用keepalived的测试结果,每秒事务数Tps达335.29,每秒查询数Qps达6035.29,平均延时3052.99ms,总的来说算好,也还只是比纯mysql主从损耗10%范围内,可以接受,毕竟可用性高了很多,而且后续压力增大也可以随时增加mycat数量来填补.
功能多了,机器也要多了一些,需要特别说明的是,因为涉及网络数据包转发关系,keepalived和后端mycat不能在同一台服务器,所以就必须独立开来.
10.21.128.208:keepalived主
10.21.128.209:keepalived备
10.21.128.200:mycat1
10.21.128.201:mycat2
10.21.128.199:vip
简单说明拓扑关系:
需要多搭建一个mycat,不过这里就不细说了,直接复制一份配置到其他机器再启动就ok了.
然后搭建一套keepalived集群:
大多数情况下,大伙使用keepalived只做HA功能,而LVS功能则交给其他软件实现.但是实际上keepalived+ipvsadm既能实现HA功能,也能实现LVS功能,非常方便.
我们在10.21.128.208和10.21.128.209上安装keepalived和修改配置.
个人不想纠结功能和版本问题,而这些也是比较常态功能性的软件,绝大部分yum源都配备,所以直接用yum安装就很方便,有额外兴趣的可以慢慢编译
1
2
|
#安装需要的软件 yum install -y keepalived ipvsadm nc rsync telnet tcpdump wget |
安装很快,我们直接看配置,yum安装默认的配置文件在/etc/keepalived/
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
|
#修改配置文件,注意注释位置 ! Configuration File for keepalived #全局配置 global_defs { notification_email { root@localhost #定义收件人邮件地址 } notification_email_from root@localhost #定义发件人 smtp_server 127.0.0.1 #如果要使用第三方smtp服务器,在现实中几乎没有意义(需要验证的原因),设为本地就可以了 smtp_connect_timeout 30 #smtp超时时间 router_id LVS_HA_MYCAT1 #此服务器keepalived的ID,随便改,注意不同服务器不一样就行 } #vrrp配置(HA配置) vrrp_instance VI_1 { #定义虚拟路由,VI_1 为虚拟路由的标示符,自己定义名称 state MASTER #指定当前节点为主节点 备用节点上设置为BACKUP即可 interface eth0 #绑定虚拟IP的网络接口,注意内外网 virtual_router_id 19 #VRRP组名,两个节点的设置必须一样,以指明各个节点属于同一VRRP组,0-255随便你用,这个ID也是虚拟MAC最后一段的来源 priority 100 #初始优先级,取值1-254之间,主节点一定要最大,其他从节点则看情况减少 advert_int 1 #组播信息发送间隔,两个节点设置必须一样 authentication { #设置验证信息,两个节点必须一致 auth_type PASS auth_pass 199200 } virtual_ipaddress { 10.21.128.199 #指定VIP,两个节点设置必须一样,虚拟ip最好和真实ip在同一网段。 } } #负载均衡配置(LVS配置) virtual_server 10.21.128.199 8066 { #指定VIP和端口,vip就是上面设置那个 delay_loop 6 #延迟多少个周期再启动服务,做服务检测 lb_algo rr #负载均衡调度算法 lb_kind DR #负载均衡类型选择,可选DR|NAT|TUN,DR性能比较高 nat_mask 255.255.255.0 #vip的掩码 persistence_timeout 0 #会话保持时间,一定时间之内用户无响应则下一次用户请求时需重新路由,一般设为0,不需要. protocol TCP #使用的协议,一般就TCP real_server 10.21.128.200 8066 { #定义后端realserver的真实服务器属性,ip和端口 weight 1 #负载均衡权重,数值越大,就负担更多连接 MISC_CHECK { #定义心跳检测的方法,因为不是web,而且用tcp_check健康检测后面的mycat会报错,所以需要misc_check的方式做心跳检测 misc_path "/etc/keepalived/shell/check_mycat_status.sh 10.21.128.200 8066" #自定义心跳检测shell脚本的路径、检测的服务器ip、检测的端口。(引号必须要) misc_timeout 3 #脚本执行超时时间 } } real_server 10.21.128.201 8066 { #同上 weight 2 MISC_CHECK { misc_path "/etc/keepalived/shell/check_mycat_status.sh 10.21.128.201 8066" misc_timeout 3 } } real_server 10.21.128.156 8066 { #同上 weight 2 MISC_CHECK { misc_path "/etc/keepalived/shell/check_mycat_status.sh 10.21.128.156 8066" misc_timeout 3 } } } |
里面涉及一个检测心跳的脚本,如下所示:
1
2
3
4
5
6
7
8
9
10
11
12
|
cat /etc/keepalived/shell/check_mycat_status .sh #!/bin/bash result=`nc - v -z $1 $2` flag= "succeeded" if [[ $result =~ $flag ]] then exit 0 else ; exit 1 fi #记得要给该脚本赋予执行权限: chmod 755 check_mycat_status.sh |
意思很简单,就是通过nc命令检测真实服务器的mycat的端口通不通,如果不通的话,keepalived就把这个mycat剔除出集群.
然后,在后端真实服务器上需要做一个操作,绑定vip创建ipvs规则:
在10.21.128.200,10.21.128.201,10.21.128.156上创建并执行下面的脚本,
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
|
#创建规则脚本 vim /shell/realserver #!/bin/bash SNS_VIP=10.21.128.199 #/etc/rc.d/init.d/functions case "$1" in start) ifconfig lo:0 $SNS_VIP broadcast $SNS_VIP netmask 255.255.255.255 up sleep 5 /sbin/route add ${SNS_VIP} /32 dev lo:0 echo "1" > /proc/sys/net/ipv4/conf/lo/arp_ignore echo "2" > /proc/sys/net/ipv4/conf/lo/arp_announce echo "1" > /proc/sys/net/ipv4/conf/all/arp_ignore echo "2" > /proc/sys/net/ipv4/conf/all/arp_announce sysctl -p > /dev/null 2>&1 echo "RealServer Start OK" ;; stop) ifconfig lo:0 down /sbin/route del -net $SNS_VIP netmask 255.255.255.255 dev lo:0 echo "0" > /proc/sys/net/ipv4/conf/lo/arp_ignore echo "0" > /proc/sys/net/ipv4/conf/lo/arp_announce echo "0" > /proc/sys/net/ipv4/conf/all/arp_ignore echo "0" > /proc/sys/net/ipv4/conf/all/arp_announce echo "RealServer Stoped" ;; restart) /sbin/route del -net $SNS_VIP netmask 255.255.255.255 dev lo:0 /sbin/route add ${SNS_VIP} /32 dev lo:0 ;; *) echo "Usage: $0 {start|stop|restart}" exit 1 esac exit 0 #赋予执行权限 chmod 755 /shell/realserver #执行一下 /shell/realserver start #然后查看下网卡状态 ifconfig lo:0 lo:0 Link encap:Local Loopback inet addr:10.21.128.199 Mask:255.255.255.255 UP LOOPBACK RUNNING MTU:16436 Metric:1 |
需要注意,每次服务器重启都必须启动这个绑定,不然lvs就不生效了,例如把他放到/etc/rc.d/rc.local
1
|
echo "/shell/realserver start" >> /etc/rc .d /rc . local |
万事俱备,只欠东风,那就启动keepalived吧.
在10.21.128.208和10.21.128.209上执行
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
|
#因为是yum安装,所以有linux服务 /etc/init .d /keepalived start Starting keepalived: [ OK ] #看看vip,因为主是208,所以vip只会在208出现,除非208挂了 ip addr 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 qdisc noqueue state UNKNOWN link /loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1 /8 scope host lo inet6 ::1 /128 scope host valid_lft forever preferred_lft forever 2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link /ether 22:87:35:77:ef:38 brd ff:ff:ff:ff:ff:ff inet 10.21.128.208 /24 brd 10.21.128.255 scope global eth0 inet 10.21.128.199 /32 scope global eth0 #-------VIP在这 inet6 fe80::2087:35ff:fe77:ef38 /64 scope link valid_lft forever preferred_lft forever #然后看看当前LVS状态 ipvsadm -L IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.21.128.199:8066 rr -> 10.21.128.156:8066 Route 2 0 0 -> 10.21.128.200:8066 Route 1 0 0 -> 10.21.128.201:8066 Route 2 0 0 |
一切都正常,那么,我们可以压测了.
1
2
|
#和之前命令差不多,只是ip不一样 . /sysbench --mysql-host=10.21.128.199 --mysql-port=8066 --mysql-user=sysbench --mysql-password=sb123 -- test =tests /db/oltp .lua --oltp_tables_count=15 --oltp-table-size=40000000 --mysql-table-engine=innodb --num-threads=1024 --oltp- read -only=off --report-interval=10 --rand- type =uniform --max- time =3600 --max-requests=40000000 --percentile=99 run >> /home/logs/sysbench_oltpX_32_20171128-3 .log |
我们来看看lvs状态
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
#查看链接状态 ipvsadm -L IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Scheduler Flags -> RemoteAddress:Port Forward Weight ActiveConn InActConn TCP 10.21.128.199:8066 rr -> 10.21.128.156:8066 Route 2 341 340 -> 10.21.128.200:8066 Route 1 341 340 -> 10.21.128.201:8066 Route 2 342 340 #加上另一个参数 ipvsadm -L --stats IP Virtual Server version 1.2.1 (size=4096) Prot LocalAddress:Port Conns InPkts OutPkts InBytes OutBytes -> RemoteAddress:Port TCP 10.21.128.199:8066 2045 3658545 0 326481K 0 -> 10.21.128.156:8066 682 1131691 0 114278K 0 -> 10.21.128.200:8066 681 1266405 0 106344K 0 -> 10.21.128.201:8066 682 1260449 0 105858K 0 |
为什么会没有out?是不是很奇怪?因为我们负载均衡类型选择的是DR模式,这个模式的特点就是当客户端和真实服务器建立链接后,真实服务器会直接把数据发送给客户端,不再需要keepalived来中转,所以就没有out的流量了,也就是为什么说效率就更高的原因了.
然后来看看压测的结果如何?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
OLTP test statistics: queries performed: read : 17043978 write: 4869708 other: 2434854 total: 24348540 transactions: 1217427 (338.00 per sec.) deadlocks: 0 (0.00 per sec.) read /write requests: 21913686 (6084.05 per sec.) other operations: 2434854 (676.01 per sec.) General statistics: total time : 3601.8265s total number of events: 1217427 total time taken by event execution: 3687506.3802s response time : min: 30.17ms avg: 3028.93ms max: 75102.41ms approx. 99 percentile: 13757.56ms Threads fairness: events (avg /stddev ): 1188.8936 /33 .40 execution time (avg /stddev ): 3601.0804 /0 .40 |
每秒事务数Tps达338.00,每秒查询数Qps达6084.05,平均延时3028.93ms,和一开始相差无几,基本符合现实.
转自
mysql+mycat压力测试一例-ping_note-51CTO博客
http://blog.51cto.com/arthur376/2045596
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?