mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構

一般小型公司數據庫,使用主從複製即可保證數據庫的高可用,但是一旦主數據庫故障,切換到從庫需要一定的時間,這樣就導致了停機時間過長,不能及時恢復業務。使用雙主(master)配合keepalived這種mysql高可用架構也是基於主從複製的原理而搭建的。這是一種簡單、便捷的解決方案,在高可用集羣環境中,keepalived使用vip,利用keepalived自帶的服務監控功能和自定義腳本來實現mysql故障時自動切換。

1、mysql雙主複製介紹

雙主複製,就是相互做主從複製,每個master既是master又是另外一臺服務器的slave。這樣,任何一方所做的變更,都會通過複製應用到另外一方的數據庫中。
mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構
主從複製涉及三個線程,一個運行到主節點(log dump thread),其餘兩個(I/O thread,SQL thread)運行在從節點,如下所示:

mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構
i/o線程去請求主庫 的binlog,並將得到的binlog日誌寫到relay log(中繼日誌) 文件中;

主庫會生成一個 log dump 線程,用來給從庫 i/o線程傳binlog;

SQL 線程,會讀取relay log文件中的日誌,並解析成具體操作,來實現主從的操作一致,而最終數據一致;

主從複製重點:

1)主從複製是異步的邏輯的sql語句級的複製

2)複製時,主庫有一個I/O線程,從庫有有兩個線程,即I/O和SQL線程。

3)實現主從複製的必要條件是主庫需要開啓binlog功能

4)作爲複製的所有mysql節點的server-id都不能相同

5)binlog文件只記錄對數據庫有更改的sql語句,不記錄任何查詢語句。

大致的邏輯流程圖如下所示:
mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構

2 keepalived

Keepalived 是一個基於 vrrp 協議來實現的服務器高可用解決方案,可以利用其實現避免IP單點故障,類似的工具還有 heartbeat 、 corosync 。不過其不會單獨出現,而是搭配着 LVS、Nginx、HAproxy,一起協同工作達到高可用的目的

VRRP 全稱Vritual Router Redundancy Protocol,虛擬路由冗餘協議。通過把幾臺提供路由功能的設備組成一個虛擬路由設備,使用一定的機制保證虛擬路由的高可用,從而達到保持業務的連續性與可靠性。

在這組成的一個虛擬路由器中,有 master 和 backup 之分。master是主節點,在一個虛擬路由器中,只能有一個master,但可以有多個backup;backup是備用節點,也就是當master掛掉之後,backup接手master節點的所有資源,當有多個backup節點時,根據其 priority (優先級)的值的大小,來選擇誰作爲master的替代者。當backup節點的優先級值相同時,根據其IP地址的大小,來決定。
工作原理圖
mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構
大致的工作流程如下所示:
mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構

3 實驗配置

3.1 基礎環境

基於社區版myql8.0進行實驗
172.31.208.123 主master A,
172.31.208.124 備庫 master B
vip 172.31.208.125
架構原理如下所示:
mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構

3.2 數據庫配置文件

要是實現主主複製,就是在主從複製的基礎上配置相互爲主從

數據庫主master A,配置文件如下所示,/etc/my.cnf

server-id = 1                                                #任意自然n,只需要保證兩臺mysql主機不重複就可以
log-bin=mysql-bin                                        #開啓二進制日誌
auto_increment_increment=2                      #步進值auto_imcrement 。一般有n臺主mysql就填n
auto_increment_offset=1                             #起始值,一般填寫第n臺主機mysql.此時爲第一臺主  mysql
#binlog-ignore=mysql                                  #忽略mysql庫,可以不填寫
#binlog-ignore=infomation_schema            #忽略information_schema庫,一般不填寫
replicate-do-db=test_db                              #指定同步的數據庫,不填寫則默認所有的數據庫

數據庫主master B,配置文件如下所示,/etc/my.cnf

server-id = 2
log-bin=mysql-bin
auto_increment_increment=2
auto_increment_offset=2
#binlog-ignore=mysql
#binlog-ignore=infomation_schema
replicate-do-db=test_db

完成配置後,重啓mysql

3.3 主庫masterA主從配置

然後開始創建複製用戶,repel,密碼repel
主庫master A

create user 'repl'@'172.31.208.124' identified with mysql_native_password by 'mysqlP@ssw0rd';      #創建用戶 mysql.0中密碼需要填寫mysql_native_password
grant replication slave on *.* to 'repl'@'172.31.208.124';                         #分配權限
flush privileges;                                                                                         #刷新權限

然後查看賬戶是否權限分配正確

show grants for 'repl'@'172.31.208.124';

mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構
查看masterA狀態,記錄二進制文件名和位置

show master status;

mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構

登陸masterB數據庫,執行同步語句

mysql> change master to
    -> master_host='172.31.208.123',
    -> master_user='repl',
    -> master_password='mysqlP@ssw0rd',
    -> master_log_file='mysql-bin.000001',
    -> master_log_pos=896;

然後啓動slave同步進程

mysql> start slave;

然後檢查slave狀態

show slave status\G

mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構
如果在error沒有看到配置錯誤信息,則說明配置成功

3.4 備庫masterB 主從配置

基本跟主庫masterA配置方式一樣
創建用戶repl分配權限

mysql> create user 'repl'@'172.31.208.123' identified with mysql_native_password by 'mysqlP@ssw0rd';
mysql> grant replication slave on *.* to 'repl'@'172.31.208.123';
mysql> flush privileges;

查看masterB的狀態
mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構
然後登陸masterA,執行同步語句

mysql> change master to 
    -> master_host='172.31.208.124',
    -> master_user='repl',
    -> master_password='mysqlP@ssw0rd',
    -> master_log_file='mysql-bin.000001',
    -> master_log_pos=866;

然後啓動slave同步,檢查slave狀態·

 mysql>start slave;
 mysql>show slave status\G

mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構
查看到以上信息,說明配置正確

3.5 測試

主庫masterA上創建test_db,並創建表product

mysql> create table product(
    ->        product_id int(10) not NULL,
    ->        product_name varchar(100) not NULL,
    ->        product_tyep varchar(32) not NULL,
    ->        sale_price int(10) default 0,
    ->        input_price int(10) default 0,
    ->        regist_time date,
    ->        primary key (product_id)
    -> );

masterB上查看

mysql> show databases;
mysql> use test_db;
mysql> show tables;
mysql> desc product;

mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構
能夠看到masterA中test_db庫中的表product已經同步過來

然後備庫masterB上創建test_db庫中的表product_new,然後再masterA上查看

mysql> create table product_new(
    -> product_id int(10) not NULL,
    ->        product_name varchar(100) not NULL,
    ->        product_tyep varchar(32) not NULL,
    ->        sale_price int(10) default 0,
    ->        input_price int(10) default 0,
    ->        regist_time date,
    ->        primary key (product_id)
    -> );

masterA上查看

mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構
至此 證明,雙主配置成功

注意事項
1、主主複製配置文件中auto_increment_increment和auto_increment_offset只能保證主鍵不重複,卻不能保證主鍵有序。

2、當配置完成Slave_IO_Running、Slave_SQL_Running不全爲YES時,show slave status\G信息中有錯誤提示,可根據錯誤提示進行更正。

3、Slave_IO_Running、Slave_SQL_Running不全爲YES時,大多數問題都是數據不統一導致。
4、兩個數據庫最好軟件硬件等規格配置要一致

常見出錯點:

1、兩臺數據庫都存在db數據庫,而第一臺MySQL db中有tab1,第二臺MySQL db中沒有tab1,那肯定不能成功。

2、已經獲取了數據的二進制日誌名和位置,又進行了數據操作,導致POS發生變更。在配置CHANGE MASTER時還是用到之前的POS。

3、stop slave後,數據變更,再start slave。出錯。

終極更正法:重新執行一遍CHANGE MASTER就好了。

4、配置keepalived

兩臺數據庫,使用yum安裝keepalived的軟件包

yum install -y keepalived

在配置前,要確保兩邊時間一致,可以用ntp chrony等工具進行時間同步
同時關閉防火牆和相關配置,保證兩邊心跳
然後確認網卡多播支持
mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構
沒有開啓的話按照如下方式開啓

ip link set multicast on dev eth0  

安裝keepalived後,檢查版本
mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構
keepalived的配置文件路徑爲:/etc/keepalived/keepalived.conf,裏面有很多無用的配置,需要進行清理,按照我們的需要進行重新配置
完成修改後主masterA 的配置文件如下:

! Configuration File for keepalived

vrrp_script check_mysql_status {                                #定義vrrp腳本,檢測mysql主從狀態
script "keepalived_check_mysql.sh"                           #腳本名稱

interval 10                                                                   #腳本檢測執行間隔時間 10秒
}

vrrp_instance VI_1 {                                                  #實例名字V1_1,相同的實例備節點名字要和這個相同
    nopreempt                                                             #採取非搶佔模式
    state BACKUP                                                    # 狀態爲BACKUP狀態,避免發生裂腦、衝突現象
    interface ens192                                                  #定義通信接口爲ens192,此參數備節點和主節點相同,根據網卡實際名稱來
    virtual_router_id 51                                              #實例ID爲51
    priority 100                                                          #優先級爲90,備節點的優先級必須比此數字低
    advert_int 5                                                           #通信檢查檢查間隔時間爲1秒
    authentication {
        auth_type PASS                                                #認證類型,此參數備節點設置和主節點設置相同
        auth_pass 1111                                                  #密碼是1111,此參數備節點設置和主節點相同
    }
    virtual_ipaddress {                                                 #虛擬機IP,即VIP爲172.31.208.95/24,綁定接口爲ens192,別名爲ens192:1,此參數備節點設置和主節點相同
        172.31.208.124/24 dev ens192 label ens192:1
    }
    track_script {
    check_mysql_status                                              #觸發檢查
    }
}

以下爲masterB的配置文件

script "keepalived_check_mysql.sh"

interval 10
}

vrrp_instance VI_1 {
    nopreempt
    state BACKUP
    interface ens192
    virtual_router_id 51
    priority 100
    advert_int 5
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        172.31.208.125/24 dev ens192 label ens192:1
    }
    track_script {
    check_mysql_status
    }
}

說明:

1、總體配置和其他keepalived配置一致
2、使用雙主,狀態都要配置成backup狀態,並且使用非搶佔模式,通過優先級來判斷誰是主庫,避免裂鬧,衝突

注意,默認情況下,keepalived軟件僅僅在對方機器宕機或者keepalive停掉的時候纔會接管業務。有時mysql服務停止,但是keepalived服務還在工作,此時就會導致用戶的訪問的vip無法找到對應的服務,所以需要編寫腳本,檢測mysql服務狀態,當服務中斷時,keepalive服務也中斷,這裏的keepalived_check_mysql.sh腳本的作用就是這樣。腳本如下,保存在主maserA和備masterB的/etc/keepalived/路徑下

#!/bin/bash
#for centos7
mysqlstr=/usr/sbin/mysqld
user=user
password=ctbtP@ssw0rd

##mysql服務狀態正常爲1,否則爲0
#mysql_status=1

####check mysql status######
$mysqlstr  -u $user -p$password -e "show status;" >/dev/null 2>&1  #執行成功,代表數據庫服務正常
echo "mysql_status=1"
exit 0
else
systemctl stop mysqld
fi

記得加上可執行權限

配置完成後,分別啓動masterA和masterB的keepalived服務

systemctl start keepalived
systemctl enable keepalvied

注意,當配置文件有任何錯誤的時候,systemctl 不會提示keepalived啓動失敗,需要使用systemclt status檢查服務
mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構
也可通過日誌文件查看啓動情況

tail -f /var/log/messages

mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構

當配置正確主masterA會有vip
mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構
而masterB不會有vip
mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構

keepalived總結

mysql學習-mysql8.0配置雙主複製+keepalived實現高可用架構

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章