Mysql雙主加Keepalived+讀寫分離

来源:https://www.cnblogs.com/clllum/archive/2019/11/04/11791913.html
-Advertisement-
Play Games

一、MySQL於keepalived簡介** 前言: 在企業中,資料庫高可用一直是企業的重中之重,中小企業很多都是使用mysql主從方案,一主多從,讀寫分離等,但是單主存在單點故障,從庫切換成主庫需要作改動。因此,如果是雙主或者多主,就會增加mysql入口,增加高可用。不過多主需要考慮自增長ID問題 ...


一、MySQL於keepalived簡介**

前言:

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

1.1、MySQL**

1.1.1、MySQL主從複製原理

複製分成三步:

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

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

\3. slave重做中繼日誌中的事件,將改變反映它自己的數據。

下圖描述了這一過程:

 

 

 

 

 

 

1.1.2、MySQL雙主構建思路

1.兩台mysql都可讀寫,互為主備,預設只使用一臺(masterA)負責數據的寫入,另一臺(masterB)備用;

2.masterA是masterB的主庫,masterB又是masterA的主庫,它們互為主從;

3.兩台主庫之間做高可用,可以採用keepalived等方案(使用VIP對外提供服務);

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

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

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

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

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

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

架構的簡易圖如下:

 

 

 

1.1.3、MySQL雙主和主從模式的區別

主從是對主操作數據,從會實時同步數據。反之對從操作,主不會同步數據,還有可能造成數據紊亂,導致主從失效。 主主則是無論對那一臺操作,另一個都會同步數據。一般用作高容災方案

1.2、Keepalived介紹**

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

1.2.1、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.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.3、目的:

解決mysql資料庫Master-Slave 單點故障問題。

1.3,1、實現方式:

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

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

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

 

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

 

1.3.2、MySQL雙主讀寫分離模式

1、使用兩個MySQL資料庫db01,db02,互為Master和Slave,即:

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

另一邊db02也作為db01的master,一旦有數據寫向db02時,db01也定時從db02獲得更新

(這不會導致迴圈,MySQL Slave預設不會記錄Master同步過來的變化)

2、但從AppServer的角度來說,同時只有一個結點db01扮演Master,另外一個結點db02扮演Slave,不能同時兩個結點扮演Master。即AppSever總是把write操作分配某個資料庫(db01),除非db01 failed,被切換。

3、如果扮演Slave的資料庫結點db02 Failed了:

a)此時appServer要能夠把所有的read,write分配給db01,read操作不再指向db02

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

4、如果扮演Master的資料庫結點db01 Failed了

a)此時appServer要能夠把所有的寫操作從db01切換分配給db02,也就是切換Master由db02充當

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

測試環境:

伺服器:

DB1:192.168.25.31、centos7.6、mysql5.7、keepalived、hostname:DB1

DB2:192.168.25.32、centos7.6、mysql5.7、keepalived、hostname:DB2

Slave1:192.168.25.34、cenots7.6、mysql5.7、hostname:slave

VIP:192.168.25.200(虛擬)

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

步驟

 

二:實現兩台MySQL主主同步

2.1、安裝MySQL

DB1、DB2兩台伺服器分別安裝MySQL,這兩台均已安裝過程省略

2.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(自增欄位的起始值:1、3、5、7、等奇數)

保存重啟,使其配置生效

 [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.3、MySQL配置DB1、DB2主主模式

2.3.1、先查看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.2、DB1、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)

 

 

 

分別查看DB1、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.4、測試主主同步

在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.5、配置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是否輸入正確了

三、安裝並配置keepalived

3.1、兩台都需要安裝keepalived

DB1、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.2、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 {

[email protected]

[email protected]

}

​       

notification_email_from [email protected]

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.2、DB2上配置keepalived,DB2伺服器上的keepalived.conf文件只修改priority為99、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 {

[email protected]

[email protected]

}

​       

notification_email_from [email protected]

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.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.4、故障轉移高可用測試

首先在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)

數據同步成功

到此,雙機熱備全部完成

四、增加讀寫分離配置**

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

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.1、MySQL配置文件增加一條配置(兩台都要做)

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

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

binlog_format=mixed

 

4.2、配置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 {

[email protected]

[email protected]

}

​       

notification_email_from [email protected]

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

​	}

}

}

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在註冊表中找到 HKEY_CURRENT_USER\Software 選中其中的類似下列文件名的文件 HKEY_CURRENT_USER\Software\{d58cb4b1-47f3-45cb-a209-f298d0c3f756} HKEY_CURRENT_USER\Software\{FBC48 ...
  • 許多時候當要使用Mysql時,會遇到如下情況: 1. 信息比較重要,希望通信被加密。2. 一些埠,比如3306埠,被路由器禁用。 對第一個問題的一個比較直接的解決辦法就是更改mysql的代碼,或者是使用一些證書,不過這種辦法顯然不是很簡單。 這裡要介紹另外一種方法,就是利用SSH通道來連接遠程的 ...
  • [root@test153 ~]# /usr/local/mysql/bin/mysqld --initialize --user=mysql --basedir=/usr/local/mysql --datadir=/data/mysql_data1 /usr/local/mysql/bin/my ...
  • 創建表空間及用戶CREATE TABLESPACE OracleDBFDATAFILE 'D:\app\zhoulx\oradata\bdc\OracleDBF.DBF' SIZE 100M AUTOEXTEND ON NEXT 20M MAXSIZE UNLIMITED -- 這裡是你設置資料庫存 ...
  • 1.select * from SYS_DICT as of timestamp to_timestamp('2019-11-05 10:00:00','yyyy-mm-dd hh24:mi:ss'); 時間點在刪除數據之前,又儘量精確 sys_dict 是表名 2.insert into SYS_ ...
  • 阿裡開發手冊的描述,禁止多表join: 手冊上寫著【強制】,相信很多同學項目裡面的代碼都不滿足這個要求。 但是關鍵問題是:不用join,這SQL究竟要怎麼寫?! 分解關聯查詢 即對每個要關聯的表進行單表查詢,然後將結果在應用程式中進行關聯。下麵的這個查詢: 可以分解成下麵這些查詢來代替: 但是該方案 ...
  • 基本環境 elasticsearch版本:6.3.1 客戶端環境:kibana 6.3.4、Java8應用程式模塊。 其中kibana主要用於數據查詢診斷和查閱日誌,Java8為主要的客戶端,數據插入和查詢都是由Java實現的。 案例介紹 使用elasticsearch存儲訂單的主要信息,docum ...
  • 前幾天,看到一個群友用WITH ROLLUP運算符。由於自個兒沒用過,看到概念及結果都雲里霧裡的,所以突然來了興趣對生成結果測了一番。 一、概念: WITH CUBE:生成的結果集顯示了所選列中值的所有組合的聚合。 WITH ROLLUP:生成的結果集顯示了所選列中值的某一層次結構的聚合。 GROU ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...