如何使用HAProxy设置MySQL负载平衡

来自菜鸟教程
跳转至:导航、​搜索

序幕


HAProxy 是一个开源软件,可以对 HTTP 和 TCP 服务器进行负载平衡。 在 上一篇关于 HAProxy 的文章中,我们为 HTTP 配置了负载平衡,在这篇文章中,我们将为 MySQL 做同样的事情。 您的所有 MySQL 服务器都必须配置为执行 Master-Master 复制,因为负载平衡涉及对所有后端的读取和写入。

本文将使用以下三个液滴:

Droplet 1 - 负载均衡器 主机名:haproxy 操作系统:Ubuntu 私有 IP:10.0.0.100

Droplet 2 - 节点 1 主机名:mysql-1 操作系统:Debian 7 私有 IP:10.0.0.1

Droplet 2 - 节点 2 主机名:mysql-2 操作系统:Debian 7 私有 IP:10.0.0.2

在继续之前,请确保所有 MySQL 服务器都已启动、运行并且正在正确复制数据库写入。

准备 MySQL 服务器


我们需要通过为 HAProxy 创建两个额外的用户来准备 MySQL 服务器。 HAProxy 将使用第一个用户来检查服务器的状态。

root@mysql-1# mysql -u root -p -e "INSERT INTO mysql.user (Host,User) values ('10.0.0.100','haproxy_check'); FLUSH PRIVILEGES;"

从 HAProxy 访问 MySQL 集群时,需要具有 root 权限的 MySQL 用户。 所有服务器上的默认 root 用户只允许在本地登录。 虽然可以通过向 root 用户授予额外权限来解决此问题,但最好有一个具有 root 权限的单独用户。

root@mysql-1# mysql -u root -p -e "GRANT ALL PRIVILEGES ON *.* TO 'haproxy_root'@'10.0.0.100' IDENTIFIED BY 'password' WITH GRANT OPTION; FLUSH PRIVILEGES"

haproxy_rootpassword 替换为您自己的安全值。 在一个 MySQL 主服务器上执行这些查询就足够了,因为更改会复制到其他服务器。

安装 MySQL 客户端


MySQL 客户端必须安装在 HAProxy droplet 上以测试连接性。

root@haproxy# apt-get install mysql-client

现在尝试以 haproxy_root 用户身份在其中一个主服务器上执行查询。

root@haproxy# mysql -h 10.0.0.1 -u haproxy_root -p -e "SHOW DATABASES"

这应该显示 MySQL 数据库的列表。

安装 HAProxy


在 HAProxy 服务器上安装包。

root@haproxy# apt-get install haproxy

启用由初始化脚本启动的 HAProxy。

root@haproxy# sed -i "s/ENABLED=0/ENABLED=1/" /etc/default/haproxy

要检查此更改是否正确执行,请执行不带任何参数的 HAProxy 的初始化脚本。

root@haproxy:~# service haproxy
Usage: /etc/init.d/haproxy {start|stop|reload|restart|status}

配置 HAProxy


重命名原配置文件

mv /etc/haproxy/haproxy.cfg{,.original}

创建和编辑一个新的

nano /etc/haproxy/haproxy.cfg

第一个块是全局和默认配置块。

global
    log 127.0.0.1 local0 notice
    user haproxy
    group haproxy

defaults
    log global
    retries 2
    timeout connect 3000
    timeout server 5000
    timeout client 5000

这篇文章 中介绍了有关每个选项的更多信息。 由于我们已经告诉 HAProxy 向 127.0.0.1 发送日志消息,我们必须配置 rsyslog 来监听它。 这也已在 同一篇文章 下的 为 HAProxy 配置日志记录中进行了介绍。

转到主要配置部分。

listen mysql-cluster
    bind 127.0.0.1:3306
    mode tcp
    option mysql-check user haproxy_check
    balance roundrobin
    server mysql-1 10.0.0.1:3306 check
    server mysql-2 10.0.0.2:3306 check

与 HTTP 负载平衡不同,HAProxy 没有针对 MySQL 的特定“模式”,因此我们使用 tcp。 我们已将 HAProxy 设置为仅侦听环回地址(假设应用程序位于同一服务器上),但是如果您的应用程序驻留在不同的 droplet 上,请使其侦听 0.0.0.0 或私有 IP 地址。

我们还需要一个配置块来查看负载均衡的统计信息。 这是完全可选的,如果您不想要统计信息,可以将其省略。

listen 0.0.0.0:8080
    mode http
    stats enable
    stats uri /
    stats realm Strictly\ Private
    stats auth A_Username:YourPassword
    stats auth Another_User:passwd

替换“stats auth”中的用户名和密码。 这将使 HAProxy 在 端口 8080 上侦听 HTTP 请求,并且统计信息将受到 HTTP 基本身份验证的保护。 因此,您可以访问统计信息

http://<Public IP of Load Balancer>:8080/

完成配置后,启动 HAProxy 服务。

service haproxy start

使用 mysql 客户端查询 HAProxy。

root@haproxy# mysql -h 127.0.0.1 -u haproxy_root -p -e "SHOW DATABASES"

“-h”选项必须与环回 IP 地址一起出现。 省略它或使用 localhost 将使 MySQL 客户端连接到将失败的 mysql.sock 文件。

测试负载平衡和故障转移


要检查负载平衡是否有效,请查询 server_id 变量两次或更多次。

root@haproxy# mysql -h 127.0.0.1 -u haproxy_root -p -e "show variables like 'server_id'"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 1     |
+---------------+-------+
root@haproxy# mysql -h 127.0.0.1 -u haproxy_root -p -e "show variables like 'server_id'"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+

这演示了具有相同权重的 roundrobin 负载平衡,我们现在将更改 mysql-2 的权重并查看结果。

nano /etc/haproxy/haproxy.cfg

server mysql-2 10.0.0.2:3306 check weight 2

重新加载以应用此更改。

service haproxy reload

多次查询 server_id

root@haproxy:~# for i in `seq 1 6`
do
mysql -h 127.0.0.1 -u haproxy_root -ppassword -e "show variables like 'server_id'"
done

+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 1     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 1     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| server_id     | 2     |
+---------------+-------+

现在负载均衡以 1:2 的比例工作,三分之一的请求发往 mysql-1,三分之二的请求发往 mysql-2。

通过停止服务使 MySQL 服务器失败

root@mysql-1# service mysql stop

或关闭接口。

root@mysql-1# ifconfig eth1 down

现在尝试“显示变量”查询以查看结果。 以下日志条目将指示 HAProxy 何时以及如何检测到故障。

tail /var/log/haproxy/haproxy.log

Nov 15 00:08:51 localhost haproxy[1671]: Server mysql-cluster/mysql-1 is DOWN, reason: Layer4 timeout, check duration: 2002ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.

减少故障转移间隔


当 MySQL 服务器出现故障时,HAProxy 需要一些时间来检测此故障并将其从集群中删除。 在本节中,我们将看到如何控制这个时间。 首先,我们将了解如何衡量这个值。 一种方法是使用 iptables 阻塞 MySQL 端口一段时间,然后删除规则并检查日志。

root@mysql-1:~# ifconfig eth1 down &&
date &&
sleep 20 &&
ifconfig eth1 up &&
date

Fri Nov 15 00:37:09 IST 2013
Fri Nov 15 00:37:29 IST 2013

端口 3306 被 阻塞 20 秒,现在我们将查看日志文件。

root@haproxy:~# tail /var/log/haproxy.log
Nov 15 16:49:38 localhost haproxy[1275]: Server mysql-cluster/mysql-1 is DOWN, reason: Layer4 connection problem, info: "Connection refused", check duration: 0ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
Nov 15 16:49:56 localhost haproxy[1275]: Server mysql-cluster/mysql-1 is UP, reason: Layer7 check passed, code: 0, info: "5.5.31-0+wheezy1-log", check duration: 1ms. 2 active and 0 backup servers online. 0 sessions requeued, 0 total in queue.

检测失败需要 6 秒(16:49:38 和 16:49:32 之间的差异),检测可以访问服务器需要 4 秒(16:49:56 和 16:49:52 之间的差异)。 这是由服务器参数上升、下降和区间决定的。

rise 参数设置服务器必须通过的检查次数才能声明为 operational。 默认值为 2。

fall 参数设置服务器必须通过的检查次数才能声明为 dead。 默认值为 3。

inter 参数设置这些检查之间的间隔。 默认值为 2000 毫秒。

将这些信息放在一起,服务器必须无法通过 3 连续检查,这些检查以 2 秒 的间隔执行,才会被视为死亡。 因此,在我们上面的示例中,将会发生以下情况。

16:49:32 - Port 3306 on mysql-1 was blocked
16:49:34 - Check - Failed - Failure No. 1
16:49:36 - Check - Failed - Failure No. 2
16:49:38 - Check - Failed - Failure No. 3 (server removed and event logged)

并且当防火墙规则被删除时。

16:49:52 - Firewall rule removed port 3306 accessible
16:49:54 - Check - Passed - Success No. 1
16:49:56 - Check - Passed - Success No. 2 (server added to cluster and event logged)

以下设置会将测试间隔减少到 1 秒,同时也会减少跌倒测试的次数。

nano /etc/haproxy/haproxy.cfg

server mysql-1 10.0.0.1:3306 check fall 2 inter 1000
server mysql-2 10.0.0.2:3306 check fall 2 inter 1000

有时你可能不想用太多的“测试”数据包淹没私有网络,特别是如果你有大量的MySQL服务器。 在这种情况下,fastinter 和 downinter 参数会派上用场。

fastinter 参数设置服务器向上或向下转换时检查之间的间隔。

downinter 参数设置服务器关闭时的测试间隔。

这种解释可能会令人困惑,因此我们将通过一个示例来了解它。

nano /etc/haproxy/haproxy.cfg

server mysql-1 10.0.0.1:3306 check fastinter 1000
server mysql-2 10.0.0.2:3306 check fastinter 1000

由于我们没有指定“inter”参数,它默认为 2000ms。 使用此配置,我们将重新启动 HAProxy 并再次进行测试。

root@mysql-1:~# iptables -A INPUT -p tcp --dport 3306 -j REJECT &&
date &&
sleep 20 &&
iptables -D INPUT -p tcp --dport 3306 -j REJECT &&
date
Fri Nov 15 17:18:48 IST 2013
Fri Nov 15 17:19:08 IST 2013

检查 HAProxy 日志文件。

root@haproxy:~# tail /var/log/haproxy.log
Nov 15 17:18:52 localhost haproxy[1353]: Server mysql-cluster/mysql-1 is DOWN, reason: Layer4 connection problem, info: "Connection refused", check duration: 0ms. 1 active and 0 backup servers left. 0 sessions active, 0 requeued, 0 remaining in queue.
Nov 15 17:19:11 localhost haproxy[1353]: Server mysql-cluster/mysql-1 is UP, reason: Layer7 check passed, code: 0, info: "5.5.31-0+wheezy1-log", check duration: 1ms. 2 active and 0 backup servers online. 0 sessions requeued, 0 total in queue.

现在只需要 4 秒(与之前的 6 秒相比)即可检测到故障,并且只需 3 秒(与 4 秒相比)即可检测到服务器已启动。 这就是幕后发生的事情。

17:18:48 - Port 3306 blocked
17:18:50 - Check - Failed - Failure No. 1
17:18:51 - Check - Failed - Failure No. 2
17:18:52 - Check - Failed - Failure No. 3 (server removed and event logged)

当端口畅通时。

17:19:08 - Firewall rule removed
17:19:10 - Check - Passed - Success No. 1
17:19:11 - Check - Passed - Success No. 2 (server added to cluster and event logged)

首先注意端口阻塞事件(17:18:48)和第一次检查(17:18:50)之间的间隔,它是2秒(“inter”间隔)。 然后注意测试 1 <-> 测试 2 和测试 2 <-> 测试 3 之间的间隔,它只有 1 秒(“fastinter”间隔)。 当服务器从 DOWN 移动到 UP 时,可以注意到相同的时间间隔。 所以“fastinter”控制这些检查之间的间隔。

那么什么是downinter? 当服务器被声明为 DOWN 时,HAProxy 会继续每 2 秒检查一次(或中间提到的间隔)。 如果你觉得你正在使用不必要的网络资源,将 downinter 设置为 5000 将使 HAProxy 在 5 秒内仅检查一次 DOWN 服务器。

重要的


我们之前所做的测试拒绝了数据包,这意味着当 HAProxy 通过向 mysql-1 发送 SYN 数据包来启动连接时,它收到了一个 RST 数据包(而不是 SYN + ACK)。 这就是日志条目提到“连接被拒绝”的原因。 在这种情况下,只有 fall、inter 和 fastinter 值进入场景。

相反,如果 HAProxy 在发送 SYN 后没有收到任何内容,则连接超时。 在这种情况下,除了上述参数之外,“超时”持续时间也会出现。 如果发生这种情况

  • iptables 设置为 DROP
  • 私有接口已关闭
  • 专用网络基础设施存在问题

延伸阅读


官方文档【X23X】http://cbonte.github.io/haproxy-dconv/configuration-1.4.html【X87X】

提交者:http: [[“%3Ca|//jesin.tk/]] [[“%3C/a|”>杰辛A]]