HAproxy+keepalived+mysql构建高可用数据库
1、概况
1.1 应用场景
Nginx/LVS/HAProxy的基于Linux的开源免费的负载均衡软件。对于大型的,需要进行高并发的网站或者对网络不太严格的场景,可以使用Nginx;对于大型的Web服务器的时候可以使用Haproxy;对性能有严格要求的时候可以使用LVS,就单纯从负载均衡的角度来说,LVS也许会成为主流,更适合现在大型的互联网公司。本文采用HAproxy+keepalived+mysql主从方案来解决业务架构高可用。
1.2 LVS/Nginx/HAProxy特点
LVS
1)抗负载能力强、是工作在网络4层之上仅作分发之用,没有流量的产生,这个特点也决定了它在负载均衡软件里的性能最强的;
2)配置性比较低,这是一个缺点也是一个优点,因为没有可太多配置的东西,所以并不需要太多接触,大大减少了人为出错的几率;
3)工作稳定,自身有完整的双机热备方案,如LVS+Keepalived和LVS+Heartbeat,不过我们在项目实施中用得最多的还是LVS/DR+Keepalived;
4)无流量,保证了均衡器IO的性能不会收到大流量的影响;
5)应用范围比较广,可以对所有应用做负载均衡;
6)软件本身不支持正则处理,不能做动静分离,这个就比较遗憾了;其实现在许多网站在这方面都有较强的需求,这个是Nginx/HAProxy+Keepalived的优势所在。
7)如果是网站应用比较庞大的话,实施LVS/DR+Keepalived起来就比较复杂了,特别后面有Windows Server应用的机器的话,如果实施及配置还有维护过程就比较复杂了。
Nginx
1)工作在网络的7层之上,可以针对http应用做一些分流的策略,比如针对域名、目录结构,它的正则规则比HAProxy更为强大和灵活,这也是许多朋友喜欢它的原因之一;
2)Nginx对网络的依赖非常小,理论上能ping通就就能进行负载功能,这个也是它的优势所在;
3)Nginx安装和配置比较简单,测试起来比较方便;
4)也可以承担高的负载压力且稳定,一般能支撑超过几万次的并发量;
5)Nginx可以通过端口检测到服务器内部的故障,比如根据服务器处理网页返回的状态码、超时等等,并且会把返回错误的请求重新提交到另一个节点,不过其中缺点就是不支持url来检测;
6)Nginx仅能支持http和Email,这样就在适用范围上面小很多,这个它的弱势;
7)Nginx不仅仅是一款优秀的负载均衡器/反向代理软件,它同时也是功能强大的Web应用服务器。LNMP现在也是非常流行的web架构,大有和以前最流行的LAMP架构分庭抗争之势,在高流量的环境中也有很好的效果。
8)Nginx现在作为Web反向加速缓存越来越成熟了,很多朋友都已在生产环境下投入生产了,而且反映效果不错,速度比传统的Squid服务器更快,有兴趣的朋友可以考虑用其作为反向代理加速器。
HAProxy
1)支持两种代理模式:TCP(四层)和HTTP(七层)HAProxy是支持虚拟主机的。
2)能够补充Nginx的一些缺点比如Session的保持,Cookie的引导等工作
3)支持url检测后端的服务器出问题的检测会有很好的帮助。
4)它跟LVS一样,本身仅仅就只是一款负载均衡软件;单纯从效率上来讲HAProxy更会比Nginx有更出色的负载均衡速度,在并发处理上也是优于Nginx的。
5)HAProxy可以对Mysql读进行负载均衡,对后端的MySQL节点进行检测和负载均衡,不过在后端的MySQL slaves数量超过10台时性能不如LVS。
6)HAProxy的算法现在也越来越多了,算法特别灵活
2、相关理论
2.1 Keepalived工作原理
keepalived:顾名思义是保持存活,常用来搭建设备的高可用,防止业务核心设备出现单点故障。keepalived基于VRRP协议来实现高可用,主要用作realserver的健康检查以及负载均衡主机和backup主机之间的故障漂移。如果将TCP/IP划分为5层,则Keepalived就是一个类似于3~5层交换机制的软件,具有3~5层交换功能,其主要作用是检测web服务器的状态,如果某台web服务器故障,Keepalived将检测到并将其从系统中剔除,当该web服务器工作正常后Keepalived自动将其加入到服务器群中,这些工作全部自动完成,而不需要人工干预,只需要人工修复故障的web服务器即可。
三层机理是发送ICMP数据包即PING给某台服务器,如果不通,则认为其故障,并从服务器群中剔除;四层机理是检测TCP端口号状态来判断某台服务器是否故障,如果检测端口存在异常,则从服务器群中剔除;五层机理是根据用户的设定检查某个服务器应用程序是否正常运行,如果不正常,则从服务器群中剔除。
2.2 HAproxy工作原理
Haproxy提供高可用性、负载均衡以及基于TCP和HTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案,反向代理服务器,支持双机热备支持虚拟主机,但其配置简单,拥有非常不错的服务器健康检查功能,当其代理的后端服务器出现故障, HAProxy会自动将该服务器摘除,故障恢复后再自动将该服务器加入。
3、架构拓扑
4、资源规划
主机名称IP操作系统
haproxy1192.168.74.126Centos7 64位
haproxy2192.168.74.127Centos7 64位
mysql1192.168.74.128Centos7 64位
mysql2192.168.74.129Centos7 64位
VIP192.168.74.150\
软/硬件选型
企业大数据系统在软/硬件选型方面将遵循两个原则:一是硬件上将遵循“同品牌、同型号、同配置”的原则,不因应用系统或分布式系统的不同而不同;二是软件上将遵偱“同操作系统、同JVM 虚拟机、同系统账户体系”的原则。
推荐硬件选型如表1-1 所示。
表1-1 推荐硬件选型列表
品牌:用户自定
设备名:节点机
配置:
CPU:2个4核,主频为2.4GHz以上
内存:16G
硬盘:500G
网卡:千兆
备注:数据中心的所有节点机器配置基本相同
每个节点的基础软件选型如表1-2所示。
表1-2 节点基础软件选型列表
操作系统:Centos7 64位
Mysql:mysql-5.7.X
HAproxy:haproxy-1.8.X
keepalived:keepalived-1.2.X
目录配置:统一自定安装目录,统一环境配置
应用服务器对只读的应用程序连接虚拟IP地址,连接到haproxy,然后通过haproxy将TCP协议转移到下面的2个MySQL主从数据库服务器中。Haproxy在此做4层的TCP交换服务。keepalived为了防止haproxy单点故障。这里可以使用两个VIP(虚拟IP)实现haproxy代理服务器的高可用负载均衡。
5、安装介质
CentOS操作系统版本:CentOS-7-x86_64-DVD-1511.iso
mysql版本:mysql-5.7.22-linux-glibc2.12-x86_64.tar
HAproxy版本:haproxy-1.8.14.tar.gz
keepalived版本:keepalived-1.2.7.tar.gz
6、准备工作(每台机器)
安装之前,如果之前安装过mysql,那么需要删除相应的各种mysql文件,删除之前请停止mysql服务。并且不要忘记删除my.cnf这些配置文件。确保删除干净。不然可能会和后面的安装有冲突。如果是实验,关闭防火墙,实际中,防火墙打开对应端口(注意实际中需要使用的端口不只有3306端口,还有同步需要使用的6677端口)。保证服务器之前能互相访问,能ping通。保证固定的ip地址。保证没有别的程序占用需要使用的端口。如3306等。这些都确认完毕后再进行安装。
6.1关闭防火墙
systemctl stopfirewalld.service
systemctl disablefirewalld.service
6.2挂载光盘(每台机器)
mount /dev/cdrom /mnt
删除原有的yum的源
cd /etc/yum.repos.d/
rm -rf *
创建自己的源vi my.repo
[centos-yum]
baseurl=file:///mnt
enabled=1
gpgcheck=0
6.3NTP服务需要每台机器进行安装(时间同步)
yum install ntp
systemctl is-enabledntpd
systemctl enable ntpd
systemctl start ntpd
7、安装mysql
以下的所有操作需要在所有的集群节点(128/129)都要进行相同的操作
7.1新增用户组mysql和用户msyql
groupadd mysql
useradd -g mysql -s/bin/false mysql
新建文件夹并赋予权限
mkdir /var/lib/mysql
chown root:mysql/var/lib/mysql
7.2将下载后的包上传至服务器/usr/local下
解压
cd /usr/local
tar xvf mysql-5.7.22-linux-glibc2.12-x86_64.tar
7.3创建链接方便访问
ln -s /usr/local/mysql-gpl-7.5.4-linux-glibc2.5-x86_64/usr/local/mysql
7.4初始化数据库(这里要注意,如果安装的版本不同,数据库初始化的命令可能不同的,很多之前的版本会使用:scripts/mysql_install_db --user=mysql来初始化,这个已经被mysql在新的版本中废弃了,所以需要使用下面的命令安装,如果需要安装别的版本请参考mysql官网的对应版本的安装命令。)
进入刚才创建的目录的bin目录下初始化,正常安装mysql如何初始化就如何进行安装就可以了,这里还可以设置安装数据库的data目录等参数。
cd /usr/local/mysql/bin
./mysqld --initialize--user=mysql --basedir=/usr/local/mysql --datadir=/usr/local/mysql/data
如果初始化成功之后,系统会提示一个随机生成的数据库密码,此时需要记住这个密码,之后登录数据库需要使用这个密码。
192.168.74.128 p.(V9O+2*etk #记录192.168.74.128的初始化密码
192.168.74.129 vKeCI;+4Igl? #记录192.168.74.129的初始化密码
7.5修改权限
chown -R root .
chown -R mysql data
chgrp -R mysql .
cpsupport-files/mysql.server /etc/rc.d/init.d/
chmod +x/etc/rc.d/init.d/mysql.server
chkconfig --addmysql.server
7.6配置主节点
vi /etc/my.cnf
[client]
port = 3306
socket =/tmp/mysql.sock
[mysqld]
basedir=/usr/local/mysql/
datadir=/usr/local/mysql/data
user=root
port=3306
socket=/tmp/mysql.sock
server-id=1
log-bin=mysql-bin
skip-name-resolve
7.7配置从节点
vi /etc/my.cnf
[client]
port = 3306
socket =/tmp/mysql.sock
[mysqld]
basedir=/usr/local/mysql/
datadir=/usr/local/mysql/data
user=root
port=3306
socket=/tmp/mysql.sock
server-id=2
log-bin=mysql-bin
skip-name-resolve
其中slave的server-id要设置比master大
/etc/init.d/mysql.serverstart
./mysql -uroot -p #登录mysql,密码粘贴上面记录的初始密码
setpassword=password('123456'); #修改密码
./mysql -uroot -p123456 #测试修改后的密码是否能够登录
7.8在Master服务器上创建MySQL用户(授权复制用户)
GRANT ALL PRIVILEGES ON*.* TO 'root'@'%' IDENTIFIED BY '123456' WITH GRANT OPTION;
查看master状态
show master status;
在slave添加master配置
命令:change master to
->master_host=' 192.168.74.128',
->master_user=' root',
->master_password='123456',
->master_log_file=' mysql-bin.000010', #show master status中File的值
->master_log_pos=154;
show master status中Position的值
7.9主从同步测试
命令:show slave status\G
当Slave_IO_Running和Slave_SQL_Running均为Yes时,表示同步成功。
8、搭建haproxy
8.1上传haproxy安装包到/usr/local
在74.126和74.127解压缩安装
tar -zxvfhaproxy-1.8.14.tar.tar
cd haproxy-1.8.14
yum install -y gcc
make TARGET=linux310
ARCH=x86_64 # uname -a查看主机信息填写
make installSBINDIR=/usr/sbin/ MANDIR=/usr/share/man/ DOCDIR=/usr/share/doc/
8.2提供启动脚本
vim /etc/init.d/haproxy
#
# haproxy
#
# chkconfig: - 85 15
# description: HAProxy is a free, very fast and reliablesolution \
# offering high availability, loadbalancing, and \
# proxying for TCP and HTTP-based applications
# processname: haproxy
# config: /etc/haproxy/haproxy.cfg
# pidfile: /var/run/haproxy.pid
#Sourcefunction library.
./etc/rc.d/init.d/functions
# Source networkingconfiguration.
. /etc/sysconfig/network
# Check that networkingis up.
["$NETWORKING" = "no" ] && exit 0
exec="/usr/sbin/haproxy"
prog=$(basename $exec)
[ -e/etc/sysconfig/$prog ] && . /etc/sysconfig/$prog
cfgfile=/etc/haproxy/haproxy.cfg
pidfile=/var/run/haproxy.pid
lockfile=/var/lock/subsys/haproxy
check() {
$exec -c -V -f $cfgfile $OPTIONS
}
start() {
$exec -c -q -f $cfgfile $OPTIONS
if [ $? -ne 0 ]; then
echo "Errors in configurationfile, check with $prog check."
return 1
fi
echo -n $"Starting $prog: "
# start it up here, usually something like"daemon $exec"
daemon $exec -D -f $cfgfile -p $pidfile$OPTIONS
retval=$?
echo
[ $retval -eq 0 ] && touch$lockfile
return $retval
}
stop() {
echo -n $"Stopping $prog: "
# stop it here, often "killproc$prog"
killproc $prog
retval=$?
echo
[ $retval -eq 0 ] && rm -f$lockfile
return $retval
}
restart() {
$exec -c -q -f $cfgfile $OPTIONS
if [ $? -ne 0 ]; then
echo "Errors in configuration file, check with $prog check."
return 1
fi
stop
start
}
reload() {
$exec -c -q -f $cfgfile $OPTIONS
if [ $? -ne 0 ]; then
echo "Errors in configurationfile, check with $prog check."
return 1
fi
echo -n $"Reloading $prog: "
$exec -D -f $cfgfile -p $pidfile $OPTIONS-sf $(cat $pidfile)
retval=$?
echo
return $retval
}
force_reload() {
restart
}
fdr_status() {
status$prog
}
case "$1" in
start|stop|restart|reload)
$1
;;
force-reload)
force_reload
;;
check)
check
;;
status)
fdr_status
;;
condrestart|try-restart)
[ ! -f $lockfile ] || restart
;;
*)
echo $"Usage: $0{start|stop|status|restart|try-restart|reload|force-reload}"
exit2
esac
8.3提供配置文件
mkdir /etc/haproxy
mkdir /var/lib/haproxy
useradd -r haproxy
vim/etc/haproxy/haproxy.cfg
global
log 127.0.0.1 local2
chroot /var/lib/haproxy
pidfile /var/run/haproxy.pid
maxconn 4000
user haproxy
group haproxy
daemon
defaults
mode tcp
log global
option dontlognull
option redispatch
retries 3
timeout http-request 10s
timeoutqueue 1m
timeout connect 10s
timeout client 1m
timeoutserver 1m
timeout http-keep-alive 10s
timeout check 10s
maxconn 600
listen stats
mode http
bind :6677
stats enable
stats hide-version
stats uri /haproxyadmin?stats
stats realm Haproxy\ Statistics
stats auth admin:admin
statsadmin if TRUE
frontend main
bind *:3306
default_backend mysql
backend mysql
balance leastconn
server m1 192.168.74.128:3306 check port3306 maxconn 300
server m2 192.168.74.129:3306 check port3306 maxconn 300
8.4修改日志系统
###Provides UDP syslog
reception //去掉下面两行注释,开启UDP监听
$ModLoad imudp
$UDPServerRun 514
local2.*
/var/log/haproxy.log //添加此行
service rsyslog restart
8.5启动测试haproxy
service haproxy start
chkconfig --add haproxy
chkconfig haproxy on
netstat -tnlp
mysql -P3306 -uroot
-p123456 -h192.168.74.129 # 查看
server_id,判断是否成功
9、搭建keepalived
9.1上传keepalived安装包到/usr/local
在74.126和74.127解压缩安装
tar xfkeepalived-1.2.7.tar.gz
cd keepalived-1.2.7
./configure --prefix=/usr/local/keepalived--sbindir=/usr/sbin/ --sysconfdir=/etc/ --mandir=/usr/local/share/man/
make && makeinstall
chkconfig --addkeepalived
chkconfig keepalived on
可能会报错1
!!! OpenSSL isnot properly installed on your system. !!!
!!! Can notinclude OpenSSL headers files.
解决方法:
yum -y installopenssl-devel
可能会报错2
configure: error: Poptlibraries isrequired
解决方法:
yum install
popt-devel
9.2提供配置文件
vim
/etc/keepalived/keepalived.conf # 两个机器配置文件不同
! Configuration Filefor keepalived
global_defs {
notification_email{ #忽略
acassen@firewall.loc
failover@firewall.loc
sysadmin@firewall.loc
}
notification_email_fromAlexandre.Cassen@firewall.loc
smtp_server 192.168.200.1
smtp_connect_timeout 30
router_id LVS_DEVEL
}
vrrp_script chk_haproxy{
script"/etc/keepalived/chk.sh" #检查haproxy的脚本
interval 2 #每两秒检查一次
}
vrrp_instance VI_1 {
stateBACKUP #定义为BACKUP节点
nopreempt #开启不抢占,另一个不写
interface ens33
virtual_router_id 51
priority 100 #开启了不抢占,所以此处优先级必须高于另一台,另一个写99
advert_int 1
authentication {
auth_type PASS
auth_pass abcd
}
virtual_ipaddress {
192.168.74.150 #配置VIP
}
track_script {
chk_haproxy #调用检查脚本
}
notify_backup "/etc/init.d/haproxyrestart"
notify_fault "/etc/init.d/haproxystop"
}
9.3创建check文件
vim/etc/keepalived/chk.sh
#!/bin/bash
if [ $(ps -C haproxy--no-header | wc -l) -eq 0 ]; then
/etc/init.d/keepalived stop
fi
chmod +x/etc/keepalived/chk.sh
service keepalivedstart
10、测试
ip addr # 查看是否绑定了虚ip
tcpdump-nn -i ens33 vrrp #抓包查看
http://192.168.74.128:6677/haproxyadmin?stats
# 通过haproxy查看状态
10.1测试无误后,重启MySQL、Haproxy、Keepalived,顺序依次为MySQL、Haproxy、Keepalived
/etc/init.d/mysql.serverstart
service haproxy start
service keepalivedstart
10.2测试mysql数据同步
通过对数据库进行增删改查操作,这里就不演示了
10.3测试mysql高可用
/etc/init.d/mysql.serverstop 停止服务测试效果,VIP是否还能够连上数据库
mysql -uroot -p123456-h192.168.74.150
10.4测试haproxyl高可用
service haproxy stop 停止服务测试效果
http://192.168.74.126:6677/haproxyadmin?stats是否还能够访问
mysql -uroot -p123456-h192.168.74.150
10.5测试mysql高可用
service keepalived stop 停止服务测试效果
ip addr 查看VIP
mysql -uroot -p123456
-h192.168.74.150 连接数据库