一、背景介紹
創(chuàng)新互聯(lián)成立于2013年,先為順河等服務(wù)建站,順河等地企業(yè),進(jìn)行企業(yè)商務(wù)咨詢服務(wù)。為順河企業(yè)網(wǎng)站制作PC+手機(jī)+微官網(wǎng)三網(wǎng)同步一站式服務(wù)解決您的所有建站問題。
傳統(tǒng)的主從復(fù)制架構(gòu)下,盡管可以使用半同步的方式進(jìn)行讀寫分離,但是主節(jié)點(diǎn)仍然存在單點(diǎn)隱患,在規(guī)模不大的情況下可以采用keepalive+雙主的模式對(duì)主節(jié)點(diǎn)進(jìn)行高可用保護(hù),客戶端通過VIP訪問MySQL服務(wù)器
二、實(shí)現(xiàn)方式
keepalive是通過vrrp協(xié)議實(shí)現(xiàn),之前有過介紹這里不多贅述,要注意的是在云主機(jī)是禁用vrrp協(xié)議的。本次實(shí)驗(yàn)采用CentOS7.4,數(shù)據(jù)庫(kù)版本為MariaDB-10.2.14,2臺(tái)MySQL服務(wù)器互為主從,172.16.10.30/24為keepalived服務(wù)的Master主機(jī),172.16.10.40/24為keepalived服務(wù)的Backup主機(jī),可以使用半同步的方式保證數(shù)據(jù)一致性,缺點(diǎn)是始終有一個(gè)服務(wù)器處于待機(jī)狀態(tài)
三、實(shí)驗(yàn)?zāi)康?/p>
采用keepalived+雙主模型對(duì)MySQL服務(wù)器做高可用,模擬A主機(jī)宕機(jī)時(shí)B主機(jī)繼續(xù)對(duì)外提供服務(wù),當(dāng)A主機(jī)上線后,重新成為Master節(jié)點(diǎn)
四、操作步驟
1.將MasterA與MasterB互為主從
(1)編輯AB主機(jī)配置文件并啟動(dòng)MySQL服務(wù)
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
skip_name_resolve=ON
relay_log=mysql-relaylog
relay_log_index=mysql-relaylog
relay_log_purge=OFF
slow_query_log=ON
server-id=10
innodb_file_per_table=ON
binlog_format=ROW
log_bin=mysql-binlog
log_slave_updates=ON
gtid_strict_mode=ON
(2)在A主機(jī)上創(chuàng)建復(fù)制賬號(hào)并導(dǎo)入數(shù)據(jù)庫(kù)
MariaDB [(none)]> grant replication slave on *.* to 'bak'@'172.16.10.%' identified by 'bakpassword';
MariaDB [(none)]> flush privileges;
MariaDB [(none)]> source /root/hellodb.sql;
MariaDB [hellodb]> show global variables like 'gtid%';
+------------------------+---------+
| Variable_name | Value |
+------------------------+---------+
| gtid_binlog_pos | 0-10-37 |
| gtid_binlog_state | 0-10-37 |
| gtid_current_pos | 0-10-37 |
| gtid_domain_id | 0 |
| gtid_ignore_duplicates | OFF |
| gtid_slave_pos | |
| gtid_strict_mode | ON |
+------------------------+---------+
(3)將B主機(jī)的Master指向A主機(jī)
MariaDB [(none)]> CHANGE MASTER TO master_host='172.16.10.30', master_port=3306, master_user='bak', master_password='bakpassword',master_use_gtid=current_pos;
MariaDB [(none)]> start slave;
MariaDB [(none)]> show global variables like 'gtid%';
+------------------------+---------+
| Variable_name | Value |
+------------------------+---------+
| gtid_binlog_pos | 0-10-37 |
| gtid_binlog_state | 0-10-37 |
| gtid_current_pos | 0-10-37 |
| gtid_domain_id | 0 |
| gtid_ignore_duplicates | OFF |
| gtid_slave_pos | 0-10-37 |
| gtid_strict_mode | ON |
+------------------------+---------+
(4)將A主機(jī)的Master指向B主機(jī)
MariaDB [(none)]> CHANGE MASTER TO master_host='172.16.10.40', master_port=3306, master_user='bak', master_password='bakpassword',master_use_gtid=current_pos;
MariaDB [(none)]> start slave;
此時(shí)雙主模型已經(jīng)構(gòu)建完成,主機(jī)B之所以不用創(chuàng)建復(fù)制賬號(hào)是因?yàn)橐褜創(chuàng)建賬號(hào)是的語(yǔ)句同步了過來
2.安裝配置keepalived
(1)AB主機(jī)安裝keepalived
(2)編輯A主機(jī)的故障轉(zhuǎn)移腳本
[root@host3 ~]# vim /etc/keepalived/chk_mysql.sh
#!/bin/bash
mysqlStr=/usr/bin/mysql
hostIP=172.16.10.30
chkUser=chk
chkPassword=chkpassword
mysqlPort=3306
$mysqlStr -h$hostIP -u$chkUser -p$chkPassword -P$mysqlPort -e "show global variables like '%gtid%';" > /dev/null 2>&1
if [ $? != 0 ];then
/usr/bin/systemctl stop keepalived.service
fi
(3)編輯A主機(jī)配置文件,啟動(dòng)服務(wù),讓A成為對(duì)外提供服務(wù)的主機(jī)
[root@host3 ~]# vim /etc/keepalived/keepalived.conf
vrrp_script chk_mysql {
script "/etc/keepalived/chk_mysql.sh"
interval 10
}
vrrp_instance VI_1 {
state MASTER
interface ens32
virtual_router_id 100
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.10.100
}
track_script {
chk_mysql
}
}
[root@host3 ~]# systemctl start keepalived.service
(4)編輯A主機(jī)配置文件,啟動(dòng)服務(wù)
[root@host4 ~]# vim /etc/keepalived/keepalived.conf
vrrp_instance VI_1 {
state BACKUP
nopreempt
interface ens32
virtual_router_id 100
priority 90
advert_int 1
authentication {
auth_type PASS
auth_pass 1111
}
virtual_ipaddress {
172.16.10.100
}
}
[root@host4 ~]# systemctl start keepalived.service
五、效果驗(yàn)證
(1)在AB任意主機(jī)上創(chuàng)建一個(gè)可以遠(yuǎn)程管理的賬號(hào)
MariaDB [hellodb]> grant all on *.* to 'chk'@'172.16.10.%' identified by 'chkpassword';
MariaDB [hellodb]> flush privileges;
(2)再使用另一個(gè)主機(jī)通過VIP發(fā)現(xiàn)當(dāng)前gtid_binlog_pos在B主機(jī)上,說明之前對(duì)外提供服務(wù)的是B主機(jī)
[root@host5 ~]# mysql -h272.16.10.100 -uchk -pchkpassword -P3306 -e"show global variables like '%gtid%';"
+------------------------+-----------------+
| Variable_name | Value |
+------------------------+-----------------+
| gtid_binlog_pos | 0-20-42 |
| gtid_binlog_state | 0-10-40,0-20-42 |
| gtid_current_pos | 0-20-42 |
| gtid_domain_id | 0 |
| gtid_ignore_duplicates | OFF |
| gtid_slave_pos | 0-20-42 |
| gtid_strict_mode | ON |
| wsrep_gtid_domain_id | 0 |
| wsrep_gtid_mode | OFF |
+------------------------+-----------------+
(3)從遠(yuǎn)程節(jié)點(diǎn)通過VIP對(duì)數(shù)據(jù)庫(kù)執(zhí)行任意DML操作后,發(fā)現(xiàn)gtid_binlog_pos回到了A主機(jī),說明A主機(jī)已持有VIP
[root@host5 ~]# mysql -h272.16.10.100 -uchk -pchkpassword -P3306 -e"delete from hellodb.students where stuid=11;"
[root@host5 ~]# mysql -h272.16.10.100 -uchk -pchkpassword -P3306 -e"show global variables like '%gtid%';"
+------------------------+-----------------+
| Variable_name | Value |
+------------------------+-----------------+
| gtid_binlog_pos | 0-10-43 |
| gtid_binlog_state | 0-20-42,0-10-43 |
| gtid_current_pos | 0-10-43 |
| gtid_domain_id | 0 |
| gtid_ignore_duplicates | OFF |
| gtid_slave_pos | 0-10-43 |
| gtid_strict_mode | ON |
| wsrep_gtid_domain_id | 0 |
| wsrep_gtid_mode | OFF |
+------------------------+-----------------+
(4)停止A主機(jī)MySQL服務(wù),模擬故障,再通過VIP執(zhí)行DML操作后發(fā)現(xiàn)gtid_binlog_pos回到了B主機(jī),此時(shí)B主機(jī)對(duì)外提供服務(wù),故障已切換
[root@host3 ~]# systemctl stop keepalived.service
[root@host5 ~]# mysql -h272.16.10.100 -uchk -pchkpassword -P3306 -e"delete from hellodb.students where stuid=7;"
[root@host5 ~]# mysql -h272.16.10.100 -uchk -pchkpassword -P3306 -e"show global variables like '%gtid%';"
+------------------------+-----------------+
| Variable_name | Value |
+------------------------+-----------------+
| gtid_binlog_pos | 0-20-45 |
| gtid_binlog_state | 0-10-44,0-20-45 |
| gtid_current_pos | 0-20-45 |
| gtid_domain_id | 0 |
| gtid_ignore_duplicates | OFF |
| gtid_slave_pos | 0-20-45 |
| gtid_strict_mode | ON |
| wsrep_gtid_domain_id | 0 |
| wsrep_gtid_mode | OFF |
+------------------------+-----------------+
(5)重啟A主機(jī)MySQL服務(wù),再重啟keepalived服務(wù),A主機(jī)重新持有VIP,此時(shí)再通過VIP執(zhí)行DML操作后發(fā)現(xiàn)gtid_binlog_pos回到A主機(jī),說明A主機(jī)重新持有VIP,至此所有操作完成
補(bǔ)充說明:
以本文為例,當(dāng)A主機(jī)的MySQLd服務(wù)停止后,其keepalived服務(wù)也會(huì)跟著停止,重啟MySQLd服務(wù),keepalived服務(wù)并不會(huì)跟著啟動(dòng),必須手動(dòng)啟動(dòng),否則主機(jī)A將無法持有VIP