vlambda博客
学习文章列表

如何利用HAProxy 代理 MySQL Master-Slave Replication

0x00 背景


我有一个MySQL Master-Slave Replication, 想要通过HAProxy代理, 做读写分离.


写流量给到Master 节点, 读流量给到Slave 节点.


首先我应该有一个HAProxy的配置, 我想应该这样写(伪配置):


listen mysqlbind *:3316mode tcp...server 192.168.1.111 192.168.1.111:3306 checkserver 192.168.1.112 192.168.1.112:3306 checkserver 192.168.1.113 192.168.1.113:3306 check




很明显, 这么写仅仅只实现了流量的分发, 但并不能实现我的需求: 把写流量给Master, 读流量给Slave 节点.


那么问题来了,首先我要能够识别Master Slave 节点, 才能有接下来的流量分离.


HAProxy有个配置项叫做 mysql-check.

但是这里并不能用它去做Master-Slave的检测,因为这个option只提供存活检测.

只要能够连上,就代表这个mysql后端是Health OK的.


这还是不符合我的需求.


MySQL 如果能够通过tcp-check 检测是Master还是Slave就好了.


既然这样, 写一个TCP-check Wrapper 不就可以了?



0X01 TCP-Check-Wrapper

这个Wrapper应该监听在TCP端口上,并以守护进程的方式运行.

当HAproxy连接至其监听的端口时, 会执行相应的脚本, 并将脚本执行结果通过 TCP 连接发送至Haproxy.


代码如下:

- [TCP-Check-Wrapper](https://github.com/ooneko/haproxy_tcp_check_wrapper)

-  [mysqlchk](https://github.com/ashraf-s9s/mysqlchk)



放置好mysqlchk 脚本, 然后在每个MySQL节点上把tcp-check-wrapper服务跑起来.


在Master节点上测试一下脚本

[root@control-01 ~]# mysqlchk.mysqlHTTP/1.1 200 OKContent-Type: text/htmlContent-Length: 43

<html><body>MySQL master is running.</body></html>



在Slave节点上测试一下

[root@control-02 ~]# mysqlchk.mysqlHTTP/1.1 200 OKContent-Type: text/htmlContent-Length: 43

<html><body>MySQL slave is running. (Slave lag: 0)</body></html>



OK, 通过 mysql check 脚本已经可以帮助我们区分Master还是Slave了.


然后配置好tcp-check-wrapper.

# /etc/haproxy-tcp-check-wrapper
host = "0.0.0.0"
port = 9090script = "/usr/bin/mysqlchk.mysql"



在每个MySQL节点上, 运行 tcp-check-wrapper.

haproxy_tcp_check &



0x02 HAProxy的配置


基于我们前面所做的, 现在可以写出HAProxy的配置文件了.


listen mysql_writebind *:3316mode tcptimeout client 10800stimeout server 10800sbalance leastconnoption tcp-checktcp-check expect string MySQL\ master\ is\ running.option allbackupsdefault-server port 9090 inter 2s downinter 5s rise 3 fall 2 slowstart 60s maxconn 64 maxqueue 128 weight 100server 192.168.1.111 192.168.1.111:3306 checkserver 192.168.1.112 192.168.1.112:3306 checkserver 192.168.1.113 192.168.1.113:3306 check

listen mysql_readbind *:3317mode tcptimeout client 10800stimeout server 10800sbalance leastconnoption tcp-checktcp-check expect string MySQL\ slave\ is\ running.option allbackupsdefault-server port 9090 inter 2s downinter 5s rise 3 fall 2 slowstart 60s maxconn 64 maxqueue 128 weight 100server 192.168.1.111 192.168.1.111:3306 checkserver 192.168.1.112 192.168.1.112:3306 checkserver 192.168.1.113 192.168.1.113:3306 check


0x03 总结

至此, 我们已经通过HAProxy, 借助了 "TCP-Check-Wrapper" + "mysqlchk", 实现了MySQL Master-Slave Replication 的读写分离,


TCP-Check-Wrapper 帮助我们对一些不能使用tcp-check option 的应用执行检查.

mysqlchk 提供了具体检测的方法.


其实再多想一点, 可以再进一步利用MHA + HAPRoxy, 可以实现 MySQL Master-Slave Replication 高可用.

即: 在Master发生故障时, MHA可以将其中一台 MySQL Slave提升为Master, 并且配置其他的Slave指向新的Master.