rhel 8.7 部署 keepalived+haproxy 實現 mysql 雙主高可用場景

文章目錄

    • @[toc]
    • 部署 mysql
      • 關閉防火墻
      • 關閉 selinux
      • 創建相關目錄
      • 創建 mysql 用戶
      • 配置 PATH 變量
      • 驗證 mysql 命令
      • 切換到 mysql 用戶
      • 在 172.72.0.116 生成配置文件
      • 在 172.72.0.137 生成配置文件
      • mysql 初始化
      • 啟動 mysql 服務
      • 修改 mysql 的 root 用戶密碼
      • 配置主從關系
        • 172.72.0.137 配置成 172.72.0.116 的從庫
        • 172.72.0.116 配置成 172.72.0.137 的從庫
      • 主從復制驗證
    • 部署 haproxy
      • 創建 haproxy 配置文件
      • 啟動 haproxy
      • 驗證 haproxy 登錄到 mysql
    • 部署 keepalived
      • Keepalived 工作原理
      • 搶占和非搶占模式
      • 在 172.72.0.116 創建 keepalived 配置文件
      • 在 172.72.0.137 創建 keepalived 配置文件
      • 配置 haproxy 健康檢測腳本
      • 啟動 keepalived 服務
      • 驗證 VIP 登錄 mysql
    • 驗證高可用是否有效
      • 當一臺 mysql 服務無進程
      • 驗證 keepalived 是否為非搶占模式
      • 當一臺 haproxy 服務無進程,mysql 服務均正常

話不多說,直接開搞

ip服務
172.72.0.116keepalived+haproxy+mysql
172.72.0.137keepalived+haproxy+mysql
172.72.0.100VIP

部署前,大家先要確認集群之間的時間是否一致,集群類的服務,最怕時間不一致

部署 mysql

  • Mysql 二進制文件下載地址

部署相關的操作,兩臺機器都需要執行,需要執行指定機器時,會額外提示

關閉防火墻

systemctl disable firewalld --now

關閉 selinux

setenforce 0
sed -i '/SELINUX/s/enforcing/disabled/g' /etc/selinux/config

創建相關目錄

mkdir -p /data/{software,mysql/{config,logs},script,mysql-back}

創建完成后的目錄結構如下

/data/
├── mysql
│   ├── config
│   ├── logs
│   ├── mysql_data
├── mysql-back
├── script
└── software

解壓下載好的二進制文件

tar xf mysql-5.7.29-linux-glibc2.12-x86_64.tar.gz

創建 mysql 用戶

useradd mysql
# 配置用戶密碼
echo mysqldba | passwd --stdin mysql

給對應的目錄和文件修改權限

chown -R mysql /data/software/mysql-5.7.29-linux-glibc2.12-x86_64
chown -R mysql /data/mysql
chown -R mysql /data/mysql-back

配置 PATH 變量

echo 'MYSQL_HOME="/data/software/mysql-5.7.29-linux-glibc2.12-x86_64"' >> /etc/profile
echo 'PATH=${PATH}:${MYSQL_HOME}/bin' >> /etc/profile
source /etc/profile

驗證 mysql 命令

查看是否缺少依賴庫

ldd /data/software/mysql-5.7.29-linux-glibc2.12-x86_64/bin/mysql

例如我這邊缺了倆依賴

        linux-vdso.so.1 (0x00007ffe91b5a000)libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f495203f000)librt.so.1 => /lib64/librt.so.1 (0x00007f4951e37000)libdl.so.2 => /lib64/libdl.so.2 (0x00007f4951c33000)libncurses.so.5 => not foundlibstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007f495189e000)libm.so.6 => /lib64/libm.so.6 (0x00007f495151c000)libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f4951304000)libc.so.6 => /lib64/libc.so.6 (0x00007f4950f3e000)/lib64/ld-linux-x86-64.so.2 (0x00007f495225f000)libtinfo.so.5 => not found

找一下是否有高版本的依賴

find / -type f -name "libncurses.so*"

嘗試用軟連接

ln -s /usr/lib64/libncurses.so.6.1 /usr/lib64/libncurses.so.5

再次使用上面的 ldd 命令去檢查依賴,發現不是 not found 了,用這個辦法,再去解決剩下的依賴缺失

驗證 mysql 命令能不能正常使用

mysql -V

可以獲取到當前的 mysql 客戶端版本

mysql  Ver 14.14 Distrib 5.7.29, for linux-glibc2.12 (x86_64) using  EditLine wrapper

切換到 mysql 用戶

后續的操作都使用 mysql 用戶

su - mysql

在 172.72.0.116 生成配置文件

cat << EOF > /data/mysql/config/my.cnf
[mysqld]
pid-file=/data/mysql/mysqld.pid
socket=/data/mysql/mysqld.sock
datadir=/data/mysql/mysql_data
log-error=/data/mysql/logs/error.log
port=13306
# MySQL 在運行時需要 errmsg.sys 文件來顯示和報告錯誤消息
lc-messages-dir=/data/software/mysql-5.7.29-linux-glibc2.12-x86_64/share/englishserver_id=116# binlog
# binlog 文件的名稱
log_bin=mysql-bin
# 設置每個二進制日志文件的最大大小
max_binlog_size=100m
# 設置用于緩存二進制日志事件的緩沖區大小
binlog_cache_size=4m
# 設置 binlog 緩存的最大大小
max_binlog_cache_size=512m
# binlog 類型
binlog_format=MIXED
# binlog 過期時間
expire_logs_days=7bind-address=0.0.0.0
# 是否允許在數據庫目錄下使用符號鏈接
## symbolic-links=0:表示不允許使用符號鏈接。如果設置為 0,MySQL 服務器在啟動時將不會使用數據庫目錄下的符號鏈接,并且可能會在符號鏈接存在時報錯。
## symbolic-links=1:表示允許使用符號鏈接。如果設置為 1,MySQL 服務器在啟動時將允許使用數據庫目錄下的符號鏈接,但僅限于特定目錄或文件(根據權限設置)。
## symbolic-links=2:表示允許使用符號鏈接,且沒有限制。如果設置為 2,MySQL 服務器在啟動時將允許使用數據庫目錄下的任意符號鏈接,包括對任意文件或目錄的鏈接。
symbolic-links=0
# mysql 最大連接數
max_connections=1000
# 默認存儲引擎
default_storage_engine=innodb
# 禁用外部鎖定,MySQL 將使用內部鎖定來代替外部鎖定
skip_external_locking
# 0:表名存儲為原始大小寫,區分大小寫;
# 1:表名存儲為小寫,不區分大小寫;
# 2:表名存儲為小寫,但會在文件系統上進行名稱比較,因此會區分大小寫。
lower_case_table_names=1
# 禁用主機緩存,每次都要重新解析域名
skip_host_cache
# 開啟主機名解析
skip_name_resolve
# 設置服務器的默認字符集
character_set_server=utf8
# 客戶端與服務器之間允許的最大數據包大小
max_allowed_packet=12M
# 控制 SQL 的執行模式
## STRICT_TRANS_TABLES:啟用嚴格模式,對于事務表,如果有非法數據插入或更新,將會引發錯誤
## NO_ZERO_IN_DATE:禁止在日期中使用 "0000-00-00" 這樣的零值,否則會被轉換為 NULL 值
## ERROR_FOR_DIVISION_BY_ZERO:當除零錯誤發生時,產生錯誤而不是返回 NULL 值
## NO_AUTO_CREATE_USER:禁止 GRANT 語句自動創建新用戶,必須手動創建
## NO_ENGINE_SUBSTITUTION:如果指定的存儲引擎不可用或不存在,不要自動替換為其他可用的存儲引擎,而應該返回錯誤
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'[client]
# 設置 MySQL 客戶端連接的默認字符集
character-set-client=utf8
EOF

在 172.72.0.137 生成配置文件

cat << EOF > /data/mysql/config/my.cnf
[mysqld]
pid-file=/data/mysql/mysqld.pid
socket=/data/mysql/mysqld.sock
datadir=/data/mysql/mysql_data
log-error=/data/mysql/logs/error.log
port=13306
# MySQL 在運行時需要 errmsg.sys 文件來顯示和報告錯誤消息
lc-messages-dir=/data/software/mysql-5.7.29-linux-glibc2.12-x86_64/share/englishserver_id=137# binlog
# binlog 文件的名稱
log_bin=mysql-bin
# 設置每個二進制日志文件的最大大小
max_binlog_size=100m
# 設置用于緩存二進制日志事件的緩沖區大小
binlog_cache_size=4m
# 設置 binlog 緩存的最大大小
max_binlog_cache_size=512m
# binlog 類型
binlog_format=MIXED
# binlog 過期時間
expire_logs_days=7bind-address=0.0.0.0
# 是否允許在數據庫目錄下使用符號鏈接
## symbolic-links=0:表示不允許使用符號鏈接。如果設置為 0,MySQL 服務器在啟動時將不會使用數據庫目錄下的符號鏈接,并且可能會在符號鏈接存在時報錯。
## symbolic-links=1:表示允許使用符號鏈接。如果設置為 1,MySQL 服務器在啟動時將允許使用數據庫目錄下的符號鏈接,但僅限于特定目錄或文件(根據權限設置)。
## symbolic-links=2:表示允許使用符號鏈接,且沒有限制。如果設置為 2,MySQL 服務器在啟動時將允許使用數據庫目錄下的任意符號鏈接,包括對任意文件或目錄的鏈接。
symbolic-links=0
# mysql 最大連接數
max_connections=1000
# 默認存儲引擎
default_storage_engine=innodb
# 禁用外部鎖定,MySQL 將使用內部鎖定來代替外部鎖定
skip_external_locking
# 0:表名存儲為原始大小寫,區分大小寫;
# 1:表名存儲為小寫,不區分大小寫;
# 2:表名存儲為小寫,但會在文件系統上進行名稱比較,因此會區分大小寫。
lower_case_table_names=1
# 禁用主機緩存,每次都要重新解析域名
skip_host_cache
# 開啟主機名解析
skip_name_resolve
# 設置服務器的默認字符集
character_set_server=utf8
# 客戶端與服務器之間允許的最大數據包大小
max_allowed_packet=12M
# 控制 SQL 的執行模式
## STRICT_TRANS_TABLES:啟用嚴格模式,對于事務表,如果有非法數據插入或更新,將會引發錯誤
## NO_ZERO_IN_DATE:禁止在日期中使用 "0000-00-00" 這樣的零值,否則會被轉換為 NULL 值
## ERROR_FOR_DIVISION_BY_ZERO:當除零錯誤發生時,產生錯誤而不是返回 NULL 值
## NO_AUTO_CREATE_USER:禁止 GRANT 語句自動創建新用戶,必須手動創建
## NO_ENGINE_SUBSTITUTION:如果指定的存儲引擎不可用或不存在,不要自動替換為其他可用的存儲引擎,而應該返回錯誤
sql_mode='STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION'[client]
# 設置 MySQL 客戶端連接的默認字符集
character-set-client=utf8
EOF

mysql 初始化

mysqld --initialize-insecure \
--user=mysql \
--basedir=${MYSQL_HOME} \
--datadir=/data/mysql/mysql_data

啟動 mysql 服務

${MYSQL_HOME}/bin/mysqld \
--defaults-file=/data/mysql/config/my.cnf --daemonize \
--plugin-dir=${MYSQL_HOME}/lib/plugin

修改 mysql 的 root 用戶密碼

進入 mysql,初始化的時候沒有設定密碼,直接回車就可以了

mysql -uroot -p -S /data/mysql/mysqld.sock

修改密碼

SET PASSWORD FOR root@localhost = PASSWORD ('YWJjMTIzCg==');

配置主從關系

以下的配置,都是基于新部署的數據庫實現的,如果當前數據庫本身存在數據的情況下,需要先把 master 的數據備份,然后在 slave 節點上恢復數據后,再進行主從配置

172.72.0.137 配置成 172.72.0.116 的從庫

在 172.72.0.116 的 mysql 里面操作,創建一個從復制專用的用戶

CREATE USER 'rpldb'@'%' IDENTIFIED BY 'cnBsZGIwMDcK';
GRANT REPLICATION SLAVE ON *.* TO 'rpldb'@'%';

查看 binlog 的文件名稱和 Position 信息

SHOW MASTER STATUS\G

獲取到類似如下的信息

*************************** 1. row ***************************File: mysql-bin.000001Position: 841Binlog_Do_DB:Binlog_Ignore_DB: sys,mysql,performance_schema,information_schema
Executed_Gtid_Set:
1 row in set (0.00 sec)

在 172.72.0.137 的 mysql 里面操作

CHANGE MASTER TO MASTER_HOST='172.72.0.116', MASTER_PORT=13306, MASTER_USER='rpldb', MASTER_PASSWORD='cnBsZGIwMDcK', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=841;

啟動復制

STOP SLAVE;
START SLAVE;

查看復制是否成功

SHOW SLAVE STATUS\G

看到這兩個都是 yes,表示主從復制已經建立成功了

             Slave_IO_Running: YesSlave_SQL_Running: Yes

172.72.0.116 配置成 172.72.0.137 的從庫

在 172.72.0.137 的 mysql 里面操作,創建一個從復制專用的用戶

CREATE USER 'rpldb'@'%' IDENTIFIED BY 'cnBsZGIwMDcK';
GRANT REPLICATION SLAVE ON *.* TO 'rpldb'@'%';

查看 binlog 的文件名稱和 Position 信息

SHOW MASTER STATUS\G

獲取到類似如下的信息

*************************** 1. row ***************************File: mysql-bin.000001Position: 841Binlog_Do_DB:Binlog_Ignore_DB: sys,mysql,performance_schema,information_schema
Executed_Gtid_Set:
1 row in set (0.00 sec)

在 172.72.0.116 的 mysql 里面操作

CHANGE MASTER TO MASTER_HOST='172.72.0.137', MASTER_PORT=13306, MASTER_USER='rpldb', MASTER_PASSWORD='cnBsZGIwMDcK', MASTER_LOG_FILE='mysql-bin.000001', MASTER_LOG_POS=841;

啟動復制

STOP SLAVE;
START SLAVE;

查看復制是否成功

SHOW SLAVE STATUS\G

看到這兩個都是 yes,表示主從復制已經建立成功了

             Slave_IO_Running: YesSlave_SQL_Running: Yes

主從復制驗證

  • 先使用 mysql root 用戶創建一個庫
create database music;

再創建一個 mysql 的普通用戶,并且對 music 庫有增改查的權限

CREATE USER 'vinci'@'%' IDENTIFIED BY 'DavVinci';
GRANT SELECT,UPDATE,INSERT,CREATE ON music.* TO 'vinci'@'%';

使用 vinci 用戶登錄到 172.72.0.116 的 mysql,進行建庫建表

CREATE TABLE music.favorite(name char(10),music_name char(20)
)charset=utf8;

插入幾條數據

INSERT INTO music.favorite(name, music_name) VALUES
('Eason Chan','遙遠的她'),
('Ronald','怪胎'),
('Hacken Lee','李香蘭');

使用 vinci 用戶登錄到 172.72.0.137 的 mysql,查看數據是否存在

SELECT music_name FROM music.favorite WHERE name='Ronald' limit 5;

部署 haproxy

  • 官網:http://www.haproxy.com
  • HAProxy提供高可用性、負載均衡以及基于TCP和HTTP的應用代理,支持虛擬主機,它是免費、快速并且可靠的一種負載均衡解決方案。適合處理高負載站點的七層數據請求。類似的代理服務可以屏蔽內部真實服務器,防止內部服務器遭受攻擊。

使用 yum 安裝

yum install -y haproxy

創建 haproxy 配置文件

備份原來的配置文件

cp /etc/haproxy/haproxy.cfg{,.bak}

創建配置文件

cat << EOF > /etc/haproxy/haproxy.cfg
global                              log 127.0.0.1 local3 info           # 在本機記錄日志maxconn 65535                       # 每個進程可用的最大連接數chroot /data/haproxy                # haproxy 安裝目錄pidfile /data/haproxy/haproxy.pid   # haproxy pid 文件目錄uid 994                             # 運行 haproxy 的用戶uid(id haproxy 命令可以查看)gid 991                             # 運行 haproxy 的用戶組id(id haproxy 命令可以查看)daemon                              # 以后臺守護進程運行defaultslog globalmode http                           # 運行模式 tcp、 http、 healthretries 3                           # 三次連接失敗,則判斷服務不可用option redispatch                   # 如果后端有服務器宕機,強制切換到正常服務器stats uri /haproxy                  # 統計頁面 URL 路徑stats refresh 30s                   # 統計頁面自動刷新時間stats realm haproxy-status          # 統計頁面輸入密碼框提示信息stats auth admin:YWJjMTIzCg==       # 統計頁面用戶名和密碼stats hide-version                  # 隱藏統計頁面上 HAProxy 版本信息maxconn 65535                       # 每個進程可用的最大連接數timeout connect 5000                # 連接超時	timeout client 50000                # 客戶端超時timeout server 50000                # 服務器端超時frontend http_haproxymode http                           # 運行模式 tcp、 http、 healthmaxconn 65535                       # 每個進程可用的最大連接數bind :18080                         # 監聽 18080 端口log global                       option httplog                   option httpclose                    # 每次請求完畢后主動關閉 http 通道frontend mysqls                        # 自定義描述信息mode tcp                            # 運行模式 tcp、 http、 healthmaxconn 65535                       # 每個進程可用的最大連接數bind *:13307                        # 監聽 13307 端口default_backend mysql_backendbackend mysql_backendmode tcpbalance roundrobin                    # 設置負載均衡模式,source 保存 session 值,roundrobin 輪詢模式# rise 2是2次正確認為服務器可用# fall 3是3次失敗認為服務器不可用server mysql01 172.72.0.116:13306 check inter 5s rise 2 fall 3server mysql02 172.72.0.137:13306 check inter 5s rise 2 fall 3
EOF

給 haproxy 的 chroot 目錄授權

mkdir /data/haproxy
chown -R haproxy /data/haproxy

啟動 haproxy

systemctl enable haproxy
systemctl start haproxy

可以在瀏覽器輸入 172.72.0.116:18080/haproxy 或者 172.72.0.137:18080/haproxy 來驗證是否可以看到統計頁面,這里的 ip,大家以自己實際的為準

驗證 haproxy 登錄到 mysql

haproxy 正確的情況下,兩個地址都可以用 13307 端口來登錄到 mysql 內

mysql -uvinci -pDavVinci -h172.72.0.116 -P13307
mysql -uvinci -pDavVinci -h172.72.0.137 -P13307

部署 keepalived

Keepalived 工作原理

  • keepalived 是以 VRRP 協議為實現基礎的,VRRP 全稱 Virtual Router Redundancy Protocol ,即虛擬路由冗余協議。

    • 虛擬路由冗余協議,可以認為是實現路由器高可用的協議。也就是說N臺提供相同功能的路由器組成一個路由器組,這個組里面有一個 master 和多個 backup,master上面有一個對外提供服務的vip,master 不斷向 backup 發送心跳信息,告訴 backup 自己還活著,當 backup 收不到心跳消息時就認為 master 已經宕機啦,這時就需要根據 VRRP 的優先級來選舉一個 backup 當 master。從而保證高可用。
  • keepalived主要有三個模塊,分別是 core、check 和 vrrp。

    • core 模塊為 keepalived 的核心,負責主進程的啟動、維護、以及全局配置文件的加載和解析。
    • check 負責健康檢查,包括常見的各種檢查方式。
    • vrrp 模塊是來實現 VRRP 協議的。
  • vrrp 虛擬路由冗余協議

    • 使用ip報文作為傳輸協議;
    • 協議號112;
    • 使用固定組播網絡 224.0.0.18 進行發送;
    • 只是用advertisement報文;
  • master路由器的選舉:

    • 比較每臺路由器設備的優先級,優先級大的為 master。優先級相同的,比較接口IP地址,地址大的成為 master;
    • master 會主動周期的發送 advertisement 報文,一秒發送一次;
    • backup 如果 3 秒沒有接到 master 發送的 advertisment 報文,就說明 master down;

搶占和非搶占模式

摘抄自:MySQL + Keepalived 雙主熱備高可用操作記錄

keepalive 通過組播,單播等方式(自定義),實現 keepalive 主備推選。工作模式分為搶占和非搶占(通過參數 nopreempt 來控制)。

  • 搶占模式

    • 主服務正常工作時,虛擬 IP 會在主上,備不提供服務,當主服務優先級低于備的時候,備會自動搶占虛擬 IP,這時,主不提供服務,備提供服務。
      也就是說,工作在搶占模式下,不分主備,只管優先級。
    • 不管 keepalived.conf 里的 state 配置成 master 還是 backup,只看誰的 priority 優先級高(一般而言,state 為 MASTER 的優先級要高于 BACKUP)。priority 優先級高的那一個在故障恢復后,會自動將 VIP 資源再次搶占回來!!
  • 非搶占模式:

    • 這種方式通過參數 nopreempt(一般設置在 advert_int 的那一行下面)來控制。不管 priority 優先級,只要 MASTER 機器發生故障,VIP 資源就會被切換到 BACKUP 上。
      并且當 MASTER 機器恢復后,也不會去將 VIP 資源搶占回來,直至 BACKUP 機器發生故障時,才能自動切換回來。

千萬注意
nopreempt 這個參數只能用于 state 為 backup 的情況,所以在配置的時候要把 master 和 backup 的 state 都設置成 backup,這樣才會實現 keepalived 的非搶占模式!

也就是說:

  • 當 state 狀態一個為 master,一個為 backup 的時候,加不加 nopreempt 這個參數都是一樣的效果。即都是根據 priority 優先級來決定誰搶占 vip 資源的,是搶占模式!
  • 當 state 狀態都設置成 backup,如果不配置 nopreempt 參數,那么也是看 priority 優先級決定誰搶占 vip 資源,即也是搶占模式。
  • 當 state 狀態都設置成 backup,如果配置 nopreempt 參數,那么就不會去考慮 priority 優先級了,是非搶占模式!即只有 vip 當前所在機器發生故障,另一臺機器才能接管 vip。即使優先級高的那一臺機器恢復 后也不會主動搶回 vip,只能等到對方發生故障,才會將 vip 切回來。

使用 yum 安裝

yum install -y keepalived

在 172.72.0.116 創建 keepalived 配置文件

備份原來的配置文件

cp /etc/keepalived/keepalived.conf{,.bak}

創建配置文件,這里采用非搶占模式

cat << EOF > /etc/keepalived/keepalived.conf
! Configuration File for keepalivedglobal_defs {# 每個 keepalived 要配置成不一樣的router_id mysql1
}# 作用:添加一個周期性執行的腳本。
## 腳本的退出狀態碼會被調用它的所有的VRRP Instance記錄。
## 注意:至少有一個VRRP實例調用它并且優先級不能為0。
## 優先級范圍是1-254,用來做健康檢查的,當檢查失敗時會將 vrrp_instance 的 priority 減少相應的值
vrrp_script chk_haproxy  {# 監控服務腳本,腳本x執行權限;script "/data/script/chk_haproxy.sh"# 檢測時間間隔(執行腳本間隔)interval 2weight -2# 解釋 weight:## 如果腳本執行成功(退出狀態碼為0),weight大于0,則priority增加。## 如果腳本執行失敗(退出狀態碼為非0),weight小于0,則priority減少。## 其他情況下,priority不變。
}vrrp_instance VI_1 {state BACKUP# 指定虛擬 ip 的網卡接口,根據自己實際網卡名稱修改interface ens160# 路由器標識,MASTER 和 BACKUP 必須是一致的virtual_router_id 51# 定義優先級,數字越大,優先級越高,在同一個 vrrp_instance 下,MASTER 的優先級必須大于 BACKUP 的優先級。這樣 MASTER 故障恢復后,就可以將VIP資源再次搶回來priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.72.0.100}# 添加此行表示非搶占模式# nopreempttrack_script {chk_haproxy}
}
EOF

在 172.72.0.137 創建 keepalived 配置文件

備份原來的配置文件

cp /etc/keepalived/keepalived.conf{,.bak}

創建配置文件,這里采用非搶占模式

cat << EOF > /etc/keepalived/keepalived.conf
! Configuration File for keepalivedglobal_defs {# 每個 keepalived 要配置成不一樣的router_id mysql2
}# 作用:添加一個周期性執行的腳本。
## 腳本的退出狀態碼會被調用它的所有的VRRP Instance記錄。
## 注意:至少有一個VRRP實例調用它并且優先級不能為0。
## 優先級范圍是1-254,用來做健康檢查的,當檢查失敗時會將 vrrp_instance 的 priority 減少相應的值
vrrp_script chk_haproxy  {# 監控服務腳本,腳本x執行權限;script "/data/script/chk_haproxy.sh"# 檢測時間間隔(執行腳本間隔)interval 2weight -2# 解釋 weight:## 如果腳本執行成功(退出狀態碼為0),weight大于0,則priority增加。## 如果腳本執行失敗(退出狀態碼為非0),weight小于0,則priority減少。## 其他情況下,priority不變。
}vrrp_instance VI_1 {state BACKUP# 指定虛擬 ip 的網卡接口,根據自己實際網卡名稱修改interface ens160# 路由器標識,MASTER 和 BACKUP 必須是一致的virtual_router_id 51# 定義優先級,數字越大,優先級越高,在同一個 vrrp_instance 下,MASTER 的優先級必須大于 BACKUP 的優先級。這樣 MASTER 故障恢復后,就可以將VIP資源再次搶回來priority 100advert_int 1authentication {auth_type PASSauth_pass 1111}virtual_ipaddress {172.72.0.100}# 添加此行表示非搶占模式# nopreempttrack_script {chk_haproxy}
}
EOF

配置 haproxy 健康檢測腳本

  • 所有 keepalived 節點都需要配置
    • 因為非搶占模式,所以需要手動切換 VIP,這里腳本用停止 keepalived 服務來觸發手動切換 VIP
    • 腳本里面是探測 haproxy 的端口三次,如果返回狀態碼都是非0,就會觸發停止 keepalived 服務
cat << EOF > /data/script/chk_haproxy.sh
#!/bin/bash
exitNum=0while true
doif ! nc -z 127.0.0.1 13307; thenlet exitNum++[ ${exitNum} -lt 3 ] || systemctl stop keepalivedfi
done
EOF

keepalived 的健康檢測腳本必須要有執行權限

chmod +x /data/script/chk_haproxy.sh

啟動 keepalived 服務

注意啟動順序,要先啟動一個 keepalived 組件,并且有 VIP 了之后,再去啟動剩下的 keepalived 組件,如果同時啟動 keepalived 組件,那就都會有 VIP 地址了

systemctl enable keepalived
systemctl start keepalived

驗證 VIP 登錄 mysql

能讀取到數據,證明 keepalived 部署沒有問題

mysql -uvinci -pDavVinci -h172.72.0.100 -P13307 -e "SELECT music_name FROM music.favorite WHERE name='Hacken Lee' limit 1;"

驗證高可用是否有效

當一臺 mysql 服務無進程

  • 殺掉一個 mysql 的進程,模擬 mysql 出現故障,等 30秒后,看是否能寫入 mysql 數據
    • 殺掉一個 mysql 的進程后,可以從 haproxy 的統計頁面看到顯示為 down
cat /data/mysql/mysqld.pid | xargs kill -9 && \
sleep 30 && \
mysql -uvinci -pDavVinci -h172.72.0.100 -P13307 -e "INSERT INTO music.favorite(name, music_name) VALUES ('Beyond','冷雨夜');"

驗證完成后,再次啟動 mysql,在 haproxy 的統計頁面看到顯示為 up,并且進入 mysql 查看 SHOW SLAVE STATUS 確認 Slave_IO_RunningSlave_SQL_Running 都是 YES

驗證 keepalived 是否為非搶占模式

存在 VIP 的節點,停止 keepalived 服務,模擬 keepalived 故障,看 VIP 是否會漂移到其他節點

systemctl stop keepalived

此時去其他節點,發現 VIP 已經漂移過來了,并且可以讀取 mysql 數據

  • 將停止的 keepalived 重新啟動,看 VIP 是否會漂移回來
    • 正常情況下,處于非搶占模式,VIP 是不會再次漂移的
systemctl start keepalived

當一臺 haproxy 服務無進程,mysql 服務均正常

  • 這里直接把有 VIP 節點的 haproxy 服務停止,模擬 haproxy 故障,并且觸發 keepalived 的健康檢測,進行 VIP 的漂移,同時驗證是否能讀取 mysql 數據
systemctl stop haproxy && \
sleep 10 && \
ip a | grep 172.72.0.100; \
mysql -uvinci -pDavVinci -h172.72.0.100 -P13307 -e "SELECT music_name FROM music.favorite WHERE name='Hacken Lee' limit 1;"

使用 tcpdump 命令觀察地址的變化

tcpdump -i ens160 vrrp -nn

可以看到,VIP 從 172.72.0.116 機器切換到 172.72.0.137 機器上,并且也能正常讀取 mysql 的數據

22:25:19.569090 IP 172.72.0.116 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 98, authtype simple, intvl 1s, length 20
22:25:20.569328 IP 172.72.0.116 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 98, authtype simple, intvl 1s, length 20
22:25:21.570001 IP 172.72.0.116 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 98, authtype simple, intvl 1s, length 20
22:25:21.578036 IP 172.72.0.116 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 0, authtype simple, intvl 1s, length 20
22:25:22.196273 IP 172.72.0.137 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 98, authtype simple, intvl 1s, length 20
22:25:23.196572 IP 172.72.0.137 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 98, authtype simple, intvl 1s, length 20
22:25:24.196795 IP 172.72.0.137 > 224.0.0.18: VRRPv2, Advertisement, vrid 51, prio 98, authtype simple, intvl 1s, length 20

基于二進制部署的 mysql 寫了一個腳本來做啟停和重啟

#!/usr/bin/env bash
baseDir="$(cd `dirname $0`;pwd)"
envName="$1"
envOpt="$2"
pidFile="/data/mysql/mysqld.pid"
MYSQL_HOME='/data/software/mysql-5.7.29-linux-glibc2.12-x86_64'function opt_usage () {echo "usage: bash $0 'start|stop|restart'"exit 1
}if [ $# -lt 1 ];thenopt_usageexit 1
fifunction start_mysql () {if [[ ! -f "${pidFile}" ]];then${MYSQL_HOME}/bin/mysqld \--defaults-file=/data/mysql/config/my.cnf --daemonize \--plugin-dir=${MYSQL_HOME}/lib/pluginif [ $? -eq 0 ];thenecho "mysql start success"fielsepidNum=$(ps -ef | grep -v grep | grep mysqld | awk '{print $2}')echo "pid: ${pidNum} is running for mysqld,please check it"exit 1fi
}function stop_mysql () {if [[ ! -f "${pidFile}" ]];thenecho "pid file: ${pidFile} is not found"exit 1elsekill $(cat ${pidFile})sleep 5num=0while truedops -ef | grep -v grep | grep mysqld | awk '{print $2}' &> /dev/nullif [ $? -eq 0 ];thenecho "stop mysql success"breakelseecho "wating for mysql shutdown......"let num++sleep 1fiif [ ${num} -eq 3 ];thenecho "stop mysql failed,please check it"exit 1fidonefi
}function status_mysql () {if [ -f "${pidFile}" ];thenpidNum="$(ps -ef | grep -v grep | grep mysqld | awk '{print $2}')"if [ ${pidNum} -eq $(cat ${pidFile}) ];thenecho "mysql is running"echo "mysql version is: $(mysql -V)"echo "   mysql  pid is: ${pidNum}"fielseecho "mysql is not running"fi
}case $1 in'start')start_mysql;;'stop')stop_mysql;;'restart')stop_mysqlstart_mysql;;'status')status_mysql;;'*')opt_usageexit 1
esac

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/39852.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/39852.shtml
英文地址,請注明出處:http://en.pswp.cn/news/39852.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數字化格局下的引領者:百望云通過強制性國家標準GB18030-2022最高級別認證

8月1日,強制性國家標準GB 18030-2022《信息技術 中文編碼字符集》實施。8月15日,百望云“綠頁閱讀器”正式通過中國電子技術標準化研究院強制性國家標準GB18030-2022《信息技術 中文編碼字符集》最高級(實現級別3)認證,彰顯了百望云在數字化信息處理領域對標國家標準的卓越技術…

Android CameraX適配Android13的踩坑之路

AndroidCameraX適配Android13的踩坑之路 前言&#xff1a; 最近把AGP插件升級到8.1.0&#xff0c;新建項目的時候目標版本和編譯版本都是33&#xff0c;發現之前的demo使用Camerax拍照和錄像都失敗了&#xff0c;于是查看了一下官網和各種資料&#xff0c;找到了Android13的適…

網絡編程(12): TCP重傳、滑動窗口、流量控制、擁塞控制

1、TCP重傳機制 通過序列號和確認號確保可靠傳輸&#xff0c;當發送端發送數據給接收到&#xff0c;接收端會返回一個確認號&#xff0c;表示收到消息了 超時重傳&#xff1a;沒有在指定時間內收到ACK報文 超時重傳的兩種可能&#xff1a;數據包丟失、確認包丟失超時重傳時間RT…

第十三課:QtCmd 命令行終端應用程序開發

功能描述&#xff1a;開發一個類似于 Windows 命令行提示符或 Linux 命令行終端的應用程序 一、最終演示效果 QtCmd 不是因為它是 Qt 的組件&#xff0c;而是采用 Qt 開發了一個類似 Windows 命令提示符或者 Linux 命令行終端的應用程序&#xff0c;故取名為 QtCmd。 上述演示…

FreeMarker系列--list的用法(長度,遍歷,下標,嵌套,排序)

原文網址&#xff1a;FreeMarker系列--list的用法&#xff08;長度,遍歷,下標,嵌套,排序&#xff09;_IT利刃出鞘的博客-CSDN博客 簡介 本文介紹FreeMarker的list的用法。 大小 Java ArrayList<String> list new ArrayList<String>(); Freemaker ${list?s…

W5500-EVB-PICO 做UDP Server進行數據回環測試(七)

前言 前面我們用W5500-EVB-PICO 開發板在TCP Client和TCP Server模式下&#xff0c;分別進行數據回環測試&#xff0c;本章我們將用開發板在UDP Server模式下進行數據回環測試。 UDP是什么&#xff1f;什么是UDP Server&#xff1f;能干什么&#xff1f; UDP (User Dataqram P…

圖數據庫_Neo4j學習cypher語言_使用CQL命令002_刪除節點_刪除屬性_結果排序Order By---Neo4j圖數據庫工作筆記0006

然后我們再來看如何刪除節點 可以看到首先 我們這里 比如我要刪除張三 可以看到 match (n:student) where n.name = "張三" delete n 這樣就是刪除了student集合中,name是張三的節點 然后我們再來看 如何來刪除關系 match (n:student)-[r]->(m:student) where…

機器學習、cv、nlp的一些前置知識

為節省篇幅&#xff0c;不標注文章來源和文章的問題場景。大部分是我的通俗理解。 文章目錄 向量關于向量的偏導數&#xff1a;雅可比矩陣二階導數矩陣&#xff1a;海森矩陣隨機變量隨機場伽馬函數beta分布數學術語坐標上升法協方差訓練集&#xff0c;驗證集&#xff0c;測試集…

Nginx的安裝及負載均衡搭建

一.Nginx的安裝 1&#xff09;準備安裝環境 yum install -y make gcc gcc-c pcre-devel pcre zlib zlib-devel openssl openssl-develPERE PCRE(Perl Compatible Regular Expressions)是一個Perl庫&#xff0c;包括 perl 兼容的正則表達式庫。 nginx的http模塊使用pcre來解…

前端jd要求:了解一門后端開發語言優先 解決方案之Node.js

前端jd要求&#xff1a;了解一門后端開發語言優先 解決方案之Node.js 前言常見的后端開發語言一、什么是 Node.js二、學習 Node.js 的前置知識三、學習 Node.js 的步驟1、Node.js 的安裝2、Node.js 的基本語法和 API模塊導入和導出文件讀寫操作HTTP 服務器命令行參數 3、Node.j…

可能導致不可接受的信息安全事件發生的核電站事故。

立陶宛伊格納利納核電站&#xff08;1992 年&#xff09; 一名在該核電站工作的程序員將惡意代碼上傳到一個負責反應堆子系統運行的自動化系統中&#xff0c;該系統被及時發現。 但如果沒有及時發現&#xff0c;誰知道會發生什么呢&#xff1f;核電站被關閉以進行調查。有關這…

Vue-8.集成(.editorconfig、.eslintrc.js、.prettierrc)

介紹 同時使用 .editorconfig、.prettierrc 和 .eslintrc.js 是很常見的做法&#xff0c;因為它們可以在不同層面上幫助確保代碼的格式一致性和質量。這種組合可以在開發過程中提供全面的代碼維護和質量保證。然而&#xff0c;這也可能增加一些復雜性&#xff0c;需要謹慎配置…

Coreutils工具包,Windows下使用Linux命令

之前總結過兩篇有關【如何在Windows系統下使用Linux的常用命令】的文章&#xff1a; GnuWin32&#xff0c;Windows下使用Linux命令 UnxUtils工具包&#xff0c;Windows下使用Linux命令 今天再推薦一個類似的工具包Coreutils 一、簡介 GNU core utilities是GNU操作系統基本…

【HDFS】hdfs的count命令的參數詳解

Usage: hadoop fs -count [-q] [-h] [-v] [-x] [-t [<storage type>]] [-u] [-e] [-s] <paths

(學習筆記-進程管理)怎么避免死鎖?

死鎖的概念 在多線程編程中&#xff0c;我們為了防止多線程競爭共享資源而導致數據錯亂&#xff0c;都會在操作共享資源之前加上互斥鎖&#xff0c;只有成功獲得到鎖的線程&#xff0c;才能操作共享資源&#xff0c;獲取不到鎖的線程就只能等待&#xff0c;直到鎖被釋放。 那…

創建一個簡單的HTML Viewer應用程序

使用wxPython和內嵌瀏覽器來創建一個簡單的HTML Viewer應用程序。 在本篇文章中&#xff0c;我們將使用Python和wxPython模塊來創建一個簡單的HTML Viewer應用程序。這個應用程序可以讓用戶輸入HTML內容&#xff0c;并在內嵌瀏覽器中顯示該內容的效果。 準備工作 在開始之前…

apache doris和StarRocks的區別

記錄一下最新要用到2個新數據庫的區別 Apache Doris是一個分布式的列式存儲系統&#xff0c;它的設計目標是提供大規模數據處理的可靠性和高性能。Doris采用了集群方式&#xff0c;通過將數據分布在多個機器上進行處理來提高性能&#xff0c;并提供了SQL查詢接口方便用戶使用。…

QT:定時器事件

定時器第一種辦法&#xff1a; 1.利用事件timerEvent&#xff0c;在幫助文檔中找到該字段&#xff1a;[override virtual protected] void QTimer::timerEvent(QTimerEvent *e) 重寫該虛函數 //重寫定時器事件void timerEvent(QTimerEvent *e);2.啟動定時器startTimer(1000); …

區間預測 | MATLAB實現QRGRU門控循環單元分位數回歸時間序列區間預測

區間預測 | MATLAB實現QRGRU門控循環單元分位數回歸時間序列區間預測 目錄 區間預測 | MATLAB實現QRGRU門控循環單元分位數回歸時間序列區間預測效果一覽基本介紹模型描述程序設計參考資料 效果一覽 基本介紹 MATLAB實現QRGRU門控循環單元分位數回歸時間序列區間預測。基于分位…

卷積神經網絡教程 (CNN) – 使用 TensorFlow 在 Python 中開發圖像分類器

在這篇博客中,讓我們討論什么是卷積神經網絡 (CNN) 以及 卷積神經網絡背后的架構——旨在解決 圖像識別系統和分類問題。 卷積神經網絡在圖像和視頻識別、推薦系統和自然語言處理方面有著廣泛的應用。 目錄 計算機如何讀取圖像? 為什么不是全連接網絡?