LVS+KeepAlived+Dbproxy+Mysql高可用集群方案
參考文檔https://www.php.cn/mysql-tutorials-116060.html
一、安裝mysql5.6
1、添加MySQL源
rpm -ivh https://repo.mysql.com//mysql57-community-release-el7-9.noarch.rpm
vim /etc/yum.repos.d/mysql-community.repo
[mysql56-community]
name=MySQL 5.6 Community Server
baseurl=http://repo.mysql.com/yum/mysql-5.6-community/el/7/$basearch/
enabled=1 #這里改成1
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
[mysql57-community]
name=MySQL 5.7 Community Server
baseurl=http://repo.mysql.com/yum/mysql-5.7-community/el/7/$basearch/
enabled=0 #這里改成0,禁用
gpgcheck=1
gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql
2、安裝mysql 5.6
2.1安裝
yum install mysql-server
2.2 初始化 #參考文檔https://www.cnblogs.com/sunny18/p/8684861.html
mysql_secure_installation
二、配置MySQL主從復(fù)制
1. 修改master節(jié)點配置文件:
vim /etc/my.cnf
[mysqld]
server-id=1 #不得與其他節(jié)點相同
report-port=3306
port=3306
datadir=/data/mysql/
socket=/tmp/mysql.sock
binlog-format=ROW
log-bin=master-bin
log-bin-index=master-bin.index
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
expire-logs-days=7
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
slave-parallel-workers=2
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log_events=1
auto_increment_increment=2 #該配置只需要在master1、master2上配置 用來確保自增鍵不沖突
auto_increment_offset=1 #該配置只需要在master1、master2上配置 用來確保自增鍵不沖突
#binlog-do-db=mydb #需要同步的數(shù)據(jù)庫,多個數(shù)據(jù)庫添加多行配置項即可,需要重啟mysql實例
#mysql中有自增長字段,在做數(shù)據(jù)庫的主主同步時需要設(shè)置自增長的兩個相關(guān)配置:auto_increment_offset和auto_increment_increment。auto_increment_offset表示自增長字段從那個數(shù)開始,他的取值范圍是1 .. 65535。auto_increment_increment表示自增長字段每次遞增的量,其默認值是1,取值范圍是1 .. 65535
##在主主同步配置時,需要將兩臺服務(wù)器的auto_increment_increment增長量都配置為2,而要把auto_increment_offset分別配置為1和2.這樣才可以避免兩臺服務(wù)器同時做更新時自增長字段的值之間發(fā)生沖突。
2.修改slave節(jié)點配置文件
vim /etc/my.cnf
[mysqld]
binlog-format=ROW
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
slave-parallel-workers=2
binlog-checksum=CRC32
master-verify-checksum=1
slave-sql-verify-checksum=1
binlog-rows-query-log_events=1
server-id=11 #不得與其他節(jié)點相同
report-port=3306
port=3306
log-bin=mysql-bin.log
datadir=/mydata
socket=/tmp/mysql.sock
#auto_increment_increment=2 #該配置只需要在master1、master2上配置 用來確保自增鍵不沖突
#auto_increment_offset=1 #該配置只需要在master1、master2上配置 用來確保自增鍵不沖突
#binlog-do-db=mydb #需要同步的數(shù)據(jù)庫,多個數(shù)據(jù)庫添加多行配置項即可,需要重啟mysql實例
注:四個節(jié)點的配置信息差不多一樣,server-id要確保唯一性。
3、登錄mysql創(chuàng)建復(fù)制用戶
#為了便于管理,本例中將所有節(jié)點的復(fù)制用戶都設(shè)置為一樣的。
GRANT REPLICATION SLAVE ON *.* TO repl@'%' IDENTIFIED BY 'passwd';
GRANT REPLICATION SLAVE ON *.* TO root@'%' IDENTIFIED BY '123456';
flush privileges;
4、為備節(jié)點提供初始數(shù)據(jù)集
注:
鎖定主表,備份主節(jié)點上的數(shù)據(jù),將其還原至從節(jié)點;
如果沒有啟用GTID,在備份時需要在master上使用show master status命令查看二進制日志文件名稱及事件位置,以便后面啟動slave節(jié)點時使用。
5、啟動從節(jié)點的復(fù)制線程
5.1 master1 執(zhí)行
CHANGE MASTER TO MASTER_HOST='master2.node.com',MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='passwd', MASTER_AUTO_POSITION=1;
5.2 master2 執(zhí)行
CHANGE MASTER TO MASTER_HOST='master1.node.com',MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='passwd', MASTER_AUTO_POSITION=1;
5.3 slave1 執(zhí)行
CHANGE MASTER TO MASTER_HOST='master1.node.com',MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='passwd', MASTER_AUTO_POSITION=1;
5.4 slave2 執(zhí)行
CHANGE MASTER TO MASTER_HOST='master2.node.com',MASTER_PORT=3306, MASTER_USER='repl', MASTER_PASSWORD='passwd', MASTER_AUTO_POSITION=1;
6、在各節(jié)點上查看是否成功開啟復(fù)制
show slave status\G;
#Slave_IO_Running: Yes\Slave_SQL_Running: Yes 表示主從復(fù)制線程成功執(zhí)行。
三、配置高可用負載均衡keepalived+lvs
master1、mastre2搭建寫高可用負載均衡,
VIP:192.168.1.120。
slave1、slave2搭建讀高可用負載均衡,
VIP:192.168.1.200。
1、安裝ipvsadm ``
注:linux內(nèi)核2.4版本以上的基本都支持LVS,要使用lvs,只需要再安裝一個lvs的管理工具:ipvsadm
yum -y install ipvsadm
ipvsadm -Ln
echo "1" > /proc/sys/net/ipv4/ip_forward
sysctl -p
2、配置lvs,四個節(jié)點上幾乎都一樣lvs腳本,只需要修改相應(yīng)的VIP即可
vim /etc/rc.d/init.d/realserver.sh
#!/bin/bash
#description: Config realserver lo and apply noarp
SNS_VIP=192.168.146.220 #修改為對應(yīng)的VIP即可
. /etc/rc.d/init.d/functions
case "$1" in
# 禁用本地的ARP請求、綁定本地回環(huán)地址
start)
/sbin/ifconfig lo down
/sbin/ifconfig lo up
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
/sbin/sysctl -p >/dev/null 2>&1
/sbin/ifconfig lo:0 $VIP netmask 255.255.255.255 up #在回環(huán)地址上綁定VIP,設(shè)定掩碼,與Direct Server(自身)上的IP保持通信
/sbin/route add -host $VIP dev lo:0
echo "LVS-DR real server starts successfully.\n"
;;
stop)
/sbin/ifconfig lo:0 down
/sbin/route del $VIP >/dev/null 2>&1
echo "1" >/proc/sys/net/ipv4/conf/lo/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/lo/arp_announce
echo "1" >/proc/sys/net/ipv4/conf/all/arp_ignore
echo "2" >/proc/sys/net/ipv4/conf/all/arp_announce
echo "LVS-DR real server stopped.\n"
;;
status)
isLoOn=`/sbin/ifconfig lo:0 | grep "$VIP"`
isRoOn=`/bin/netstat -rn | grep "$VIP"`
if [ "$isLoON" == "" -a "$isRoOn" == "" ]; then
echo "LVS-DR real server has run yet."
else
echo "LVS-DR real server is running."
fi
exit 3
;;
*)
echo "Usage: $0 {start|stop|status}"
exit 1
esac
exit 0
3、添加腳本執(zhí)行權(quán)限個節(jié)點都執(zhí)行:
chmod u+x /etc/rc.d/init.d/realserver.sh
4、啟動lvs
/etc/rc.d/init.d/realserver.sh start #啟動lvs腳本設(shè)置參數(shù),綁定VIP
5、4臺服務(wù)器安裝keepalived
注:Keepalived是一個專門為lvs提供高可用功能的機制,它可以實現(xiàn)當(dāng)有兩個主從lvs,而且主lvs損壞的時候,將其IP地址以及l(fā)vs轉(zhuǎn)移至備份lvs上。
yum -y install keepalived
6、配置文件位置:/etc/keepalived/keepalived.conf
master1、master2上的keeplived為互備模式
slave1、slave2上的keeplived為互備模式
vim /etc/keepalived/keepalived.conf
! Configuration File for keepalived
global_defs {
router_id LVS_Master
}
vrrp_instance VI_1 {
state BACKUP #在備機上修改為BACKUP
interface eth1 #VIP要綁定到eth1上,是具體情況而定,填寫具體的主機網(wǎng)卡名稱
virtual_router_id 60
priority 100 #對應(yīng)備機的值要小于這個值
nopreempt #不搶占資源,意思就是它活了之后也不會再把主搶回來,備機不需要設(shè)置改項
advert_int 1
authentication {
auth_type PASS #備機上要與之一致
auth_pass 1111 #備機上要與之一致
}
virtual_ipaddress {
192.168.1.120/32 dev eth1 label eth1:0 #VIP要綁定到eth1上,是具體情況而定,填寫具體的主機網(wǎng)卡名稱,修改為對應(yīng)的VIP
}
}
virtual_server 192.168.1.120 3306 { #修改為對應(yīng)的VIP
delay_loop 6
lb_algo wrr #lvs負載均衡算法
lb_kind DR #lvs的轉(zhuǎn)發(fā)模式
#nat_mask 255.255.255.0
persistence_timeout 50
protocol TCP
real_server 192.168.1.121 3306 { #修改為master01對應(yīng)的ip
weight 2
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 3306
}
}
real_server 192.168.1.114 3306 { #修改為master02對應(yīng)的ip
weight 2
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 3306
}
}
}
7、啟動keepalibed,并查看VIP綁定情況
/etc/init.d/keepalived start
ip add #查看IP狀態(tài)
ipvsadm -Ln # 查看LVS狀態(tài),若有沒有該工具yum -y install ipvsadm即可
四、安裝使用dbproxy
1.rpm -vhi Atlas-2.2.1.el6.x86_64.rpm # 將下載的rpm安裝到服務(wù)器上
2.cd /usr/local/mysql-proxy/conf/ # 進入到代理目錄
3.cp test.cnf dbproxy.cnf # 將自帶的test配置文件拷貝成新的排位置文件
2.vim /usr/local/mysql-proxy/conf/dbproxy.cnf # 修改新的配置文件
[mysql-proxy]
#帶#號的為非必需的配置項目
#管理接口的用戶名
admin-username = admin
#管理接口的密碼
admin-password = 123456
#Atlas后端連接的MySQL主庫的IP和端口,可設(shè)置多項,用逗號分隔
#修改地址為之前配置的虛擬地址
proxy-backend-addresses = 192.168.1.120:3308
#Atlas后端連接的MySQL從庫的IP和端口,@后面的數(shù)字代表權(quán)重,用來作負載均衡,若省略則默認為1,可設(shè)置多項,用逗號分隔
#修改地址為兩個從庫的地址
proxy-read-only-backend-addresses = 99.1.17.14:3308@1,99.1.17.13:3308@1
#用戶名與其對應(yīng)的加密過的MySQL密碼,密碼使用PREFIX/bin目錄下的加密程序encrypt加密,下行的user1和user2為示例,將其替換為你的MySQL的用戶名和加密密碼!
#為確保代理正常寫入。最好新建統(tǒng)一新的賬戶去代理
pwds = root:/iZxz+0GRoA=
#設(shè)置Atlas的運行方式,設(shè)為true時為守護進程方式,設(shè)為false時為前臺方式,一般開發(fā)調(diào)試時設(shè)為false,線上運行時設(shè)為true,true后面不能有空格。
daemon = true
#設(shè)置Atlas的運行方式,設(shè)為true時Atlas會啟動兩個進程,一個為monitor,一個為worker,monitor在worker意外退出后會自動將其重啟,設(shè)為false時只有worker,沒有monitor,一般開發(fā)調(diào)試時設(shè)為false,線上運行時設(shè)為true,true后面不能有空格。
keepalive = true
#工作線程數(shù),對Atlas的性能有很大影響,可根據(jù)情況適當(dāng)設(shè)置
event-threads = 8
#日志級別,分為message、warning、critical、error、debug五個級別
log-level = debug
#日志存放的路徑
log-path = /usr/local/mysql-proxy/log
#SQL日志的開關(guān),可設(shè)置為OFF、ON、REALTIME,OFF代表不記錄SQL日志,ON代表記錄SQL日志,REALTIME代表記錄SQL日志且實時寫入磁盤,默認為OFF
sql-log = ON
#慢日志輸出設(shè)置。當(dāng)設(shè)置了該參數(shù)時,則日志只輸出執(zhí)行時間超過sql-log-slow(單位:ms)的日志記錄。不設(shè)置該參數(shù)則輸出全部日志。
sql-log-slow = 3000
#實例名稱,用于同一臺機器上多個Atlas實例間的區(qū)分
#instance = test
#Atlas監(jiān)聽的工作接口IP和端口
proxy-address = 0.0.0.0:3306
#Atlas監(jiān)聽的管理接口IP和端口
admin-address = 0.0.0.0:2345
#分表設(shè)置,此例中person為庫名,mt為表名,id為分表字段,3為子表數(shù)量,可設(shè)置多項,以逗號分隔,若不分表則不需要設(shè)置該項
#tables = person.mt.id.3
#默認字符集,設(shè)置該項后客戶端不再需要執(zhí)行SET NAMES語句
charset = utf8
#允許連接Atlas的客戶端的IP,可以是精確IP,也可以是IP段,以逗號分隔,若不設(shè)置該項則允許所有IP連接,否則只允許列表中的IP連接
#client-ips = 127.0.0.1, 192.168.1
#Atlas前面掛接的LVS的物理網(wǎng)卡的IP(注意不是虛IP),若有LVS且設(shè)置了client-ips則此項必須設(shè)置,否則可以不設(shè)置
#lvs-ips = 192.168.1.1
五、監(jiān)控mysql健康狀態(tài)
對mysql的健康狀態(tài)檢查后執(zhí)行的操作,在real_server區(qū)段添加:
notify_up $PATH/SCRIPT.sh #檢測到服務(wù)開啟后執(zhí)行的腳本 可以是郵件報警,如某某IP,mysql掛掉。。。。
notify_down $PATH/SCRIPT.sh #檢測到服務(wù)停止后執(zhí)行的腳本.
在實際應(yīng)用中,當(dāng)master掛掉之后,backup會占有資源。
但當(dāng)master恢復(fù)之后會搶占資源,自己繼續(xù)做回主,將VIP綁定至master主機上。此時正在連接的業(yè)務(wù)有可能會中斷。
所以在生產(chǎn)上需要設(shè)置為不搶占(nopreempt)資源,即它活了之后也不會將主搶回來,繼續(xù)作為備機存在。但nopreempt只能在stat為BACKUP時設(shè)置,所以此時應(yīng)該將主備機上的stat 都設(shè)置為BACKUP,將priority設(shè)置為一高一低,以優(yōu)先級高低確定誰是主。對keeplived做簡單的修改即可:
state BACKUP #都修改成BACKUP
virtual_router_id 60 #默認51 主從都修改為60
priority 100 #優(yōu)先級(1-254之間),另一臺改為90,備用節(jié)點必須比主節(jié)點優(yōu)先級低。
nopreempt #不搶占資源,意思就是它活了之后也不會再把主搶回來,備機不需要設(shè)置改項
五、附錄
1、架構(gòu)圖

WechatIMG117.png
2.遇見的問題
1.dbproxy日志報錯信息如下:
2019-12-18 06:15:45: (critical) proxy-plugin.c.1450: I have no server backend, closing connection
2019-12-18 06:15:45: (critical) network-mysqld.c.1387: plugin_call(CON_STATE_READ_QUERY) failed
解決方式:
由于代理賬號未能在全部數(shù)據(jù)庫上統(tǒng)一造成的。
新建統(tǒng)一賬號作為代理賬號即可。