Keepalived原理:
Keepalived 的原理主要基于虛擬路由冗余協議(VRRP,Virtual Router Redundancy Protocol)、健康檢查機制和負載均衡機制,以下為你詳細介紹:
- VRRP 協議實現高可用:VRRP 是 Keepalived 實現高可用性的核心協議。在一個 VRRP 組中,有多臺運行 Keepalived 的服務器,其中一臺被選舉為主(Master)服務器,其他的作為備(Backup)服務器。
- 選舉機制:通過比較設備的優先級(Priority)來確定 Master 。優先級取值范圍是 1 到 254,數值越大優先級越高。默認情況下,優先級最高的設備會成為 Master 。當優先級相同時,IP 地址較大的設備會成為 Master 。Master 服務器承擔實際的網絡流量轉發任務,而 Backup 服務器則處于監聽狀態。
- 心跳檢測:Master 服務器會定期(默認每隔 1 秒)向 Backup 服務器發送 VRRP 通告報文,以告知 Backup 自己的存活狀態。Backup 服務器接收到通告報文后,會重置定時器。如果 Backup 服務器在一定時間(通常是幾個通告間隔時間)內沒有收到 Master 發送的通告報文,就會認為 Master 服務器出現故障,然后 Backup 服務器中優先級最高的設備會升級為 Master ,接管原來 Master 的工作,繼續處理網絡流量。
- 狀態切換:當原來的 Master 服務器恢復正常后,它會重新參與選舉。如果其優先級高于當前的 Master 服務器,那么它會重新成為 Master ,而原來的 Master 則切換回 Backup 狀態。
- 健康檢查機制:Keepalived 可以對服務器的服務狀態進行健康檢查,以確保提供服務的服務器是正常運行的。
- 常見檢查方式:包括 TCP 端口檢查、HTTP 檢查、腳本檢查等。例如,對于 Web 服務器,可以通過 HTTP 檢查方式,向服務器的 Web 端口發送請求,根據服務器的響應來判斷服務器是否正常。如果服務器沒有響應或者響應狀態碼不符合預期,Keepalived 就會認為該服務器出現故障,將其從服務池中移除,不再將流量轉發到該服務器。
- 動態調整:通過健康檢查,Keepalived 可以實時監測服務器的狀態,并根據服務器的狀態動態調整負載均衡的策略,保證服務的可用性和穩定性。
- 負載均衡機制(結合 LVS 時):Keepalived 常與 Linux 虛擬服務器(LVS)結合使用,實現負載均衡功能。
- LVS 原理:LVS 是基于 Linux 內核的一種高性能負載均衡技術,它工作在網絡層(OSI 模型的第三層),可以根據不同的調度算法(如輪詢、加權輪詢、最少連接等)將客戶端的請求轉發到后端的多個真實服務器上。
- 協同工作:Keepalived 可以管理 LVS 的配置,監控后端真實服務器的狀態。當發現某臺真實服務器出現故障時,Keepalived 會自動調整 LVS 的配置,將該服務器從負載均衡的服務器池中移除,避免將請求轉發到故障服務器上,從而保證服務的連續性和可用性。
綜上所述,Keepalived 通過 VRRP 協議實現高可用性,通過健康檢查機制確保服務器的正常運行,通過與 LVS 結合實現負載均衡,為網絡服務提供了可靠的保障。
MySQL雙主復制原理:
MySQL 主主復制(也稱為雙主復制)是一種特殊的復制模式,兩臺 MySQL 服務器都可以作為主服務器,同時接受寫入操作,并將各自的更改復制到對方,實現雙向的數據同步。其原理主要涉及以下幾個關鍵部分:
- 二進制日志(Binary Log):每臺 MySQL 服務器都啟用二進制日志功能,用于記錄所有對數據庫進行修改的操作,如 INSERT、UPDATE、DELETE 等。二進制日志以事件的形式存儲,包含了操作的具體內容和相關信息。例如,當在主服務器 A 上執行一個?
INSERT
?語句插入一條新記錄時,該操作會被記錄到主服務器 A 的二進制日志中。 - I/O 線程:在主主復制中,每臺服務器都有一個 I/O 線程。當一臺服務器(假設為服務器 A)上有數據更改并記錄到二進制日志后,另一臺服務器(服務器 B)的 I/O 線程會連接到服務器 A,請求讀取服務器 A 的二進制日志。I/O 線程將讀取到的二進制日志事件記錄到本地的中繼日志(Relay Log)中。例如,服務器 B 的 I/O 線程會定期檢查服務器 A 的二進制日志是否有更新,如果有更新則讀取并寫入到自己的中繼日志中。
- 中繼日志(Relay Log):中繼日志用于存儲從主服務器復制過來的二進制日志事件。服務器 B 的 I/O 線程將從服務器 A 讀取的二進制日志事件寫入中繼日志后,由服務器 B 的 SQL 線程來處理這些事件。
- SQL 線程:每臺服務器的 SQL 線程負責讀取中繼日志中的事件,并在本地數據庫上執行這些事件,從而實現數據的同步。例如,服務器 B 的 SQL 線程讀取中繼日志中來自服務器 A 的?
INSERT
?操作事件,并在服務器 B 的數據庫中執行相同的?INSERT
?操作,插入相同的記錄。 - 設置唯一標識:為了避免循環復制(即一臺服務器將另一臺服務器復制過來的數據又復制回去),每臺服務器都需要設置一個唯一的服務器 ID(server-id)。在 MySQL 的配置文件(如?
my.cnf
?或?my.ini
)中可以設置?server-id
?參數,且每臺服務器的?server-id
?必須不同。例如,服務器 A 的?server-id
?設置為 1,服務器 B 的?server-id
?設置為 2。 - 雙向復制配置:要實現主主復制,需要在兩臺服務器上分別進行配置。每臺服務器都要配置對方為自己的主服務器,指定對方的 IP 地址、端口、用戶名、密碼等連接信息。例如,在服務器 A 上配置服務器 B 為其主服務器,在服務器 B 上配置服務器 A 為其主服務器。
一、環境準備
操作系統 | 主機 | 描述 | 安裝服務 |
Centos 7.9 | A | MySQL主機 | MySQL、Keepalived |
Centos 7.9 | B | MySQL主機 | MySQL、Keepalived |
二、MySQL主主復制部署
注意事項:
在做主主同步前,需要特別注意的一個問題:
主主復制和主從復制有一些區別,因為多主中都可以對服務器有寫權限,所以設計到自增長重復問題,例如:
出現的問題(多主自增長ID重復)
1)首先在A和B兩個庫上創建test表結構;
2)停掉A,在B上對數據表test(存在自增長屬性的ID字段)執行插入操作,返回插入ID為1;
3)然后停掉B,在A上對數據表test(存在自增長屬性的ID字段)執行插入操作,返回的插入ID也是1;
4)然后 同時啟動A,B,就會出現主鍵ID重復
解決方法:
只要保證兩臺服務器上的數據庫里插入的自增長數據不同就可以了
如:A插入奇數ID,B插入偶數ID,當然如果服務器多的話,還可以自定義算法,只要不同就可以了
在下面例子中,在兩臺主主服務器上加入參數,以實現奇偶插入!
記住:在做主主同步時需要設置自增長的兩個相關配置,如下:
auto_increment_offset 表示自增長字段從那個數開始,取值范圍是1 .. 65535。這個就是序號。如果有n臺mysql機器,則從第一臺開始分為設1,2...n
auto_increment_increment 表示自增長字段每次遞增的量,其默認值是1,取值范圍是1 .. 65535。如果有n臺mysql機器,這個值就設置為n。
在主主同步配置時,需要將兩臺服務器的:
auto_increment_increment 增長量都配置為2
auto_increment_offset 分別配置為1和2。這是序號,第一臺從1開始,第二臺就是2,以此類推.....
這樣才可以避免兩臺服務器同時做更新時自增長字段的值之間發生沖突。(針對的是有自增長屬性的字段)。
1、在A、B節點上安裝mysql服務
#步驟一:解壓
mkdir -p /opt/sumscope
cd /opt/sumscope
tar -zxvf mysql-5.7.44-linux-glibc2.12-x86_64.tar.gz
mv mysql-5.7.44-linux-glibc2.12-x86_64 mysql#步驟二:在/opt/sumscope/mysql目錄下創建data logs目錄
cd /opt/sumscope/mysql
mkdir data logs#步驟三:初始化MySQL
cd /opt/sumscope/mysql/bin
./mysqld --defaults-file=/opt/sumscope/mysql/my.cnf --basedir=/opt/sumscope/mysql --datadir=/opt/sumscope/mysql/data --user=root --initialize#步驟四:自定義啟動命令
vim /opt/sumscope/mysql/support-files/mysql.server
basedir=/opt/sumscope/mysql
datadir=/opt/sumscope/mysql/data#步驟五:將啟動腳本放在/etc/init.d目錄下
cp /opt/sumscope/mysql/support-files/mysql.server /etc/init.d/mysql#步驟六:創建mysql用戶
useradd mysql
chown -R mysql.mysql /opt/sumscope/mysql/#步驟七:啟動MySQL,修改root用戶密碼service mysql start cat /opt/sumscope/mysql/logs/mysql_error.log##修改root用戶的密碼
ALTER USER 'root'@'localhost' IDENTIFIED BY 'ppp';##使用utf-8編碼創建數據庫tbook
create database tbook character set utf8 collate utf8_bin;##授權stc用戶遠程登錄tbook數據庫 grant all privileges on tbook.* to stc@'%' identified by 'ppp';
2、在節點A上進行相關配置
2.1、修改MySQL的配置
#步驟一:修改mysql的配置
root@master ~]# vim /etc/my.cnf
[mysqld]
bind-address=0.0.0.0
port=3306
user=mysql
basedir=/usr/local/mysql
datadir=/data/mysql
#socket=/tmp/mysql.sock
log-error=/data/mysql/mysql.err
pid-file=/data/mysql/mysql.pid
socket=/var/lib/mysql/mysql.sock#log-bin=master1server-id = 1
log-bin = mysql-bin
binlog-ignore-db = mysql,information_schema
sync_binlog = 1
binlog_checksum = none
binlog_format = mixed
auto-increment-increment = 2
auto-increment-offset = 1
slave-skip-errors = all #步驟二:重啟MySQL服務
[root@master ~]# service mysql restart
2.2、數據同步授權
MySQL [(none)]> grant replication slave,replication client on *.* to root@'192.168.179.131' identified by "ppp";MySQL [(none)]> flush privileges;
MySQL [(none)]> FLUSH TABLES WITH READ LOCK;MySQL [(none)]> show master status;
+------------------+----------+--------------+--------------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+--------------------------+-------------------+
| mysql-bin.000002 | 3514 | | mysql,information_schema | |
+------------------+----------+--------------+--------------------------+-------------------+
2.3、創建同步用戶sync
CREATE USER 'sync'@'%' identified by '123456';GRANT REPLICATION SLAVE ON *.* TO 'sync'@'%';
3、在節點B上進行相關配置
3.1、修改MySQL的配置
root@master ~]# vim /etc/my.cnf
[mysqld]
bind-address=0.0.0.0
port=3306
user=mysql
basedir=/usr/local/mysql
datadir=/data/mysql
#socket=/tmp/mysql.sock
socket=/var/lib/mysql/mysql.sock
log-error=/data/mysql/mysql.err
pid-file=/data/mysql/mysql.pidserver-id = 2
log-bin = mysql-bin
binlog-ignore-db = mysql,information_schema
sync_binlog = 1
binlog_checksum = none
binlog_format = mixed
auto-increment-increment = 2
auto-increment-offset = 2
slave-skip-errors = all
3.2、數據庫同步授權
數據同步授權(iptables防火墻開啟3306端口,要確保對方機器能使用下面權限連接到本機mysql)同理slave也要授權給master機器遠程同步數據的權限。
MySQL [(none)]> grant replication slave,replication client on *.* to root@'192.168.179.129' identified by "ppp";MySQL [(none)]> flush privileges;
MySQL [(none)]> FLUSH TABLES WITH READ LOCK;MySQL [(none)]> show master status;
+------------------+----------+--------------+--------------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+--------------------------+-------------------+
| mysql-bin.000009 | 1945 | | mysql,information_schema | |
+------------------+----------+--------------+--------------------------+-------------------+
3.3、執行主主同步操作
先在slave數據庫上做同步master的設置。(確保slave上要同步的數據,提前在master上存在。最好雙方數據保持一致)
MySQL [(none)]> unlock tables;MySQL [(none)]> stop slave;MySQL [(none)]> change master to master_host='192.168.179.129',master_user='root',master_password='ppp',master_log_file='mysql-bin.000002',master_log_pos=3514;MySQL [(none)]> start slave;MySQL [(none)]> show slave status \G;
4、在節點A上執行同步操作
MySQL [(none)]> unlock tables;MySQL [(none)]> stop slave;MySQL [(none)]> change master to master_host='192.168.179.131',master_user='root',master_password='ppp',master_log_file='mysql-bin.000009',master_log_pos=1945;MySQL [(none)]> start slave;MySQL [(none)]> show slave status \G;
5、測試MySQL主主同步的效果
5.1、在A、B節點上寫入數據查看數據同步效果
在節點A上寫入數據
5在節點B上查看數據并進行讀寫操作
?
5.2、測試結論
在上述測試操作后可知節點A寫入的數據能被節點B進行增刪改操作,節點B寫入的數據也能被節點A進行增刪改操作,兩個MySQL數據庫實現了雙主復制。
三、安裝Keepalived服務
1、在節點A上安裝Keepalived作為master節點
#步驟一:安裝編譯需要的軟件包
[root@master ~]# yum install -y pcre-devel openssl-devel popt-devel #安裝依賴包#步驟二:安裝keepalived服務
[root@master ~]# tar zxvf keepalived-1.2.7.tar.gz
[root@master ~]# cd keepalived-1.2.7
[root@master ~]# ./configure --prefix=/usr/local/keepalived
[root@master ~]# make && make install#將keepalived配置成系統服務
[root@master ~]# cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
[root@master ~]# cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
[root@master ~]# mkdir /etc/keepalived/
[root@master ~]# cp /usr/local/keepalived/etc/keepalived/keepalived.conf /etc/keepalived/
[root@master ~]# cp /usr/local/keepalived/sbin/keepalived /usr/sbin/#步驟三:配置keepalived配置文件
########################################################配置文件###############################################
[root@master ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalivedglobal_defs {router_id keep1; #keep1是本節點的標識,一般為hostnamescript_user root #使用root執行 enable_script_security
}vrrp_script check_mysql {script "/etc/keepalived/check_mysql.sh"#檢測MySQL狀態的腳本路徑interval 2 #檢測間隔時間weight -20 #如果如果上述條件成立權重-20fall 2 #檢測連續2次失敗才算確定是真失敗。會用weight減少優先級(1-255之間)rise 1 #檢測1次成功就算成功。但不修改優先級
}
vrrp_instance VI_1 {state MASTER #主節點為MASTER,從節點為BACKUPinterface ens33 #本機網卡名稱virtual_router_id 100 #虛擬路由的ID號,兩個節點設置的參數必須一樣,相同的VRID為一組,它將決定多播的地址。mcast_src_ip 192.168.179.131 #本機的IP地址priority 100 #節點的優先級(0~254之間),MASTER比BACKUP高nopreempt #優先級設置,異常恢復后再次搶占的問題。advert_int 1 #組播信息發送間隔,兩個的參數必須一樣,默認為1s。authentication {auth_type PASSauth_pass p #按照實際生產的需求來(一般為root密碼)}track_script {check_mysql}virtual_ipaddress {192.168.179.88 #虛擬IP地址,兩臺主機的必須一致。}
}
########################################################配置文件################################################步驟四:配置keepalived檢測腳本內容
########################################################MySQL檢測腳本內容###############################################
[root@master ~]# vim /etc/keepalived/check_mysql.sh #檢測MySQL服務斷開就殺掉keepalived進程,使VIP漂移#!/bin/bash counter=$(netstat -na|grep "LISTEN"|grep ":3306 "|wc -l)if [ "${counter}" -eq 0 ]; thenservice keepalived stopfi########################################################MySQL檢測腳本內容################################################步驟五:對檢測腳本添加執行權限、啟動keepalived服務[root@master ~]# chmod +x /etc/keepalived/check_mysql.sh[root@master ~]# /etc/init.d/keepalived start
2、在節點B上安裝Keepalived作為slave節點
安裝步驟與節點A上安裝的方法相同,但是配置文件需要修改
#步驟一:配置keepalived配置文件
########################################################配置文件###############################################
[root@slave ~]# vi /etc/keepalived/keepalived.conf
! Configuration File for keepalivedglobal_defs {router_id keep2;script_user rootenable_script_security
}vrrp_script check_mysql { script "/etc/keepalived/check_mysql.sh" #檢測腳本所在的位置interval 2weight -20fall 2rise 1
}
vrrp_instance VI_1 {state BACKUP #修改狀態名稱interface ens33 #修改網卡名稱virtual_router_id 100mcast_src_ip 192.168.179.133 #自己的IP地址priority 80 #作為備節點權重要比主節點小advert_int 1authentication {auth_type PASSauth_pass p}track_script {check_mysql }virtual_ipaddress {192.168.179.88 #虛擬IP地址}
}
########################################################配置文件################################################步驟二:配置keepalived檢測腳本內容用于檢測MySQL的狀態
########################################################MySQL檢測腳本內容###############################################
[root@master ~]# vim /etc/keepalived/check_mysql.sh #檢測MySQL服務斷開就殺掉keepalived進程,使VIP漂移#!/bin/bash counter=$(netstat -na|grep "LISTEN"|grep ":3306 "|wc -l)if [ "${counter}" -eq 0 ]; thenservice keepalived stopfi########################################################MySQL檢測腳本內容################################################步驟三:對檢測腳本添加執行權限、啟動keepalived服務[root@master ~]# chmod +x /etc/keepalived/check_mysql.sh[root@master ~]# /etc/init.d/keepalived start
注意:因為keepalived中配置了MySQL狀態檢測腳本,keepalived在啟動時會執行檢測腳本,所以等MySQL服務啟動成功后再啟動keepalived服務,否則服務將無法啟動keepalived。
四、高可用場景測試
模擬場景一:當主機MySQL出現故障(3306端口不存在)
步驟一:分別在主機和備機上添加對虛擬IP的驗證方式
步驟二:關閉節點A上的MySQL服務
因為配置了權重原因虛擬IP在節點A上,關閉MySQL服務看keepalived服務是否會運行mysql狀態檢測腳本的內容從而使虛擬IP漂移到節點B上。
步驟三:驗證虛擬IP是否漂移到節點B上
在瀏覽器上驗證:輸入:http://192.168.179.88/a.html
結論:虛擬IP從主節點漂移到從節點上
步驟四:模擬故障恢復虛擬IP自動遷回
?在瀏覽器上驗證:輸入:http://192.168.179.88/a.html
結論:因為主機故障恢復,主節點上的keepalived配置的權重要比從節點的權重要高,所以虛擬IP自動從從節點漂移到從主點上?