MySQL 高可用——雙主

生產環境中一臺mysql主機存在單點故障,所以我們要確保mysql的高可用性,即兩臺MySQL服務器如果其中有 一臺MySQL服務器掛掉後,另外一臺能立馬接替其進行工作。 MySQL的高可用方案一般有如下幾種: keepalived+雙主,MHA,PXC,MMM,Heartbeat+DRBD等,比較常用的是keepalived+雙主,MHA和PXC。 本節主要介紹了利用 keepalived 實現 MySQL 數據庫的高可用。 Keepalived+mysql雙主來實現MySQL-HA,我 們必須保證兩臺MySQL數據庫的數據完全一樣,基本思路是兩臺MySQL互爲主從關係,通過Keepalived配置虛 擬IP,實現當其中的一臺MySQL數據庫宕機後,應用能夠自動切換到另外一臺MySQL數據庫,保證系統的高可 用。
一、配置兩臺MySQL主主同步
該過程的第一部分就是master記錄二進制日誌。在每個事務更新數據完成之前,master在二日誌記錄這些改 變。MySQL將事務寫入二進制日誌。在事件寫入二進制日誌完成後,master通知存儲引擎提交事務。 下一步就 是slave將master的binary log拷貝到它自己的中繼日誌。首先,slave開始一個工作線程——I/O線程。I/O線程 在master上打開一個普通的連接,然後開始binlog dump process。Binlog dump process從master的二進制日 志中讀取事件,如果已經同步了master,它會睡眠並等待master產生新的事件。I/O線程將這些事件寫入中繼日 志。 SQL slave thread(SQL從線程)處理該過程的後一步。SQL線程從中繼日誌讀取事件,並重放其中的事 件而更新slave的數據,使其與master中的數據一致。只要該線程與I/O線程保持一致,中繼日誌通常會位於OS 的緩存中,所以中繼日誌的開銷很小。 主主同步就是兩臺機器互爲主的關係,在任何一臺機器上寫入都會同 步。 若mysql主機開啓了防火牆,需要關閉防火牆或創建規則。
master1有關複製的配置如下:
#開啓二進制日誌,修改server-id號

[root@mysql ~]# vim /etc/my.cnf 
log-bin=mysql-bin
binlog_format=mixed
server-id=1
relay-log=relay-bin
relay-log-index=slave-relay-bin.index
auto-increment-increment=2
auto-increment-offset=1
[root@mysql ~]# systemctl restart mysqld

master2有關複製的配置如下:

[root@mysql ~]# vim /etc/my.cnf 
log-bin=mysql-bin
binlog_format=mixed
server-id=2
relay-log=relay-bin
relay-log-index=slave-relay-bin.index
auto-increment-increment=2
auto-increment-offset=2
[root@mysql ~]# systemctl restart mysqld

注:master1和master2只有server-id不同和 auto-increment-offset不同。
mysql中有自增長字段,在做數據庫的主主同步時需要設置自增長的兩個相關配置:auto_increment_offset和 auto_increment_increment。 auto-increment-increment表示自增長字段每次遞增的量,其默認值是1。它的值 應設爲整個結構中服務器的總數,本案例用到兩臺服務器,所以值設爲2。 auto-increment-offset是用來設定數 據庫中自動增長的起點(即初始值),因爲這兩能服務器都設定了一次自動增長值2,所以它們的起點必須得不同,這樣才能避免兩臺服務器數據同步時出現主鍵衝突。
注:可以在my.cnf文件中添加“binlog_do_db=數據庫名”配置項(可以添加多個)來指定要同步的數據庫 。
將master1設爲master2的主服務器 在master1主機上創建授權賬戶,允許在master2(192.168.171.145)主機上 連接

mysql> grant replication slave on *.* to rep@'192.168.171.%' identified by '123';
mysql> flush privileges;
#查看master1的當前binlog狀態信息
mysql> show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 |      610 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

在master2上將master1設爲自已的主服務器並開啓slave功能

mysql>change master to master_host='192.168.171.135',master_user='rep',master_password='123',master_log_file='mysql-bin.000001',master_log_pos=610;
mysql>start slave;
mysql>show slave status\G       # 查看slave狀態,一下兩個進程必須爲yes
Slave_IO_Running:Yes 
Slave_SQL_Running:Yes 

在這裏插入圖片描述
標註:切記MySQL的UUID不要相同,這裏我是克隆的另一個mysql所以做的過程中報錯UUID相同導致兩個進程只有一個yes了,報錯信息如下

Last_IO_Error: Fatal error: The slave I/O thread stops because master and slave have equal MySQL server UUIDs; these UUIDs must be different for replication to work.

將master2設爲master1的主服務器 在master2主機上創建授權賬戶,允許在

master1(192.168.171.135)主機上 連接
mysql>grant replication slave on *.* to rep@'192.168.171.%' identified by '123';
mysql>flush privileges;
#查看master2的當前binlog狀態信息
mysql>show master status;
+------------------+----------+--------------+------------------+-------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000002 |      610 |              |                  |                   |
+------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

在master1上將master2設爲自已的主服務器並開啓slave功能

mysql> change master to master_host='192.168.171.145',master_user='rep',master_password='123',master_log_file='mysql-bin.000002',master_log_pos=610;
mysql> start slave;
#查看salve狀態
mysql> show slave status\G
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

在這裏插入圖片描述
測試主主同步 在master1上創建要同步的數據庫如test1,並在test1中創建一張測試表如tab1

mysql> create database test1;
mysql> use test1;
mysql> create table tab1(id int,name varchar(32));
#查看master2主機是否同步了master1上的數據變化
mysql>show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| sys                |
| test1              |
+--------------------+
5 rows in set (0.00 sec)
mysql>use test1;
mysql>show tables;
+-----------------+
| Tables_in_test1 |
+-----------------+
| tab1            |
+-----------------+
1 row in set (0.00 sec)
#可以看出master2同步了master的數據變化 在master2主機上向tab1表中插入數據
mysql>insert into tab1 values(1,'tom1');
mysql>commit;
#查看master1主機是否同步了master2上的數據變化
mysql> select * from tab1;
+------+------+
| id   | name |
+------+------+
|    1 | tom1 |
+------+------+
1 row in set (0.00 sec)

現在任何一臺MySQL上更新數據都會同步到另一臺MySQL,MySQL同步完成。

注:若主MYSQL服務器已經存在,只是後期才搭建從MYSQL服務器,在置配數據同步前應先將主 MYSQL服務器的要同步的數據庫拷貝到從MYSQL服務器上(如先在主MYSQL上備份數據庫,再用備份 在從MYSQL服務器上恢復)

下面我們就完成keepalived的高可用性。 keepalived是集羣管理中保證集羣高可用的一個軟件解決方案,其功 能類似於heartbeat,用來防止單點故障 keepalived是以VRRP協議爲實現基礎的,VRRP全稱Virtual Router Redundancy Protocol,即虛擬路由冗餘協議。 虛擬路由冗餘協議,可以認爲是實現路由器高可用的協議,即 將N臺提供相同功能的路由器組成一個路由器組,這個組裏面有一個master和多個backup,master上面有一個 對外提供服務的vip,master會發組播(組播地址爲224.0.0.18),當backup收不到vrrp包時就認爲master宕掉 了,這時就需要根據VRRP的優先級來選舉一個backup當master。這樣的話就可以保證路由器的高可用了。 keepalived主要有三個模塊,分別是core 、check和vrrp。core模塊爲keepalived的核心,負責主進程的啓動、 維護以及全局配置文件的加載和解析。check負責健康檢查,包括常見的各種檢查方式。vrrp模塊是來實現 VRRP協議的。
二、keepalived的安裝配置
在master1和master2上安裝軟件包keepalived 安裝keepalived軟件包與服務控制 在編譯安裝Keepalived之前,必須先安裝內核開發包kernel-devel以及openssl-devel、popt-devel等支持庫。
在兩臺master上進行如下操作

[root@mysql ~]# wget https://www.keepalived.org/software/keepalived-2.0.20.tar.gz 
[root@mysql ~]# yum -y install kernel-devel openssl-devel popt-devel 
[root@mysql ~]# tar zxf keepalived-2.0.20.tar.gz 
[root@mysql ~]# cd keepalived-2.0.20/
[root@mysql keepalived-2.0.20]# ./configure --prefix=/ && make && make install 

注意:如不知道keepalived需要哪些依賴包,可到下載後的源碼解壓目錄下查看INSTALL 文件內容, 執行make install操作之後,會自動生成/etc/init.d/keepalived腳本文件,但還需要手動添加爲系統服務,這樣就可以使用 service、chkconfig工具來對keepalived服務程序進行管理了。
修改Keepalived的配置文件 :

配置區域含義說明:
global_defs:主要是配置故障發生時的通知對象以及 機器標識。
vrrp_instance:用來定義對外提供服務的VIP區域及其相關屬性。
virtual_server:虛擬服務器定義

#master1上修改

[root@mysql ~]# vim  /etc/keepalived/keepalived.conf 
! Configuration File for keepalived

global_defs {
   router_id mysql-1
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 100
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.171.200
    }
}

virtual_server 192.168.171.200 3306 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 60
    protocol TCP

    real_server 192.168.171.135 3306 {
        weight 1
        notify_down /etc/keepalived/bin/mysql.sh
        TCP_CHECK {
                connect_port 3306
                connect_timeout 3
                retry 3
                delay_before_retry 3

        }
    }
}
[root@mysql /]# systemctl start keepalived
#將master1配置好的文件複製給master,稍加修改即可
[root@mysql /]# scp /etc/keepalived/keepalived.conf [email protected]:/etc/keepalived/
! Configuration File for keepalived

global_defs {
   router_id mysql-2
}

vrrp_instance VI_1 {
    state BACKUP
    interface ens33
    virtual_router_id 51
    priority 50
    advert_int 1
    nopreempt
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    virtual_ipaddress {
        192.168.171.200
    }
}

virtual_server 192.168.171.200 3306 {
    delay_loop 6
    lb_algo rr
    lb_kind DR
    persistence_timeout 60
    protocol TCP

    real_server 192.168.171.145 3306 {
        weight 1
        notify_down /etc/keepalived/bin/mysql.sh
        TCP_CHECK {
                connect_port 3306
                connect_timeout 3
                retry 3
                delay_before_retry 3

        }
   }
}
[root@mysql ~]# systemctl start keepalived
在兩臺master上進行如下操作:

[root@mysql ~]# mkdir /etc/keepalived/bin
[root@mysql ~]# vim /etc/keepalived/bin/mysql.sh
#!/bin/bash
pkill keepalived
#賦予執行權限
[root@mysql ~]# chmod +x /etc/keepalived/bin/mysql.sh 

測試 在master1和master2分別執行ip addr show dev eth0命令查看master1和 master2對VIP(羣集虛擬IP)的控制權。
master1上:
在這裏插入圖片描述
master2上:
在這裏插入圖片描述
對比兩個圖可以發現,VIP地址在master1上
停止MySQL服務,看keepalived健康檢查程序是 否會觸發我們編寫的腳本 停止master1主機的mysql服務
master1:
在這裏插入圖片描述
master2:
在這裏插入圖片描述

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