欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Heartbeat、haproxy及MySQL双主复制实现读写负载均衡及高可用详细教程

程序员文章站 2022-06-30 08:33:36
目录 一、中间件简述 1. heartbeat简介 2. haproxy简介 二、安装配置 1. 基本环境 2. 配置mysql双主复制 3. 安装配置haproxy 4. 安装配置heartbea...

目录

一、中间件简述

1. heartbeat简介

2. haproxy简介

二、安装配置

1. 基本环境

2. 配置mysql双主复制

3. 安装配置haproxy

4. 安装配置heartbeat

5. 创建mysql服务检测脚本

三、功能测试

1. 验证haproxy的负载均衡轮询策略

2. 验证mysql的高可用性

3. 验证宕机重新上线后自动添加到haproxy中

4. 验证haproxy的高可用性

四、总结

本篇我们将做另一个实验,利用haproxy实现mysql双主复制的读写负载均衡与mysql的高可用,同时用heartbeat保证两台负载均衡器的高可用性。

一、中间件简述

1. heartbeat简介

一、heartbeat简介。

2. haproxy简介

haproxy是一个开源的高性能的反向代理或者说是负载均衡服务软件之一,它支持双机热备、虚拟主机、基于tcp和http应用代理等功能。其配置简单,而且拥有很好的对服务器节点的健康检查功能(相当于keepalived健康检查),当其代理的后端服务器出现故障时,haproxy会自动的将该故障服务器摘除,当服务器的故障恢复后haproxy还会自动重新添加回服务器主机。

haproxy实现了一种事件驱动、单一进程模型,此模型支持非常大的并发连接数。多进程或多线程模型受内存限制、调度器限制以及无处不在的锁限制,很少能处理数千并发连接。事件驱动模型因为在有更好的资源和时间管理的用户空间(user-space)实现所有这些任务,所以没有这些问题。此模型的弊端是,在多核系统上,这些程序通常扩展性较差。这就是为什么必须对其进行优化以使每个cpu时间片(cycle)做更多的工作。

haproxy特别适用于那些负载特大的web站点,这些站点通常又需要会话保持或七层处理。haproxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进当前架构中,同时可以保护web服务器不被暴露到网络上。

haproxy软件引入了frontend,backend的功能,frontend(acl规则匹配)可以根据任意http请求头做规则匹配,然后把请求定向到相关的backend(server pools等待前端把请求转过来的服务器组)。通过frontend和backend,我们可以很容易的实现haproxy的7层代理功能。

二、安装配置

1. 基本环境

os:centos linux release 7.2.1511 (core)
172.16.1.126:heartbeat + haproxy + mysql replication master
172.16.1.127:heartbeat + haproxy + mysql replication master
172.16.1.100:vip

整体架构图如图1所示。

Heartbeat、haproxy及MySQL双主复制实现读写负载均衡及高可用详细教程图1

2. 配置mysql双主复制

所谓mysql双主复制,就是两个mysql服务器都能读能写,数据记录通过二进制传达给对方从而保持数据的一致性。就本例简而言之,172.16.1.126到172.16.1.127的主从复制 + 172.16.1.127到172.16.1.126的主从复制 = 172.16.1.126、172.16.1.127的双主复制。双主复制的详细配置步骤可以参考这篇文章:https://www.cnblogs.com/phpstudy2015-6/p/6485819.html#_label7,这里从略。

与主从复制相比,双主复制需要注意以下三个参数的设置:

log_slave_updates:要设置为true,将复制事件写入本机binlog。一台服务器既做主库又做从库时此选项必须要开启。 auto_increment_offset和auto_increment_increment:为避免自增列冲突,需要设置这两个参数,例如在双主复制中,可以配置如下:

# mastera自增长id
auto_increment_offset = 1
auto_increment_increment = 2  #奇数id
# masterb自增加id
auto_increment_offset = 2
auto_increment_increment = 2  #偶数id

3. 安装配置haproxy

以下步骤用root用户在172.16.1.126、172.16.1.127两个主机上执行。

(1)从以下地址下载haproxy
https://www.haproxy.org/download/1.8/src/haproxy-1.8.12.tar.gz

(2)创建haproxy运行账户和组

groupadd haproxy #添加haproxy组
useradd -g haproxy haproxy -s /bin/false #创建账户haproxy并加入到haproxy组

(3)解压

tar zxvf haproxy-1.8.12.tar.gz
cd haproxy-1.8.12

(4)查看操作系统版本信息

[root@hdp3~/haproxy-1.8.12]#uname -r
3.10.0-327.el7.x86_64
[root@hdp3~/haproxy-1.8.12]#

(5)编译与安装

make target=linux3100 cpu=x86_64 prefix=/usr/local/haprpxy
make install prefix=/usr/local/haproxy

参数说明:

target:使用uname -r查看内核,如:2.6.18-371.el5,此时该参数就为linux26。kernel 等于2.6.28的用:target=linux2628,等等。 cpu:使用uname -r查看系统信息,如x86_64 gnu/linux,此时该参数就为x86_64。 prefix:指定haprpxy安装路径。

(6)设置haproxy

mkdir -p /usr/local/haproxy/conf #创建配置文件目录
mkdir -p /etc/haproxy #创建配置文件目录
touch /usr/local/haproxy/conf/haproxy.cfg #创建配置文件
ln -s /usr/local/haproxy/conf/haproxy.cfg /etc/haproxy/haproxy.cfg #添加配置文件软连接
cp -r /root/haproxy-1.8.12/examples/errorfiles /usr/local/haproxy/errorfiles #拷贝错误页面
ln -s /usr/local/haproxy/errorfiles /etc/haproxy/errorfiles #添加软连接
mkdir -p /usr/local/haproxy/log #创建日志文件目录
touch /usr/local/haproxy/log/haproxy.log #创建日志文件
ln -s /usr/local/haproxy/log/haproxy.log /var/log/haproxy.log #添加软连接
cp /root/haproxy-1.8.12/examples/haproxy.init /etc/rc.d/init.d/haproxy #拷贝开机启动文件
chmod +x /etc/rc.d/init.d/haproxy #添加脚本执行权限
chkconfig haproxy on #设置开机启动
ln -s /usr/local/haproxy/sbin/haproxy /usr/sbin #添加软连接

(7)配置haproxy.cfg参数
编辑/usr/local/haproxy/conf/haproxy.cfg,内容如下:

global
  log     127.0.0.1 local2       # 日志定义级别(err | warning | info | debug)
  chroot   /usr/local/haproxy      # 当前工作目录
  pidfile   /var/run/haproxy.pid     # 进程id
  maxconn   4000             # 最大连接数
  user    haproxy           # 运行改程序的用户
  group    haproxy
  daemon                  # 后台形式运行
  stats socket /usr/local/haproxy/stats

defaults
  mode          tcp      # haproxy运行模式(http | tcp | health)
  log           global     # 采用全局定义的日志
  option         dontlognull  # 不记录健康检查的日志信息
  option         redispatch   # serverid对应的服务器挂掉后,强制定向到其他健康的服务器
  retries         3       # 三次连接失败则服务器不用
  timeout http-request  10s
  timeout queue      1m
  timeout connect     10s      # 连接超时
  timeout client     1m       # 客户端超时
  timeout server     1m       # 服务器超时
  timeout http-keep-alive 10s
  timeout check      10s      # 心跳检测
  maxconn         600      # 最大连接数

listen stats                # 配置haproxy状态页(用来查看的页面)
  mode http
  bind :8888
  stats enable
  stats hide-version           # 隐藏haproxy版本号
  stats uri   /haproxyadminstats   # 一会用于打开状态页的uri
  stats realm  haproxy\ statistics   # 输入账户密码时的提示文字
  stats auth  admin:admin       # 用户名:密码

frontend main
  bind 0.0.0.0:6603
 # 使用6603端口。监听前端端口(表示任何ip访问6603端口都会将数据轮番转发到mysql服务器群组中)
  default_backend       mysql   # 后端服务器组名

backend mysql
  balance   roundrobin         # 使用轮询方式调度
  server mysql1 172.16.1.126:3306 check port 3306 maxconn 300
  server mysql2 172.16.1.127:3306 check port 3306 maxconn 300

(8)启动日志
编辑/etc/rsyslog.conf文件,去掉以下两行的注释,并在其后添加一行:

# provides tcp syslog reception
$modload imtcp          # 去掉注释
$inputtcpserverrun 514      # 去掉注释
local2.*  /var/log/haproxy.log # 添加此行

(9)启动haproxy

systemctl start haproxy
systemctl status haproxy -l
systemctl stop haproxy
systemctl restart haproxy

此时打开输入172.16.1.126:8888/haproxyadminstats,用admin/admin登陆后如图2所示,表明安装haproxy成功。

Heartbeat、haproxy及MySQL双主复制实现读写负载均衡及高可用详细教程图2

4. 安装配置heartbeat

heartbeat的源码编译安装需要依次安装cluster glue、resource agents和heartbeat 三个软件,并且三个软件要安装在相同目录下。详细安装配置步骤参考:https://blog.csdn.net/wzy0623/article/details/81188814#二、安装heartbeat。

这里需要注意的是haresources的设置。在上一篇中,我们建立了一个名为mysql的脚本,它调用remove_slave.sh。当heartbeat主机获得资源时,将自动把mysql主从复制中的slave置为master。这次我们用/usr/local/heartbeat/etc/ha.d/haresources来启动haproxy,文件内容只有如下一行:

hdp3 172.16.1.100 haproxy

而/usr/local/heartbeat/etc/ha.d/resource.d/haproxy文件中也只有如下一行:

/etc/init.d/haproxy restart

资源只有vip,我们用这种配置保证haproxy的高可用性。当初始启动heartbeat后,vip绑定在172.16.1.126上。

5. 创建mysql服务检测脚本

与上一篇的实验类似,这里保留自定义mysql_check脚本用于检查本机mysql的服务器状态。脚本内容与部署参见https://blog.csdn.net/wzy0623/article/details/81188814#4.%20创建mysql服务检测脚本。

三、功能测试

1. 验证haproxy的负载均衡轮询策略

用客户端连接vip,并多次执行mysql查询,可以看到查询请求依次被发送到在两个主机上执行。

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 126  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 127  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 126  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 127  |
+---------------+-------+

c:\windows\system32>

2. 验证mysql的高可用性

在172.16.1.126上杀掉mysql:

pkill -9 mysqld

用客户端连接vip,并多次执行mysql查询,可以看到查询请求都被发送到172.16.1.127。一台mysql宕机不影响应用的正常使用,保证了mysql服务的高可用性。

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 127  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 127  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 127  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"\
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 127  |
+---------------+-------+

c:\windows\system32>

3. 验证宕机重新上线后自动添加到haproxy中

在172.16.1.126再次启动mysql,并重启haproxy服务:

service mysql start
systemctl restart haproxy

用客户端连接vip,并多次执行mysql查询,可以看到查询请求依次被发送到在两个主机上执行。

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"\
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 127  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"\
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 126  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"\
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 127  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"\
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 126  |
+---------------+-------+

c:\windows\system32>

4. 验证haproxy的高可用性

初始vip在126,126的haproxy启动,127的haproxy停止。客户端访问:

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"\
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 127  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"\
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 126  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"\
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 127  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"\
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 126  |
+---------------+-------+

c:\windows\system32>

停止172.16.1.126上的mysql服务:

pkill -9 mysqld

mysql_check会检测到本机mysql服务宕机,触发停止heartbeat服务。vip漂移到172.16.1.127,同时172.16.1.127上的haproxy被拉起:

[root@hdp4~]#ip a
1: lo:  mtu 65536 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
   valid_lft forever preferred_lft forever
  inet6 ::1/128 scope host
   valid_lft forever preferred_lft forever
2: ens160:  mtu 1500 qdisc mq state up qlen 1000
  link/ether 00:50:56:a5:49:7f brd ff:ff:ff:ff:ff:ff
  inet 172.16.1.127/24 brd 172.16.1.255 scope global ens160
   valid_lft forever preferred_lft forever
  inet 172.16.1.100/24 brd 172.16.1.255 scope global secondary ens160:0
   valid_lft forever preferred_lft forever
  inet6 fe80::250:56ff:fea5:497f/64 scope link
   valid_lft forever preferred_lft forever
[root@hdp4~]#
[root@hdp4~]#
[root@hdp4~]#/etc/init.d/haproxy status
● haproxy.service - sysv: ha-proxy is a tcp/http reverse proxy which is particularly suited for high availability environments.
 loaded: loaded (/etc/rc.d/init.d/haproxy)
 active: active (running) since thu 2018-07-26 11:25:47 cst; 26s ago
  docs: man:systemd-sysv-generator(8)
 process: 532199 execstop=/etc/rc.d/init.d/haproxy stop (code=exited, status=0/success)
 process: 532205 execstart=/etc/rc.d/init.d/haproxy start (code=exited, status=0/success)
main pid: 532210 (haproxy)
 cgroup: /system.slice/haproxy.service
     └─532210 /usr/sbin/haproxy -d -f /etc/haproxy/haproxy.cfg -p /var/run/haproxy.pid

jul 26 11:25:47 hdp4 systemd[1]: starting sysv: ha-proxy is a tcp/http reverse proxy which is particularly suite...ts....
jul 26 11:25:47 hdp4 haproxy[532205]: starting haproxy: [ ok ]
jul 26 11:25:47 hdp4 systemd[1]: started sysv: ha-proxy is a tcp/http reverse proxy which is particularly suited...ents..
hint: some lines were ellipsized, use -l to show in full.
[root@hdp4~]#

客户端访问不受影响:

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"\
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 126  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"\
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 127  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"\
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 126  |
+---------------+-------+

c:\windows\system32>mysql -utest -p123456 -p6603 -h172.16.1.100 -e "show variables like 'server_id'"\
mysql: [warning] using a password on the command line interface can be insecure.
+---------------+-------+
| variable_name | value |
+---------------+-------+
| server_id   | 127  |
+---------------+-------+

c:\windows\system32>

在172.16.1.126上再次启动heartbeat,vip并不发生漂移,仍然停留在172.16.1.127上。

[root@hdp3~]#systemctl start heartbeat
[root@hdp3~]#
[root@hdp3~]#
[root@hdp3~]#ip a
1: lo:  mtu 65536 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
   valid_lft forever preferred_lft forever
  inet6 ::1/128 scope host
   valid_lft forever preferred_lft forever
2: ens32:  mtu 1500 qdisc pfifo_fast state up qlen 1000
  link/ether 00:50:56:a5:0f:77 brd ff:ff:ff:ff:ff:ff
  inet 172.16.1.126/24 brd 172.16.1.255 scope global ens32
   valid_lft forever preferred_lft forever
  inet6 fe80::250:56ff:fea5:f77/64 scope link
   valid_lft forever preferred_lft forever
[root@hdp3~]#

四、总结

之所以要使用mysql双主复制而不是主从复制,是因为本方案中并没有涉及读写分离,而是在两个等价的mysql服务器之间做读写负载均衡。 heartbeat利用实现了haproxy的ha,避免了haproxy的单点故障,出现故障时可以自动切换到正常的节点。 haproxy服务器提供了负载均衡的作用,将用户请求分发到多个backend。同时,一台mysql故障并不会影响整个集群,因为haproxy会检测backend的状态,并据此自动添加或删除集群中的mysql服务。 如本例的配置,需要考虑单台mysql服务器的负载最好不要超过50%,否则一旦某台mysql服务器故障,可能出现另一台正常mysql不堪重负的情况。 只采用本例的配置无法处理“脑裂”问题。例如,当心跳线闪断,slave获得vip,而此时master除了与slave失去联系,本身并无任何问题,也绑定同一vip。当心跳恢复正常时,就会出现vip的冲突等问题。脑裂是一个比较复杂的话题,通常需要引入其它插件,并且“多管齐下”才能彻底解决。