前段时间在搞MySQL的读负载均衡,最后在LVS和haproxy两个方案之间纠结。本来很倾向于haproxy,因为在我们的KVM虚机环境里LVS老是出一些稀奇古怪的问题(和物理机的设置有关),所以想尽量不用LVS。然而,性能测试的结果却让我对haproxy很失望。
环境
虚机的环境大致如下
CPU: 4 core ,2Ghz
OS:CentOS 6.3 64位
MySQL: MySQL 5.5 1主2从
haproxy:1.5.12
sysbench: 0.4.12
测试方法
CPU: 4 core ,2Ghz
OS:CentOS 6.3 64位
MySQL: MySQL 5.5 1主2从
haproxy:1.5.12
sysbench: 0.4.12
测试方法
MySQL 1主2从,haproxy/lvs 部署在其中一个从上,haproxy/lvs后端为2个从机,然后从另外的机器上用sysbench对haproxy/lvs压测。
sysbench跑的simple测试,500w数据,50并发。
测试结果(大概的tps值)
注1
)用一个客户端压测时,并不能将lvs的能力完全释放,用两个客户端就可以达到7w/s的tps,正好是单机的双倍。
那么问题来了,为什么用了haproxy后,tps反而只有单机的一半?
下面逐步增加sysbench的线程数观察CPU利用率的变化
这是单机sysbench压测时,mysql进程CPU占用率的情况。
因为是CPU敏感的测试,MySQL进程的CPU占用率和测出的tps基本成正比,tps数据就不列了。
这是通过haproxy压测时,mysql进程和haproxy进程CPU占用的情况
从上面这个表,可以看到几个结果
1)在qps压到很高时, haproxy本身占用的CPU也比较高
2)在上面的配置中不能将2个虚机的4*2个核压满。压满是400%*2,但实际只有174%+112%,而单机测试时可以将CPU占用率压到 383%,所以导致搞了2台虚机做负载均衡,性能反而不如一台虚机。
但是,参考这位网友的测试结果,在物理机上是可以把haproxy的单核CPU占用压到100%,达到6.5w/s的qps的。
http://www.cnblogs.com/lulu/archive/2013/07/24/3213363.html
所以,可能我们的虚拟环境下,haproxy这样的7层包转发的代理,qps就是上不去。
但是LVS的DR模式没有这个问题,性能的线性扩展很好,而且几乎不占CPU。据有经验的同事讲,LVS的转发吞吐量在虚机下可以达到17w/s,物理机上70w/s。
因此,如果没有7层包处理的硬性需求,负载又比较高的话,负载均衡应尽量用LVS DR。
参考
下面这篇文章列出了常用MySQL的负载均衡方案和配置方法,虽然是基于galera,但可以参考。
http://severalnines.com/blog/benchmark-load-balancers-mysqlmariadb-galera-cluster
不过它的测试结果有点令我惊讶。我用同样的方法在单机上测到tps是它单机结果的将近10倍,难道Gelera集群比普通MySQL复制相比性能损耗就有这么大。
为此,我查了下别人的测试结果,发现,galera在sync_binlog=0情况下,确实可能只有普通的单MySQL实例的十分之一慢10倍,sync_binlog=1时性能是普通的单MySQL实例的一半。
http://openlife.cc/blogs/2011/august/running-sysbench-tests-against-galera-cluster
另外,galera的lvs测试结果和从单节点上压测是一样的,这一点可以理解,它测试时跑的是写测试,不管从哪个节点执行,事务都要在每个galera节点上执行一次,
所以往多个节点写,不会比往单节点写的性能更好。这和上面链接里的测试结果也是吻合的。
sysbench跑的simple测试,500w数据,50并发。
测试结果(大概的tps值)
项目 | tps |
单机直连 |
3.5w/s |
haproxy(tcp模式) |
1.7w/s |
lvs(dr) | 4.5w/s |
lvs(dr)(两个客户端压测,注1) | 7w/s |
那么问题来了,为什么用了haproxy后,tps反而只有单机的一半?
下面逐步增加sysbench的线程数观察CPU利用率的变化
这是单机sysbench压测时,mysql进程CPU占用率的情况。
线程数 | mysql CPU占用率 |
1 | 36% |
2 | 67% |
4 | 100% |
8 | 191% |
16 | 340% |
32 | 383% |
这是通过haproxy压测时,mysql进程和haproxy进程CPU占用的情况
线程数 |
从机1 | 从机2 |
|||
mysqld | haproxy | ksoftirqd | mysqld | haproxy | |
1 | 34 | 15 | 13 | 0 | 0 |
2 | 34 | 22 | 29 | 25 | 0 |
4 | 70 | 38 | 30 | 45 | 40 |
8 | 120 | 55 | 0 | 73 | 12 |
16 | 134 | 40 | 0 | 102 | 10 |
32 | 127 | 32 | 0 | 115 | 6 |
1)在qps压到很高时, haproxy本身占用的CPU也比较高
2)在上面的配置中不能将2个虚机的4*2个核压满。压满是400%*2,但实际只有174%+112%,而单机测试时可以将CPU占用率压到 383%,所以导致搞了2台虚机做负载均衡,性能反而不如一台虚机。
但是,参考这位网友的测试结果,在物理机上是可以把haproxy的单核CPU占用压到100%,达到6.5w/s的qps的。
http://www.cnblogs.com/lulu/archive/2013/07/24/3213363.html
- 使用:redis-benchmark->Haproxy->redis 方式测试tcp转发,get请求
- 单进程:6.5w/s 100%CPU(相比twenproxy要快一些呢)
- 2进程: 12w/s 100%*2CPU
- 4进程: 15w/s 65%*4 CPU
所以,可能我们的虚拟环境下,haproxy这样的7层包转发的代理,qps就是上不去。
但是LVS的DR模式没有这个问题,性能的线性扩展很好,而且几乎不占CPU。据有经验的同事讲,LVS的转发吞吐量在虚机下可以达到17w/s,物理机上70w/s。
因此,如果没有7层包处理的硬性需求,负载又比较高的话,负载均衡应尽量用LVS DR。
参考
下面这篇文章列出了常用MySQL的负载均衡方案和配置方法,虽然是基于galera,但可以参考。
http://severalnines.com/blog/benchmark-load-balancers-mysqlmariadb-galera-cluster
不过它的测试结果有点令我惊讶。我用同样的方法在单机上测到tps是它单机结果的将近10倍,难道Gelera集群比普通MySQL复制相比性能损耗就有这么大。
为此,我查了下别人的测试结果,发现,galera在sync_binlog=0情况下,确实可能只有普通的单MySQL实例的十分之一慢10倍,sync_binlog=1时性能是普通的单MySQL实例的一半。
http://openlife.cc/blogs/2011/august/running-sysbench-tests-against-galera-cluster
另外,galera的lvs测试结果和从单节点上压测是一样的,这一点可以理解,它测试时跑的是写测试,不管从哪个节点执行,事务都要在每个galera节点上执行一次,
所以往多个节点写,不会比往单节点写的性能更好。这和上面链接里的测试结果也是吻合的。