Keepalived+HAProxy实现MySQL高可用负载均衡的配置
Keepalived
由于在生产环境使用了mysqlcluster,需要实现高可用负载均衡,这里提供了keepalived+haproxy来实现.
keepalived主要功能是实现真实机器的故障隔离及负载均衡器间的失败切换.可在第3,4,5层交换.它通过VRRPv2(Virtual Router Redundancy Protocol) stack实现的.
Layer3:Keepalived会定期向服务器群中的服务器.发送一个ICMP的数据包(既我们平时用的Ping程序),如果发现某台服务的IP地址没有激活,Keepalived便报告这台服务器失效,并将它从服务器群中剔除,这种情况的典型例子是某台服务器被非法关机。Layer3的方式是以服务器的IP地址是否有效作为服务器工作正常与否的标准。
Layer4:主要以TCP端口的状态来决定服务器工作正常与否。如web server的服务端口一般是80,如果Keepalived检测到80端口没有启动,则Keepalived将把这台服务器从服务器群中剔除。
Layer5:在网络上占用的带宽也要大一些。Keepalived将根据用户的设定检查服务器程序的运行是否正常,如果与用户的设定不相符,则Keepalived将把服务器从服务器群中剔除。
Software Design
keepalived启动后会有单个进程
8352 ? Ss 0:00 /usr/sbin/keepalived 8353 ? S 0:00 \_ /usr/sbin/keepalived 8356 ? S 0:01 \_ /usr/sbin/keepalived
父进程:内存管理,子进程管理等等
子进程:VRRP子进程
子进程:Healthchecking 子进程
实例
2台mysqlcluster 10.1.6.203 master 10.1.6.205 backup
vip 10.1.6.173
目的访问10.1.6.173 3366端口 分别轮询通过haproxy转发到10.1.6.203 3306 和10.1.6.205 3306
mysqlcluster搭建参照之前博客,这里在2台机上安装keepalived
root@10.1.6.203:~# apt-get install keepalived root@10.1.6.203:~# cat /etc/keepalived/keepalived.conf vrrp_script chk_haproxy { script "killall -0 haproxy" # verify the pid existance interval 2 # check every 2 seconds weight -2 # add 2 points of prio if OK } vrrp_instance VI_1 { interface eth1 # interface to monitor state MASTER virtual_router_id 51 # Assign one ID for this route priority 101 # 101 on master, 100 on backup nopreempt debug virtual_ipaddress { 10.1.6.173 } track_script { #注意大括号空格 chk_haproxy } notify_master /etc/keepalived/scripts/start_haproxy.sh #表示当切换到master状态时,要执行的脚本 notify_fault /etc/keepalived/scripts/stop_keepalived.sh #故障时执行的脚本 notify_stop /etc/keepalived/scripts/stop_haproxy.sh #keepalived停止运行前运行notify_stop指定的脚本 }
VRRPD配置包括三个类:
- VRRP同步组(synchroization group)
- VRRP实例(VRRP Instance)
- VRRP脚本
这里使用了 VRRP实例, VRRP脚本
注意配置选项:
stat:指定instance(Initial)的初始状态,就是说在配置好后,这台服务器的初始状态就是这里指定的,但这里指定的不算,还是得要通过竞选通过优先级来确定,里如果这里设置为master,但如若他的优先级不及另外一台,那么这台在发送通告时,会发送自己的优先级,另外一台发现优先级不如自己的高,那么他会就回抢占为master
- interface:实例绑定的网卡,因为在配置虚拟IP的时候必须是在已有的网卡上添加的
- priority 101:设置本节点的优先级,优先级高的为master
- debug:debug级别
- nopreempt:设置为不抢占
vrrp_script chk_haproxy { script "killall -0 haproxy" # verify the pid existance interval 2 # check every 2 seconds 脚本执行间隔 weight -2 # add 2 points of prio if OK 脚本结果导致的优先级变更:2表示优先级+2;-2则表示优先级-2 }
然后在实例(vrrp_instance)里面引用,有点类似脚本里面的函数引用一样:先定义,后引用函数名
track_script { chk_haproxy }
注意:VRRP脚本(vrrp_script)和VRRP实例(vrrp_instance)属于同一个级别
root@10.1.6.203:scripts# cat start_haproxy.sh #!/bin/bash sleep 5 get=`ip addr |grep 10.1.6.173 |wc -l` echo $get >> /etc/keepalived/scripts/start_ha.log if [ $get -eq 1 ] then echo "`date +%c` success to get vip" >> /etc/keepalived/scripts/start_ha.log /usr/local/sbin/haproxy -f /etc/haproxy/haproxy.cfg else echo "`date +%c` can not get vip" >> /etc/keepalived/scripts/start_ha.log fi root@10.1.6.203:scripts# cat stop_keepalived.sh #!/bin/bash pid=`pidof keepalived` if [ $pid == "" ] then echo "`date +%c` no keepalived process id" >> /etc/keepalived/scripts/stop_keep.log else echo "`date +%c` will stop keepalived " >> /etc/keepalived/scripts/stop_keep.log /etc/init.d/keepalived stop fi /etc/init.d/keepalived stop root@10.1.6.203:scripts# cat stop_haproxy.sh #!/bin/bash pid=`pidof haproxy` echo "`date +%c` stop haproxy" >> /etc/keepalived/scripts/stop_ha.log kill -9 $pid
同理配置10.1.6.205
root@10.1.6.205:~# cat /etc/keepalived/keepalived.conf vrrp_script chk_haproxy { script "killall -0 haproxy" # verify the pid existance interval 2 # check every 2 seconds weight 2 # add 2 points of prio if OK } vrrp_instance VI_1 { interface eth1 # interface to monitor state BACKUP virtual_router_id 51 # Assign one ID for this route priority 100 # 101 on master, 100 on backup virtual_ipaddress { 10.1.6.173 } track_script { chk_haproxy } notify_master /etc/keepalived/scripts/start_haproxy.sh notify_fault /etc/keepalived/scripts/stop_keepalived.sh notify_stop /etc/keepalived/scripts/stop_haproxy.sh }
HAProxy
下面再介绍下haproxy
HAProxy是一款基于TCP(第四层)和HTTP(第七层)应用的代理软件,它也可作为负载均衡器.可以支持数以万计的并发连接.同时可以保护服务器不暴露到网络上,通过端口映射.它还自带监控服务器状态的页面.
安装haproxy
wget -O/tmp/haproxy-1.4.22.tar.gz http://haproxy.1wt.eu/download/1.4/src/haproxy-1.4.22.tar.gz tar xvfz /tmp/haproxy-1.4.22.tar.gz -C /tmp/ cd /tmp/haproxy-1.4.22 make TARGET=linux26 make install
haproxy需要对每一个mysqlcluster服务器进行健康检查
1.在2台主机分别配置haproxy.cfg
root@10.1.6.203:scripts# cat /etc/haproxy/haproxy.cfg global maxconn 51200 #默认最大连接数 #uid 99 #gid 99 daemon #以后台形式运行haproxy #quiet nbproc 1 #进程数量(可以设置多个进程提高性能) pidfile /etc/haproxy/haproxy.pid #haproxy的pid存放路径,启动进程的用户必须有权限访问此文件 defaults mode tcp #所处理的类别 (#7层 http;4层tcp ) option redispatch #serverId对应的服务器挂掉后,强制定向到其他健康的服务器 option abortonclose #当服务器负载很高的时候,自动结束掉当前队列处理比较久的连接 timeout connect 5000s #连接超时 timeout client 50000s #客户端超时 timeout server 50000s #服务器超时 log 127.0.0.1 local0 #错误日志记录 balance roundrobin #默认的负载均衡的方式,轮询方式 listen proxy bind 10.1.6.173:3366 #监听端口 mode tcp #http的7层模式 option httpchk #心跳检测的文件 server db1 10.1.6.203:3306 weight 1 check port 9222 inter 12000 rise 3 fall 3 #服务器定义,check inter 12000是检测心跳频率 rise 3是3次正确认为服务器可用, fall 3是3次失败认为服务器不可用,weight代表权重 server db2 10.1.6.205:3306 weight 1 check port 9222 inter 12000 rise 3 fall 3 listen haproxy_stats mode http bind 10.1.6.173:8888 option httplog stats refresh 5s stats uri /status #网站健康检测URL,用来检测HAProxy管理的网站是否可以用,正常返回200,不正常返回503 stats realm Haproxy Manager stats auth admin:p@a1SZs24 #账号密码 root@10.1.6.205:~$ cat /etc/haproxy/haproxy.cfg global maxconn 51200 #uid 99 #gid 99 daemon #quiet nbproc 1 pidfile /etc/haproxy/haproxy.pid defaults mode tcp option redispatch option abortonclose timeout connect 5000s timeout client 50000s timeout server 50000s log 127.0.0.1 local0 balance roundrobin listen proxy bind 10.1.6.173:3366 mode tcp option httpchk server db1 10.1.6.203:3306 weight 1 check port 9222 inter 12000 rise 3 fall 3 server db2 10.1.6.205:3306 weight 1 check port 9222 inter 12000 rise 3 fall 3 listen haproxy_stats mode http bind 10.1.6.173:8888 option httplog stats refresh 5s stats uri /status stats realm Haproxy Manager stats auth admin:p@a1SZs24
2.安装xinetd
root@10.1.6.203:~# apt-get install xinetd
3.在每个节点添加xinetd服务脚本和mysqlchk端口号
root@10.1.6.203:~# vim /etc/xinetd.d/mysqlchk # default: on # description: mysqlchk service mysqlchk #需要在servive定义 { flags = REUSE socket_type = stream port = 9222 wait = no user = nobody server = /opt/mysqlchk log_on_failure += USERID disable = no per_source = UNLIMITED bind = 10.1.6.173 } root@10.1.6.203:~# vim /etc/services mysqlchk 9222/tcp # mysqlchk
4.编写mysqlchk监控服务脚本
root@10.1.6.203:~# ls -l /opt/mysqlchk -rwxr--r-- 1 nobody root 1994 2013-09-17 11:27 /opt/mysqlchk root@10.1.6.203:~# cat /opt/mysqlchk #!/bin/bash # # This script checks if a mysql server is healthy running on localhost. It will # return: # "HTTP/1.x 200 OK\r" (if mysql is running smoothly) # - OR - # "HTTP/1.x 500 Internal Server Error\r" (else) # # The purpose of this script is make haproxy capable of monitoring mysql properly # MYSQL_HOST="localhost" MYSQL_SOCKET="/var/run/mysqld/mysqld.sock" MYSQL_USERNAME="mysqlchkusr" #该账户密码需要在mysql里添加 MYSQL_PASSWORD="secret" MYSQL_OPTS="-N -q -A" TMP_FILE="/dev/shm/mysqlchk.$$.out" ERR_FILE="/dev/shm/mysqlchk.$$.err" FORCE_FAIL="/dev/shm/proxyoff" MYSQL_BIN="/opt/mysqlcluster/mysql-cluster-gpl-7.2.6-linux2.6-x86_64/bin/mysql" CHECK_QUERY="select 1" preflight_check() { for I in "$TMP_FILE" "$ERR_FILE"; do if [ -f "$I" ]; then if [ ! -w $I ]; then echo -e "HTTP/1.1 503 Service Unavailable\r\n" echo -e "Content-Type: Content-Type: text/plain\r\n" echo -e "\r\n" echo -e "Cannot write to $I\r\n" echo -e "\r\n" exit 1 fi fi done } return_ok() { echo -e "HTTP/1.1 200 OK\r\n" echo -e "Content-Type: text/html\r\n" echo -e "Content-Length: 43\r\n" echo -e "\r\n" echo -e "<html><body>MySQL is running.</body></html>\r\n" echo -e "\r\n" rm $ERR_FILE $TMP_FILE exit 0 } return_fail() { echo -e "HTTP/1.1 503 Service Unavailable\r\n" echo -e "Content-Type: text/html\r\n" echo -e "Content-Length: 42\r\n" echo -e "\r\n" echo -e "<html><body>MySQL is *down*.</body></html>\r\n" sed -e 's/\n$/\r\n/' $ERR_FILE echo -e "\r\n" rm $ERR_FILE $TMP_FILE exit 1 } preflight_check if [ -f "$FORCE_FAIL" ]; then echo "$FORCE_FAIL found" > $ERR_FILE return_fail; fi $MYSQL_BIN $MYSQL_OPTS --host=$MYSQL_HOST --socket=$MYSQL_SOCKET --user=$MYSQL_USERNAME --password=$MYSQL_PASSWORD -e "$CHECK_QUERY" > $TMP_FILE 2> $ERR_FILE if [ $? -ne 0 ]; then return_fail; fi return_ok;
测试
2个节点开启keepalived(主节点会获得vip,自动拉起haproxy),xinetd
root@10.1.6.203:~# ip add 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 16436 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 2: eth0: <BROADCAST,MULTICAST> mtu 1500 qdisc pfifo_fast state DOWN qlen 1000 link/ether 00:26:b9:36:0f:81 brd ff:ff:ff:ff:ff:ff inet 211.151.105.186/26 brd 211.151.105.191 scope global eth0 3: eth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000 link/ether 00:26:b9:36:0f:83 brd ff:ff:ff:ff:ff:ff inet 10.1.6.203/24 brd 10.1.6.255 scope global eth1 inet 10.1.6.173/32 scope global eth1 4: eth2: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000 link/ether 00:26:b9:36:0f:85 brd ff:ff:ff:ff:ff:ff 5: eth3: <BROADCAST,MULTICAST> mtu 1500 qdisc noop state DOWN qlen 1000 link/ether 00:26:b9:36:0f:87 brd ff:ff:ff:ff:ff:ff root@10.1.6.203:~# netstat -tunlp | grep ha tcp 0 0 10.1.6.173:3366 0.0.0.0:* LISTEN 1042/haproxy tcp 0 0 10.1.6.203:8888 0.0.0.0:* LISTEN 1042/haproxy udp 0 0 0.0.0.0:56562 0.0.0.0:* 1042/haproxy root@10.1.6.203:~# netstat -tunlp | grep xine tcp 0 0 10.1.6.203:9222 0.0.0.0:* LISTEN 30897/xinetd root@10.1.6.203:~# ps -ef | grep haproxy root 1042 1 0 Sep17 ? 00:00:00 /usr/local/sbin/haproxy -f /etc/haproxy/haproxy.cfg
测试:
通过vip10.1.6.173 3366访问cluster数据库(注意账户dave权限需要加3个ip10.1.6.203,10.1.6.205,10.1.6.173)
root@10.1.6.203:mgm# mysql -udave -p -h 10.1.6.173 -P 3366 Enter password: Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1344316 Server version: 5.5.22-ndb-7.2.6-gpl-log MySQL Cluster Community Server (GPL) Type 'help;' or '\h' for help. Type '\c' to clear the buffer. mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | dave | | test | +--------------------+ 3 rows in set (0.01 sec) mysql>
手动分别使keepalive,haproxy,数据库挂掉.vip10.1.6.173会自动漂到10.1.6.205从上,并不影响vip的访问
通过vip,haproxy查看各节点状态
http://10.1.6.173:8888/status
相关文章
- 这篇文章主要介绍了MySQL性能监控软件Nagios的安装及配置教程,这里以CentOS操作系统为环境进行演示,需要的朋友可以参考下...2015-12-14
- 新版 Mysql 中加入了对 JSON Document 的支持,可以创建 JSON 类型的字段,并有一套函数支持对JSON的查询、修改等操作,下面就实际体验一下...2016-08-23
深入研究mysql中的varchar和limit(容易被忽略的知识)
为什么标题要起这个名字呢?commen sence指的是那些大家都应该知道的事情,但往往大家又会会略这些东西,或者对这些东西一知半解,今天我总结下自己在mysql中遇到的一些commen sense类型的问题。 ...2015-03-15- 这篇文章主要介绍了MySQL 字符串拆分操作(含分隔符的字符串截取),具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-02-22
- 一、先说一下为什么要分表:当一张的数据达到几百万时,你查询一次所花的时间会变多,如果有联合查询的话,有可能会死在那儿了。分表的目的就在于此,减小数据库的负担,缩短查询时间。根据个人经验,mysql执行一个sql的过程如下:1...2014-05-31
- 我们自己鼓捣mysql时,总免不了会遇到这个问题:插入中文字符出现乱码,虽然这是运维先给配好的环境,但是在自己机子上玩的时候咧,总得知道个一二吧,不然以后如何优雅的吹牛B。...2015-03-15
- 这几天在centos下装mysql,这里记录一下安装的过程,方便以后查阅Mysql5.5.37安装需要cmake,5.6版本开始都需要cmake来编译,5.5以后的版本应该也要装这个。安装cmake复制代码 代码如下: [root@local ~]# wget http://www.cm...2015-03-15
- 宿主机使用网线的时候,客户机在Bridged Adapter模式下,使用Atheros AR8131 PCI-E Gigabit Ethernet Controller上网没问题。 宿主机使用无线的时候,客户机在Bridged Adapter模式下,使用可选项里唯一一个WIFI选项,Microsoft Virtual Wifi Miniport Adapter也无法上网,故弃之。...2013-09-19
- 首先要声明一点,大部分情况下,修改MySQL密码是需要有mysql里的root权限的...2013-09-11
- MySQL命令行导出数据库: 1,进入MySQL目录下的bin文件夹:cd MySQL中到bin文件夹的目录 如我输入的命令行:cd C:/Program Files/MySQL/MySQL Server 4.1/bin (或者直接将windows的环境变量path中添加该目录) ...2013-09-26
- 一、连接Mysql格式: mysql -h主机地址 -u用户名 -p用户密码1、连接到本机上的MYSQL。首先打开DOS窗口,然后进入目录mysql/bin,再键入命令mysql -u root -p,回车后提示你输密码.注意用户名前可以有空格也可以没有空格,但是密...2015-11-08
- Navicat for MySQL注册码用来激活 Navicat for MySQL 软件,只要拥有 Navicat 注册码就能激活相应的 Navicat 产品。这篇文章主要介绍了Navicat for MySQL 11注册码\激活码汇总,需要的朋友可以参考下...2020-11-23
- 这篇文章主要介绍了mysql IS NULL使用索引案例讲解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下...2021-08-14
- 这篇文章主要介绍了基于PostgreSQL和mysql数据类型对比兼容,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-12-25
- 一、准备编译环境,安装所需依赖包yum groupinstall 'Development' -y yum install openssl openssl-devel zlib zlib-devel -y yum install readline-devel pcre-devel ncurses-devel bison-devel cmake -y二、编译安...2015-10-21
Mysql中 show table status 获取表信息的方法
这篇文章主要介绍了Mysql中 show table status 获取表信息的方法的相关资料,需要的朋友可以参考下...2016-03-12- 这篇文章主要为大家分享了20分钟MySQL基础入门教程,快速掌握MySQL基础知识,真正了解MySQL,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...2016-12-02
- 这篇文章主要介绍了node.js如何操作MySQL数据库,帮助大家更好的进行web开发,感兴趣的朋友可以了解下...2020-10-29
- 传统的关系数据库一般由数据库(database)、表(table)、记录(record)三个层次概念组成,MongoDB是由数据库(database)、集合(collection)、文档对象(document)三个层次组成。MongoDB对于关系型数据库里的表,但是集合中没有列、行和关...2013-09-11
- 这篇文章主要介绍了Delphi远程连接Mysql的实现方法,需要的朋友可以参考下...2020-06-30