Mysql雙主加Keepalived+讀寫分離

1、MySQL於keepalived簡介**

前言:mysql

在企業中,數據庫高可用一直是企業的重中之重,中小企業不少都是使用mysql主從方案,一主多從,讀寫分離等,可是單主存在單點故障,從庫切換成主庫須要做改動。所以,若是是雙主或者多主,就會增長mysql入口,增長高可用。不過多主須要考慮自增加ID問題,這個須要特別設置配置文件,好比雙主,可使用奇偶,總之,主之間設置自增加ID相互不衝突就能完美解決自增加ID衝突問題。ios

1.一、MySQL**

1.1.一、MySQL主從複製原理

複製分紅三步:web

\1. master將改變記錄到二進制日誌(binary log)中(這些記錄叫作二進制日誌事件,binary log events);sql

\2. slave將master的binary log events拷貝到它的中繼日誌(relay log);數據庫

\3. slave重作中繼日誌中的事件,將改變反映它本身的數據。vim

下圖描述了這一過程:centos

 

 

 

 

 

 

1.1.二、MySQL雙主構建思路

1.兩臺mysql均可讀寫,互爲主備,默認只使用一臺(masterA)負責數據的寫入,另外一臺(masterB)備用;bash

2.masterA是masterB的主庫,masterB又是masterA的主庫,它們互爲主從;服務器

3.兩臺主庫之間作高可用,能夠採用keepalived等方案(使用VIP對外提供服務);網絡

4.全部提供服務的從服務器與masterB進行主從同步(雙主多從);

5.建議採用高可用策略的時候,masterA或masterB均不因宕機恢復後而搶佔VIP(非搶佔模式);

這樣作能夠在必定程度上保證主庫的高可用,在一臺主庫down掉以後,能夠在極短的時間內切換到另外一臺主庫上(儘量減小主庫宕機對業務形成的影響),減小了主從同步給線上主庫帶來的壓力;

可是也有幾個不足的地方:

1.masterB可能會一直處於空閒狀態(能夠用它當從庫,負責部分查詢);

2.主庫後面提供服務的從庫要等masterB先同步完了數據後才能去masterB上去同步數據,這樣可能會形成必定程度的同步延時;

架構的簡易圖以下:

 

 

 

1.1.三、MySQL雙主和主從模式的區別

主從是對主操做數據,從會實時同步數據。反之對從操做,主不會同步數據,還有可能形成數據紊亂,致使主從失效。 主主則是不管對那一臺操做,另外一個都會同步數據。通常用做高容災方案

1.二、Keepalived介紹**

Keepalived是一個基於VRRP協議來實現的WEB 服務高可用方案,能夠利用其來避免單點故障。一個WEB服務至少會有2臺服務器運行Keepalived,一臺爲主服務器(MASTER),一臺爲備份服務器(BACKUP),可是對外表現爲一個虛擬IP,主服務器會發送特定的消息給備份服務器,當備份服務器收不到這個消息的時候,即主服務器宕機的時候,備份服務器就會接管虛擬IP,繼續提供服務,從而保證了高可用性。

1.2.一、keepalived理論工做原理

keepalived可提供vrrp以及health-check功能,能夠只用它提供雙機浮動的vip(vrrp虛擬路由功能),這樣能夠簡單實現一個雙機熱備高可用功能。

keepalived是一個相似於layer3, 4 & 5交換機制的軟件,也就是咱們平時說的第3層、第4層和第5層交換。Keepalived的做用是檢測web 服務器的狀態。 Layer3,4&5工做在IP/TCP協議棧的IP層,TCP層,及應用層,原理分別以下:

  Layer3:Keepalived使用Layer3的方式工做式時,Keepalived會按期向服務器羣中的服務器

  發送一個ICMP的數據包(既咱們平時用的Ping程序),若是發現某臺服務的IP地址沒有激活,Keepalived便報告這臺服務器失效,並將它從服務器羣中剔除,這種狀況的典型例子是某臺服務器被非法關機。Layer3的方式是以服務器的IP地址是否有效做爲服務器工做正常與否的標準。在本文中將採用這種方式。

  Layer4:若是您理解了Layer3的方式,Layer4就容易了。Layer4主要以TCP端口的狀態來決定服務器工做正常與否。如web server的服務端口通常是80,若是Keepalived檢測到80端口沒有啓動,則Keepalived將把這臺服務器從服務器羣中剔除。

  Layer5:Layer5就是工做在具體的應用層了,比Layer3,Layer4要複雜一點,在網絡上佔用的帶寬也要大一些。Keepalived將根據用戶的設定檢查服務器程序的運行是否正常,若是與用戶的設定不相符,則Keepalived將把服務器從服務器羣中剔除。

vip即虛擬ip,是附在主機網卡上的,即對主機網卡進行虛擬,此IP仍然是佔用了此網段的某個IP。

1.2.二、keepalived高可用故障切換轉移原理

Keepalived高可用服務對之間的故障切換轉移,是經過 VRRP (Virtual Router Redundancy Protocol ,虛擬路由器冗餘協議)來實現的。

 

核心:

  在 Keepalived服務正常工做時,主 Master節點會不斷地向備節點發送(多播的方式)心跳消息,用以告訴備Backup節點本身還活看,當主 Master節點發生故障時,就沒法發送心跳消息,備節點也就所以沒法繼續檢測到來自主 Master節點的心跳了,因而調用自身的接管程序,接管主Master節點的 IP資源及服務。而當主 Master節點恢復時,備Backup節點又會釋放主節點故障時自身接管的IP資源及服務,恢復到原來的備用角色。

VRRP ,全 稱 Virtual Router Redundancy Protocol ,中文名爲虛擬路由冗餘協議 ,VRRP的出現就是爲了解決靜態踣甶的單點故障問題,VRRP是經過一種競選機制來將路由的任務交給某臺VRRP路由器的。

1.三、目的:

解決mysql數據庫Master-Slave 單點故障問題。

1.3,一、實現方式:

\1. Master-Master Replication 實現數據同步。

2.經過keepalived虛擬IP 從網絡層實現單點故障時IP自動切換,從而實現高可用。

3.經過keepalived配置實現read讀指向Slave節點,實現讀寫分離。

 

缺點:根據線上實際應用狀況,只考慮單點網絡故障及機器設備故障時虛擬ip自動切換(只切換一次)。不考慮mysql服務異常等狀況,數據庫異常可經過nagios等監控,防止屢次來回切換,形成數據混亂!且故障節點恢復時,要人工操做及注意步驟。

 

1.3.二、MySQL雙主讀寫分離模式

一、使用兩個MySQL數據庫db01,db02,互爲Master和Slave,即:

一邊db01做爲db02的master,一旦有數據寫向db01時,db02定時從db01更新

另外一邊db02也做爲db01的master,一旦有數據寫向db02時,db01也定時從db02得到更新

(這不會致使循環,MySQL Slave默認不會記錄Master同步過來的變化)

二、但從AppServer的角度來講,同時只有一個結點db01扮演Master,另一個結點db02扮演Slave,不能同時兩個結點扮演Master。即AppSever老是把write操做分配某個數據庫(db01),除非db01 failed,被切換。

三、若是扮演Slave的數據庫結點db02 Failed了:

a)此時appServer要可以把全部的read,write分配給db01,read操做再也不指向db02

b)一旦db02恢復過來後,繼續充當Slave角色,並告訴AppServer能夠將read分配給它了.

四、若是扮演Master的數據庫結點db01 Failed了

a)此時appServer要可以把全部的寫操做從db01切換分配給db02,也就是切換Master由db02充當

b)db01恢復過來後,充當Slave的角色,Master由db02繼續扮演。

測試環境:

服務器:

DB1:192.168.25.3一、centos7.六、mysql5.七、keepalived、hostname:DB1

DB2:192.168.25.3二、centos7.六、mysql5.七、keepalived、hostname:DB2

Slave1:192.168.25.3四、cenots7.六、mysql5.七、hostname:slave

VIP:192.168.25.200(虛擬)

遠程客戶端:192.168.25.35(用來調用vip測試)

步驟

 

二:實現兩臺MySQL主主同步

2.一、安裝MySQL

DB一、DB2兩臺服務器分別安裝MySQL,這兩臺均已安裝過程省略

2.二、修改MySQL配置文件

分別修改配置文件,在/etc/my.cnf文件中得[mysqld]段加配置信息

 DB1:
 
 [root@DB1 ~]# vim /etc/my.cnf
 
 server-id=1
 
 log-bin=mysql-bin
 
 relay-log=mysql-relay-bin
 
 replicate-wild-ignore-table=mysql.%
 
 replicate-wild-ignore-table=test.%
 
 replicate-wild-ignore-table=information_schema.%
 
 
 
 auto-increment-increment = 2
 
 auto-increment-offset = 1
 
 slave-skip-errors = all

解釋:

server-id=1(節點標識,每臺的server-id不能養,必須全局惟一)

log-bin=mysql-bin(開啓binlog日誌,用於主從數據複製)

relay-log=mysql-relay-bin(開啓relay-log日誌,relay-log日誌記錄的是從服務器I/O 線程將主服務器的二進制日誌讀取過來記錄到從服務器本地文件,而後SQL線程會讀取relay-log日誌的內容並應用到從服務器)

replicate-wild-ignore-table=mysql.%(複製過濾選項)

auto-increment-increment = 2(字段一次遞增多少)

auto-increment-offset = 1(自增字段的起始值:一、三、五、七、等奇數)

保存重啓,使其配置生效

 [root@DB1 ~]# service mysqld restart
 
 Shutting down MySQL.. SUCCESS!
 
 Starting MySQL. SUCCESS!
 
 DB2:
 
 [root@DB2 ~]# vim /etc/my.cnf
 
 server-id=2
 
 log-bin=mysql-bin
 
 relay-log=mysql-relay-bin
 
 replicate-wild-ignore-table=mysql.%
 
 replicate-wild-ignore-table=test.%
 
 replicate-wild-ignore-table=information_schema.%
 
 
 
 auto-increment-increment = 2
 
 auto-increment-offset = 2
 
 slave-skip-errors = all
 
 保存重啓,使其配置生效
 
 [root@DB2 ~]# service mysqld restart
 
 Shutting down MySQL.. SUCCESS!
 
 Starting MySQL. SUCCESS!
 
 Slave1:
 
 [root@slave1 ~]# vim /etc/my.cnf
 
 [mysqld]
 
 
 
 server-id=3
 
 log-bin=mysql-bin
 
 log-slave-updates
 
 relay-log=mysql-relay-bin
 
 replicate-wild-ignore-table=mysql.%
 
 replicate-wild-ignore-table=test.%
 
 replicate-wild-ignore-table=information_schema.%
 
 
 
 auto-increment-increment = 2
 
 auto-increment-offset = 3
 
 slave-skip-errors = all

 

#注:在執行主主互備以前要保證兩臺服務器上MySQL數據一致

2.三、MySQL配置DB一、DB2主主模式

2.3.一、先查看log bin日誌和pos位置

DB1:

 [root@DB1 ~]# mysql -uroot -pwww.123
 
 mysql> show master status;

 

 

 

 

 DB2:
 
 [root@DB2 ~]# mysql -uroot -pwww.123
 
 mysql> show master status;

2.3.二、DB一、DB2互相提高訪問權限

 

DB1:

在DB1的數據庫建立DB2的複製用戶並受權

 mysql> grant replication slave on *.* to 'cproot'@'192.168.25.32' identified by 'cpwww.123';
 
 Query OK, 0 rows affected, 1 warning (0.02 sec)
 
 刷新並查看log bin日誌和pos位置
 
 mysql> flush privileges;
 
 Query OK, 0 rows affected (0.02 sec)
 
 
 
 mysql> show master status;

 

DB2:

 mysql> grant replication slave on *.* to 'cproot'@'192.168.25.31'identified by 'cpwww.123'; 
 
 Query OK, 0 rows affected, 1 warning (0.02 sec)
 
 mysql> flush privileges;
 
 Query OK, 0 rows affected (0.01 sec)
 
 mysql> show master status;

 

在DB2的數據庫中將DB1設置爲本身得主服務器

 mysql> change master to master_host='192.168.25.31',master_user='cproot',master_password='cpwww.123',master_log_file='mysql-bin.000001',master_log_pos=613;
 
 Query OK, 0 rows affected, 2 warnings (0.11 sec)

 

 

 

DB1:

在DB1的數據庫中將DB2設置爲本身的主服務器

 mysql> change master to master_host='192.168.25.32',master_user='cproot',master_password='cpwww.123',master_log_file='mysql-bin.000001',master_log_pos=613;
 
 Query OK, 0 rows affected, 2 warnings (0.11 sec)

 

 

 

分別查看DB一、DB2服務器狀態

DB2:

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G;

 

 

若是slave_io不是yes是  這樣得話那就有三種可能錯誤須要排查

1,網絡不通

2,密碼不正確

3,Pos不對

4,防火牆沒關

我此次遇到的就是防火牆沒關,而且用service iptables stop還很差使,我是這樣解決的

先看提示得錯誤

提示用/bin/systemctl stop iptables.service這樣得方式去關閉,這裏須要先安裝iptables.services而後在關閉防火牆

[root@DB2 data]# yum -y install iptables-services

[root@DB2 ~]# systemctl stop iptables

DB1:

mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G;

 

到此主主同步配置完成,查看狀態slave_io和slave_sql都是yes說明主主同步成功

2.四、測試主主同步

在DB1上建立一個數據庫one,而後在DB2上查看是否同步成功

注意:在建立以前最好再次重啓一下MySQL數據庫否則可能會同步不成功

DB1:

mysql> create database one;

Query OK, 1 row affected (0.02 sec)

 

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| one                |

| performance_schema |

| sys                |

+--------------------+

5 rows in set (0.00 sec)

 

DB2:

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| one                |

| performance_schema |

| sys                |

+--------------------+

5 rows in set (0.00 sec)

在DB2把新建的數據庫one刪除掉,看看DB1上是否還存在

mysql> drop database one;

Query OK, 0 rows affected (0.01 sec)

 

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| performance_schema |

| sys                |

+--------------------+

4 rows in set (0.00 sec)

DB1:

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| performance_schema |

| sys                |

+--------------------+

4 rows in set (0.00 sec)

 

雙向操做沒問題,均可以同步成功,主主已經搭建成功

2.五、配置slave從服務器

DB1

在DB1的數據庫建立slave1的複製用戶並受權

mysql> grant replication slave on *.* to 'cproot'@'192.168.25.34' identified by 'cpwww.123';

Query OK, 0 rows affected, 1 warning (0.01 sec)

 

mysql> flush privileges;

Query OK, 0 rows affected (0.01 sec)

 

mysql> show master status;

在slave裏的數據庫裏把DB1設置爲主服務器

Slave1:

mysql> change master to master_host='192.168.25.31',master_user='cproot',master_password='cpwww.123',master_log_file='mysql-bin.000003',master_log_pos=774;

Query OK, 0 rows affected, 2 warnings (0.05 sec)

mysql> start slave;

Query OK, 0 rows affected (0.01 sec)

mysql> show slave status\G

 

 

查看狀態slave_io和slave_sql都是yes,這裏主從就同步成功了

測試在DB1數據庫新建two

DB1:

mysql> create database two;

Query OK, 1 row affected (0.02 sec)

 

mysql> show databases;

Slave1:

在slave1上查看是否同步

 

 

主從同步成功

同步錯誤問題總結:若是slave_io不是yes多看看防火牆是否關閉,還有就是受權是輸入得帳號密碼和pos是否輸入正確了

3、安裝並配置keepalived

3.一、兩臺都須要安裝keepalived

DB一、DB2:

安裝keepalived並將其配置成系統服務。DB1和DB2都要進行以下操做:

[root@DB1 ~]# yum install -y openssl-devel

[root@DB1 ~]# cd /usr/local/src/

[root@DB1 src]# wget http://www.keepalived.org/software/keepalived-1.3.5.tar.gz

[root@DB1 src]# tar -zxvf keepalived-1.3.5.tar.gz 

[root@DB1 src]# cd keepalived-1.3.5

[root@DB1 keepalived-1.3.5]# ./configure --prefix=/usr/local/keepalived

執行這個後會發如今最後會報錯configure: error: libnfnetlink headers missing(沒有的話忽略)

而後執行

[root@DB1 keepalived-1.3.5]# yum -y install libnfnetlink-devel

再從新執行./configure

[root@DB1 keepalived-1.3.5]# ./configure --prefix=/usr/local/keepalived

[root@DB1 keepalived-1.3.5]# make && make install

在執行這一條的時候若是遇到這樣的錯誤多是沒有依賴包

 

 

 

解決方法:

[root@DB2 keepalived-1.3.5]# yum -y install libnl libnl-devel libnfnetlink-devel openssl-devel

(最好是在安裝以前所有執行這條語句以防發生錯誤)

[root@DB1 keepalived-1.3.5]# cp /usr/local/src/keepalived-1.3.5/keepalived/etc/init.d/keepalived /etc/rc.d/init.d/

[root@DB1 keepalived-1.3.5]# cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/

[root@DB1 keepalived-1.3.5]# mkdir /etc/keepalived/

[root@DB1 keepalived-1.3.5]# cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/

[root@DB1 keepalived-1.3.5]# cp /usr/local/keepalived/sbin/keepalived /usr/sbin/

[root@DB1 keepalived-1.3.5]# echo "/etc/init.d/keepalived start" >>/etc/rc.local 

 

3.二、DB1上的keepalived.conf配置

DB1:

[root@DB1 ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak

[root@DB1 ~]# vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

​       

global_defs {

notification_email {

ops@wangshibo.cn

tech@wangshibo.cn

}

​       

notification_email_from ops@wangshibo.cn

smtp_server 127.0.0.1 

smtp_connect_timeout 30

router_id MASTER-HA

}

​       

vrrp_script chk_mysql_port {     #檢測mysql服務是否在運行。有不少方式,好比進程,用腳本檢測等等

​    script "/opt/chk_mysql.sh"   #這裏經過腳本監測

​    interval 2                   #腳本執行間隔,每2s檢測一次

​    weight -5                    #腳本結果致使的優先級變動,檢測失敗(腳本返回非0)則優先級 -5

​    fall 2                    #檢測連續2次失敗纔算肯定是真失敗。會用weight減小優先級(1-255之間)

​    rise 1                    #檢測1次成功就算成功。但不修改優先級

}

​       

vrrp_instance VI_1 {

​    state BACKUP 

​    interface ens160      #指定虛擬ip的網卡接口

​    mcast_src_ip 192.168.25.31

​    virtual_router_id 79    #路由器標識,MASTER和BACKUP必須是一致的

​    priority 100            #定義優先級,數字越大,優先級越高,在同一個vrrp_instance下,MASTER的優先級必須大於BACKUP的優先級。這樣MASTER故障恢復後,就能夠將VIP資源再次搶回來 

  \#  nopreempt

​    advert_int 1         

​    authentication {   

​        auth_type PASS 

​        auth_pass 1111     

​    }

​    virtual_ipaddress {    

​        192.168.25.200

​    }

​      

track_script {               

   chk_mysql_port             

}

}

編寫切換腳本。KeepAlived作心跳檢測,若是Master的MySQL服務掛了(3306端口掛了),那麼它就會選擇自殺。Slave的KeepAlived經過心跳檢測發現這個狀況,就會將VIP的請求接管

[root@DB1 ~]# vim /opt/chk_mysql.sh

\#!/bin/bash

counter=$(netstat -na|grep "LISTEN"|grep "3306"|wc -l)

if [ "${counter}" -eq 0 ]; then

​	/etc/init.d/keepalived stop

fi

[root@DB1 ~]# chmod 755 /opt/chk_mysql.sh 

[root@DB1 ~]# /etc/init.d/keepalived start

3.二、DB2上配置keepalived,DB2服務器上的keepalived.conf文件只修改priority爲9九、nopreempt不設置

DB2:

[root@DB2 ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak

[root@DB2 ~]# >/etc/keepalived/keepalived.conf

[root@DB2 ~]# vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

​       

global_defs {

notification_email {

ops@qq.com

tech@qq.com

}

​       

notification_email_from ops@wangshibo.cn

smtp_server 127.0.0.1 

smtp_connect_timeout 30

router_id MASTER-HA

}

​       

vrrp_script chk_mysql_port {

​    script "/opt/chk_mysql.sh"

​    interval 2            

​    weight -5                 

​    fall 2                 

​    rise 1               

}

​       

vrrp_instance VI_1 {

​    state BACKUP

​    interface ens160 

​    mcast_src_ip 192.168.25.32

​    virtual_router_id 79    

​    priority 99          

​    advert_int 1         

​    authentication {   

​        auth_type PASS 

​        auth_pass 1111     

​    }

​    virtual_ipaddress {    

​       192.168.25.200

​    }

​      

track_script {               

   chk_mysql_port             

}

}

[root@DB2 ~]# cat /opt/chk_mysql.sh 

\#!/bin/bash

counter=$(netstat -na|grep "LISTEN"|grep "3306"|wc -l)

if [ "${counter}" -eq 0 ]; then

​    /etc/init.d/keepalived stop

fi

[root@DB2 ~]# chmod 755 /opt/chk_mysql.sh 

[root@DB2 ~]# /etc/init.d/keepalived start

####經常使用的指令說明

(1)notification_email:收件箱

(2)notification_email_from:發件箱

(3)vrrp_mcast_group4:VRRP多播地址,必須爲D類地址,便可用IP範圍爲224.0.0.0~239.255.255.255

(4)script:自定義檢查腳本路徑

(5)interval:自定義檢查腳本的執行時間間隔,單位爲秒

(6)vrrp_instance:配置虛擬路由器實例

(7)state:MASTER或BACKUP,當前節點在此虛擬路由器上的初始狀態,只能有一個爲MASTER,其他的都應該爲BACKUP,此處都須要配置爲BACKUP

(8)nopreempt:定義工做模式爲非搶佔模式,默認爲搶佔模式

(9)preempt_delay:搶佔模式下,節點上線後觸發新選舉操做的延遲時長,單位爲秒

(10)interface:綁定當前虛擬路由器使用的物理接口

(11)virtual_router_id:當前虛擬路由器的惟一標識,取值範圍爲0~255,兩個節點必須一致

(12)priority:當前主機在此虛擬路由器中的優先級,取值範圍爲0~255

(13)advert_int:VRRP通告心跳信息和優先級信息的時間間隔,單位爲秒

(14)auth_type:認證類型

(15)auth_pass:認證密碼,兩個節點必須一致

(16)virtual_ipaddress:VIP地址

(17)可經過命令# man keepalived.conf查看keepalived.conf配置文件的詳細幫助文檔

 

如今查看一下vip在那一臺機器,在DB1上是正確的

在DB1下是正確的

3.三、測試:

首先先測試vip能不能正常切換

在DB1上操做關閉MySQL,看看能不能飄移到DB2上,而後在啓動能不能正常飄移到DB1上

DB1:

[root@DB1 ~]# /etc/init.d/mysqld stop

[root@DB1 ~]# ip addr

查看得知,關閉msyql後vip已經沒了

 

 

DB2:

[root@DB2 ~]# ip addr

此時VIP已經飄移到DB2上

 

 

啓動DB1的MySQL和keepalived

注意:先啓動MySQL在啓動keepalived,由於腳本里MySQL沒有啓動的話keepalived啓動後會再次關閉的

DB1:

[root@DB1 ~]# /etc/init.d/mysqld start

Starting MySQL. SUCCESS! 

[root@DB1 ~]# /etc/init.d/keepalived start

Starting keepalived (via systemctl):                       [  肯定  ]

[root@DB1 ~]# ip addr

此時VIP已經成功飄移回DB1上

 

 

3.四、故障轉移高可用測試

首先在DB1和DB2上都要受權容許root用戶遠程登陸,用於在客戶端登陸測試!

並在兩臺機器上設置IPtables防火牆規則

DB1:

受權:

[root@DB1 ~]# mysql -uroot -pwww.123

mysql> grant all on *.* to root@'192.168.25.%' identified by "www.123";

Query OK, 0 rows affected, 1 warning (0.02 sec)

 

mysql> flush privileges;

Query OK, 0 rows affected (0.01 sec)

添加防火牆規則:

[root@DB1 ~]# vim /etc/sysconfig/iptables

-A INPUT -s 192.168.0.0/24 -d 224.0.0.18 -j ACCEPT       #容許組播地址通訊

-A INPUT -s 192.168.0.0/24 -p vrrp -j ACCEPT             #容許VRRP(虛擬路由器冗餘協)通訊

-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT    #開放mysql的3306端口

[root@DB1 ~]# systemctl start iptables

DB2:

[root@DB2 ~]# mysql -uroot -pwww.123

mysql>  grant all on *.* to root@'192.168.25.%' identified by "www.123";

Query OK, 0 rows affected, 1 warning (0.01 sec)

 

mysql> flush privileges;

Query OK, 0 rows affected (0.01 sec)

[root@DB2 ~]# vim /etc/sysconfig/iptables

-A INPUT -s 192.168.0.0/24 -d 224.0.0.18 -j ACCEPT       #容許組播地址通訊

-A INPUT -s 192.168.0.0/24 -p vrrp -j ACCEPT             #容許VRRP(虛擬路由器冗餘協)通訊

-A INPUT -m state --state NEW -m tcp -p tcp --dport 3306 -j ACCEPT    #開放mysql的3306端口

[root@DB2 ~]# systemctl start iptables

注意:若是在啓動防火牆報錯(沒有文件或目錄時在防火牆規則里加一條

「IPTABLES -P INPUT ACCEPT」而後保存退出會生成/etc/sysconfig/下的iptables配置文件:使用service iptables save以後再從新啓動iptables就能夠了)

Monitor:

經過MySQL客戶端經過VIP鏈接,看是否能夠鏈接成功。(鏈接是須要提早在服務器端受權的)

[root@monitor ~]# mysql -h 192.168.25.200 -uroot -pwww.123

 

 

建立一個數據庫,而後在庫中建立一個表,並插入數據。

mysql> show variables like "%hostname%";      (這條語句可查看當前VIP在那臺服務器上)

 

 

mysql> show databases;

 

 

mysql> create database one;

Query OK, 1 row affected (0.01 sec)

 

mysql> use one;

Database changed

mysql> create table test_table(id int, name varchar(32));

Query OK, 0 rows affected (0.08 sec)

 

mysql> show tables;

+----------------+

| Tables_in_one |

+----------------+

| one_table     |

+----------------+

1 row in set (0.00 sec)

mysql> insert into one_table(id,name) values(1,'glt');

Query OK, 1 row affected (0.02 sec)

驗證數據:

分別查看DB1和DB2的數據同步狀況

DB1:

[root@DB1 ~]# mysql -uroot -pwww.123

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| performance_schema |

| sys                |

| one               |

+--------------------+

5 rows in set (0.00 sec)

mysql> use one;

Database changed

mysql> show tables;

+----------------+

| Tables_in_one |

+----------------+

| one_table     |

+----------------+

1 row in set (0.00 sec)

mysql> select * from one_table;

+------+------+

| id   | name |

+------+------+

|    1 | glt  |

+------+------+

1 row in set (0.00 sec)

 

DB2:

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| one                |

| performance_schema |

| sys                |

+--------------------+

5 rows in set (0.00 sec)

mysql> use one

Database changed

mysql> show tables;

+---------------+

| Tables_in_one |

+---------------+

| one_table     |

+---------------+

1 row in set (0.00 sec)

 

mysql> select * from one_table

​    -> ;

+------+------+

| id   | name |

+------+------+

|    1 | glt  |

+------+------+

1 row in set (0.00 sec)

 

3.5故障測試:

中止DB1中的MySQL,經過VIP登陸查看當前的在那一臺服務器上並繼續在one庫上插入數據,而後在重啓DB1看是否能夠同步數據。

DB1:

[root@DB1 ~]# service mysqld stop

Shutting down MySQL............ SUCCESS!

Monitor:

[root@monitor ~]# mysql -h 192.168.25.200 -uroot -pwww.123

mysql> show variables like "%hostname%";

+---------------+-------+

| Variable_name | Value |

+---------------+-------+

| hostname      | DB2   |

+---------------+-------+

1 row in set (0.00 sec)

當前鏈接的是DB2,故障自動切換成功。

mysql> use one;

Database changed

mysql> insert into one_table(id,name)values(2,'hhh');

Query OK, 1 row affected (0.03 sec)

 

mysql> select * from one_table;

+------+------+

| id   | name |

+------+------+

|    1 | glt  |

|    2 | hhh  |

+------+------+

2 rows in set (0.00 sec)

啓動DB1查看同步狀況

DB1:

[root@DB1 ~]# /etc/init.d/mysqld start

Starting MySQL. SUCCESS! 

[root@DB1 ~]# mysql -uroot -pwww.123

mysql> show databases;

+--------------------+

| Database           |

+--------------------+

| information_schema |

| mysql              |

| one                |

| performance_schema |

| sys                |

+--------------------+

5 rows in set (0.00 sec)

mysql> use one;

Reading table information for completion of table and column names

You can turn off this feature to get a quicker startup with -A

 

Database changed

mysql> show tables;

+---------------+

| Tables_in_one |

+---------------+

| one_table     |

+---------------+

1 row in set (0.00 sec)

 

mysql> select * from one_table

​    -> ;

+------+------+

| id   | name |

+------+------+

|    1 | glt  |

|    2 | hhh  |

+------+------+

2 rows in set (0.00 sec)

數據同步成功

到此,雙機熱備所有完成

4、增長讀寫分離配置**

在以前的基礎上改動如下環境;以下:

192.168.25.31 MySQL+keepalived

192.168.25.32 MySQL+keepalived

寫入VIP:192.168.25.200(31主,32從)

讀取VIP:192.168.25.100(32主,31從)

4.一、MySQL配置文件增長一條配置(兩臺都要作)

[root@DB1 ~]# cp /etc/my.cnf /etc/my.cnf.bak

[root@DB1 ~]# vim /etc/my.cnf

binlog_format=mixed

 

4.二、配置keepalived

DB1:

[root@DB1 ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak2

[root@DB1 ~]# vim /etc/keepalived/keepalived.conf

修改以下

! Configuration File for keepalived

​       

global_defs {

notification_email {

ops@wangshibo.cn

tech@wangshibo.cn

}

​       

notification_email_from ops@wangshibo.cn

smtp_server 127.0.0.1 

smtp_connect_timeout 30

router_id MASTER-HA

}

​       

vrrp_script chk_mysql_port {     #檢測mysql服務是否在運行。有不少方式,好比進程,用腳本檢測等等

​    script "/opt/chk_mysql.sh"   #這裏經過腳本監測

​    interval 2                   #腳本執行間隔,每2s檢測一次

​    weight -5                    #腳本結果致使的優先級變動,檢測失敗(腳本返回非0)則優先級 -5

​    fall 2                    #檢測連續2次失敗纔算肯定是真失敗。會用weight減小優先級(1-255之間)

​    rise 1                    #檢測1次成功就算成功。但不修改優先級

}

​       

vrrp_instance VI_1 {

​    state BACKUP 

​    interface ens160      #指定虛擬ip的網卡接口

​    mcast_src_ip 192.168.25.31

​    virtual_router_id 79    #路由器標識,MASTER和BACKUP必須是一致的

​    priority 100            #定義優先級,數字越大,優先級越高,在同一個vrrp_instance下,MASTER的優先級必須大於BACKUP的優先級。這樣MASTER故障恢復後,就能夠將VIP資源再次搶回來 

​    nopreempt #不主動搶佔資源,只有在優先級高的機器上設置便可,優先級低的機器不設置

​    advert_int 1         

​    authentication {   

​        auth_type PASS 

​        auth_pass 1111     

​    }

​    virtual_ipaddress {    

​        192.168.25.200  #寫入虛擬VIP

​    }

}

​      

track_script {               

   chk_mysql_port             

vrrp_instance VI_2{

​	state BACKUP #另外一臺配置爲MASTER

​	interface ens160

​	virtual_router_id 44 #注意id和上面的不一樣(另外一臺和這個ID同樣)

​	priority 90 #優先級,另外一臺爲100

​	advert_int 1

​	authentication {

​	auth_type pass

​	auth_pass 1111

​	}

​	virtual_ipaddress {

​	192.168.25.100 #讀取虛擬VIP

​	}

}

}

 

 

DB2:

##注意:在這次的環境中不知道爲何DB2的keepalived必需要在/usr/local/keepalived/var/run/這個路徑下把keepalived.pid文件放進去,否則啓動不了,而且每啓動一次這個文件就會消失一次,須要再次拷貝過去,原keepalived.pid文件在/run/keepalived.pid

[root@DB2 ~]# cp /run/keepalived.pid /usr/local/keepalived/var/run/**

 

[root@DB2 ~]# cp /etc/keepalived/keepalived.conf /etc/keepalived/keepalived.conf.bak2

[root@DB2 ~]# vim /etc/keepalived/keepalived.conf

! Configuration File for keepalived

​       

global_defs {

notification_email {

ops@qq.com

tech@qq.com

}

​       

notification_email_from ops@wangshibo.cn

smtp_server 127.0.0.1 

smtp_connect_timeout 30

router_id MASTER-HA

}

​       

vrrp_script chk_mysql_port {

​    script "/opt/chk_mysql.sh"

​    interval 2            

​    weight -5                 

​    fall 2                 

​    rise 1               

}

​       

vrrp_instance VI_1 {

​    state BACKUP #兩臺此處都是BACKUP

​    interface ens160 #網卡接口

​    \#mcast_src_ip 192.168.25.32

​    virtual_router_id 79    

​    priority 90          

​    advert_int 1         

​    authentication {   

​        auth_type PASS 

​        auth_pass 1111     

​    }

​    virtual_ipaddress {    

​       192.168.25.200  #寫入虛擬VIP

​    }

​      

track_script {               

   chk_mysql_port             

}

}

vrrp_instance VI_2{

​	state MASTER #用於MySQL讀

​	interface ens160 #網卡接口

​	virtual_router_id 44 #注意id和上面的不一樣(另外一臺和這個ID同樣)

​	priority 100 #優先級,另外一臺爲90

​	advert_int 1

​	authentication {

​	auth_type pass

​	auth_pass 1111

​	}

​	virtual_ipaddress {

​	192.168.25.100 #讀取虛擬VIP

​	}

}

}

 

4.三、查看當前ip是否作成了讀寫分離

DB1和DB2重啓keepalived查看此時的虛擬ip

DB1:

[root@DB1 ~]# ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

​    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

​    inet 127.0.0.1/8 scope host lo

​       valid_lft forever preferred_lft forever

​    inet6 ::1/128 scope host 

​       valid_lft forever preferred_lft forever

2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000

​    link/ether 00:50:56:9d:45:0a brd ff:ff:ff:ff:ff:ff

​    inet 192.168.25.31/24 brd 192.168.25.255 scope global noprefixroute ens160

​       valid_lft forever preferred_lft forever

​    inet 192.168.25.200/32 scope global ens160

​       valid_lft forever preferred_lft forever

​    inet6 fe80::779a:c241:de68:1ca8/64 scope link noprefixroute 

​       valid_lft forever preferred_lft forever

DB1的虛擬ip是寫入ip沒問題

 

DB2:

[root@DB2 ~]# ip addr

1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000

​    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00

​    inet 127.0.0.1/8 scope host lo

​       valid_lft forever preferred_lft forever

​    inet6 ::1/128 scope host 

​       valid_lft forever preferred_lft forever

2: ens160: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000

​    link/ether 00:50:56:9d:54:61 brd ff:ff:ff:ff:ff:ff

​    inet 192.168.25.32/24 brd 192.168.25.255 scope global noprefixroute ens160

​       valid_lft forever preferred_lft forever

​    inet 192.168.25.100/32 scope global ens160

​       valid_lft forever preferred_lft forever

​    inet6 fe80::5a60:abe2:4734:487e/64 scope link noprefixroute 

​       valid_lft forever preferred_lft forever

此時DB2的虛擬ip是讀取ip沒得問題

4.四、故障處理 (測試)

故障一:31(寫)服務器或者網絡故障,虛擬ip 200切換到32

 

一、 31服務器恢復後,不要插上網線或者修改31的iP(防止數據自動同步,致使數據污染)

二、 暫時關閉keepalive(默認開機不啓動)

三、 啓動31的mysql並停掉slave,防止32數據同步到31,同時插上網線或者修改iP爲31;

四、 檢查32的slave狀態是有主鍵衝突,若是有主鍵衝突,導出31上的數據,並作刪除;

五、 重啓32的slave,查看是否還有主鍵衝突,若是有繼續上步操做,直到32的slave狀態恢復正常;

六、 開啓31的slave並查看slave狀態,正常狀況下應該不會出現主鍵衝突,若是有主鍵衝突,導出數據並分析緣由,(根據實際狀況處理)

七、 檢查31與32服務器數據是否一致,若是數據一致,切換VIP 100(讀虛擬IP)到31,修改步驟以下:

a)修改32的keepalive配置vrrp_instance VI_2 中state狀態爲BACKUP、priority 修改成90

b)重啓32 keepalive(確保31的keepalive是關閉狀態)

c)修改31的keepalive配置vrrp_instance VI_2 中state狀態爲MASTER、priority 修改成180

d)重啓31的keepalive

e)檢查VIP 100(讀虛擬IP)是否切到31上,而且VIP 200(寫虛擬IP)應該保留在32上。

八、 線上應用測試(讀與寫)

 

故障修復後的狀態應該是:

1.192.168.25.31 mysql+keepalive

2.192.168.25.32 mysql+keepalive

3.寫入VIP:192.168.25.200(32主,31從)

4.讀取VIP:192.168.25.100(31主,32從)

 

故障2、32(讀)數據庫出現故障,VIP 100(讀虛擬IP)切到31服務器

一、修復32服務器以前應斷開網線或者修改ip(防止讀VIP自動切回)

二、關閉keepalive 因此服務器上的keepalive 最好設計成開不會自動啓動命令以下:chkconfig keepalived off

三、檢查32數據庫的slave狀態是否正常,數據庫數據同步是否正常

四、數據同步完成後啓動keepalive,檢查讀取數據的虛擬IP 100應該切回本服務器,寫數據的虛擬IP不變。

五、應用測試讀寫數據是否正常

 

故障3、兩臺數據庫服務器同時故障

一、 開啓31和32數據庫以前,先斷網線

二、 分別檢查31和32服務器的mysql更新的最新時間

三、 若是31數據比較新,先插上31的網線,使其對外提供服務。

3.1檢查讀和寫的虛擬iP是否都在31上

3.2關閉32上的keepalive,而且開啓32上msyql的salve,同步31上的數據

3.3若是同步正常啓動keepalive

3.4測試讀寫數據是否正常

四、若是32的數據比較新,就先插上32的網線,使其對外提供服務

4.1 檢查讀和寫的虛擬ip是否都在32上

4.2 關閉31上的keepalive,而且開啓31上mysql的save,開始同步32上的數據

4.3若是同步正常,啓動31的keepalive

4.4測試讀寫數據是否正常

4.5應用測試程序是否正常

相關文章
相關標籤/搜索