一鍵部署MySQL8+keepalived雙主熱備高可用

来源:https://www.cnblogs.com/reim/archive/2022/12/09/16968346.html
-Advertisement-
Play Games

作者:李紅建 責編:宇亭 在第一期研發分享中,我們解釋了,為什麼Tinamu作為一款列式存儲引擎在初期不支持 Delete 功能的原因,然後對一些友商列式存儲引擎的 Delete 方案進行了一些調研和總結,感興趣的同學可以查看我們上一期的分享:關於列式資料庫實現 Delete 功能的調研之旅。 本期 ...


概述

本次的文章會格外的長,網上大多的配置流程已經不可使用,本篇文章可以稱為保姆級教程,而且通過shell腳本大大減少了部署mysql主從,雙主的工作量。

img

如上圖,VIP地址為192.168.10.100,如果主機192.168.10.129掛了,會自動切換到備機192.168.10.130上,由於是雙主,數據可以進行同步恢復

部署流程大致為

  1. 192.168.10.129伺服器上部署docker、mysql一主一叢
  2. 192.168.10.130伺服器上部署docker、mysql一主一叢
  3. 192.168.10.129的Master1資料庫和192.168.10.130的資料庫互為主從
  4. 在兩台伺服器上安裝keeplived形成高可用

部署流程

配置第一臺Master

部署Master

準備Master配置文件my.cnf

mkdir /home/mysql_config
mkdir /home/mysql_config/master1
mkdir /home/mysql_config/master1/config
touch /home/mysql_config/master1/config/my.cnf
chmod +x /home/mysql_config/master1/config/my.cnf

cat > /home/mysql_config/master1/config/my.cnf <<EOF
[mysqld]
server_id=110
user=mysql
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
default-authentication-plugin=mysql_native_password
max_connections=800
max_connect_errors=1000

log_bin=mysql_binlog_master1
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/slow.log

log_error=/var/lib/mysql/mysql.err
log_replica_updates=ON
enforce_gtid_consistency=ON
gtid_mode=ON

plugin-load="rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so"
#rpl_semi_sync_source_enabled=ON
#rpl_semi_sync_replica_enabled=ON

binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=sys
binlog-ignore-db=performance_schema

[client]
default-character-set=utf8mb4
EOF

運行Master

會自動下載最新版mysql

docker run -d --name mysql_master1 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=admin123456 -e TZ="Asia/Shanghai" -v /home/mysql_config/master1/config:/etc/mysql/conf.d mysql --authentication_policy=mysql_native_password

啟動半同步插件

此步主要是為了將#rpl_semi_sync_source_enabled=ON#rpl_semi_sync_replica_enabled=ON的井號去掉

mysql會檢測semisync_source.sosemisync_replica.so插件的情況,如果沒有安裝就不能設置rpl_semi_sync_source_enabledrpl_semi_sync_replica_enabled

cat > /home/mysql_config/master1/config/my.cnf <<EOF
[mysqld]
server_id=110
user=mysql
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
default-authentication-plugin=mysql_native_password
max_connections=800
max_connect_errors=1000

log_bin=mysql_binlog_master1
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/slow.log

log_error=/var/lib/mysql/mysql.err
log_replica_updates=ON
enforce_gtid_consistency=ON
gtid_mode=ON

plugin-load="rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so"
rpl_semi_sync_source_enabled=ON
rpl_semi_sync_replica_enabled=ON

binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=sys
binlog-ignore-db=performance_schema

[client]
default-character-set=utf8mb4
EOF

重新開啟

docker restart mysql_master1
docker exec -it mysql_master1 mysql -uroot -padmin123456 -e "show variables like 'rpl_semi_sync_%';"
+---------------------------------------------+------------+
| Variable_name                               | Value      |
+---------------------------------------------+------------+
| rpl_semi_sync_replica_enabled               | ON         |
| rpl_semi_sync_replica_trace_level           | 32         |
| rpl_semi_sync_source_enabled                | ON         |
| rpl_semi_sync_source_timeout                | 10000      |
| rpl_semi_sync_source_trace_level            | 32         |
| rpl_semi_sync_source_wait_for_replica_count | 1          |
| rpl_semi_sync_source_wait_no_replica        | ON         |
| rpl_semi_sync_source_wait_point             | AFTER_SYNC |
+---------------------------------------------+------------+

部署Slave

準備Slave配置文件my.cnf

mkdir /home/mysql_config/slave1
mkdir /home/mysql_config/slave1/config
touch /home/mysql_config/slave1/config/my.cnf
chmod +x /home/mysql_config/slave1/config/my.cnf

cat > /home/mysql_config/slave1/config/my.cnf <<EOF
[mysqld]
server_id=120
user=mysql
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
default-authentication-plugin=mysql_native_password
max_connections=800
max_connect_errors=1000

log_bin=mysql_binlog_master1_slave1
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/slow.log

log_error=/var/lib/mysql/mysql.err
log_replica_updates=ON     
enforce_gtid_consistency=ON
gtid_mode=ON

binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=sys
binlog-ignore-db=performance_schema

[client]
default-character-set=utf8mb4
EOF

運行Slave

會自動下載最新版mysql

docker run -d --name mysql_master1_slave1 -p 4306:3306 -e MYSQL_ROOT_PASSWORD=admin123456 -e TZ="Asia/Shanghai" -v /home/mysql_config/slave1/config:/etc/mysql/conf.d mysql --authentication_policy=mysql_native_password

主從配置

安裝MySQL客戶端

兩台Master都需要安裝,而且後續keepalived也需要安裝

在網站查詢https://dev.mysql.com/downloads/repo/yum/要安裝的mysql版本,以mysql80-community-release-el8-4.noarch.rpm舉例

yum module disable mysql
wget https://dev.mysql.com/get/mysql80-community-release-el8-4.noarch.rpm
rpm -ivh mysql80-community-release-el8-4.noarch.rpm
yum install mysql-community-client
yum module enable mysql

編寫腳本文件

touch /home/mysql_config/mysql_script.sh
chmod +x /home/mysql_config/mysql_script.sh

cat > /home/mysql_config/mysql_script.sh <<'EOF'
#!/bin/bash
MASTER_RPL_USER=rpl_admin
MASTER_RPL_PASSWORD=rpl_admin123456
# master and slaves admin user
ADMIN_USER=root
ADMIN_PASSWORD=admin123456
ALLOW_HOST=%

MASTER_HOST=192.168.10.129
MASTER_PORT=3306
SLAVE_HOST=192.168.10.129
SLAVE_PORT=4306

# master
DROP_USER_SQL="DROP USER '$MASTER_RPL_USER'@'$ALLOW_HOST';"
CREATE_USER_SQL="CREATE USER '$MASTER_RPL_USER'@'$ALLOW_HOST' IDENTIFIED BY '$MASTER_RPL_PASSWORD';"
GRANT_PRIVILEGES_SQL="GRANT REPLICATION SLAVE ON *.* TO '$MASTER_RPL_USER'@'$ALLOW_HOST';"
FLUSH_PRIVILEGES_SQL="FLUSH PRIVILEGES;"

mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$CREATE_USER_SQL"
mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$GRANT_PRIVILEGES_SQL"
mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$FLUSH_PRIVILEGES_SQL"

# master's slave shell
RESULT=`mysql -h$MASTER_HOST -p$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "SHOW MASTER STATUS;" | grep -v grep |tail -n +2| awk '{print $1,$2}'`
LOG_FILE_NAME=`echo $RESULT | grep -v grep | awk '{print $1}'`
LOG_FILE_POS=`echo $RESULT | grep -v grep | awk '{print $2}'`

SYNC_SQL="change master to master_host='$MASTER_HOST', master_port=$MASTER_PORT, master_user='$MASTER_RPL_USER',master_password='$MASTER_RPL_PASSWORD',master_log_file='$LOG_FILE_NAME',master_log_pos=$LOG_FILE_POS;"
START_SYNC_SQL="start REPLICA;"
STATUS_SQL="show REPLICA status\G;"

mysql -h$SLAVE_HOST -P$SLAVE_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$SYNC_SQL"
mysql -h$SLAVE_HOST -P$SLAVE_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$START_SYNC_SQL"
mysql -h$SLAVE_HOST -P$SLAVE_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$STATUS_SQL"
EOF

執行腳本並檢查

sh /home/mysql_config/mysql_script.sh
*************************** 1. row ***************************
...
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
...

配置第二台

部署Master

準備Master配置文件my.cnf

mkdir /home/mysql_config
mkdir /home/mysql_config/master2
mkdir /home/mysql_config/master2/config
touch /home/mysql_config/master2/config/my.cnf
chmod +x /home/mysql_config/master2/config/my.cnf

cat > /home/mysql_config/master2/config/my.cnf <<EOF
[mysqld]
server_id=111
user=mysql
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
default-authentication-plugin=mysql_native_password
max_connections=800
max_connect_errors=1000

log_bin=mysql_binlog_master2
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/slow.log

log_error=/var/lib/mysql/mysql.err
log_replica_updates=ON
enforce_gtid_consistency=ON
gtid_mode=ON

plugin-load="rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so"
#rpl_semi_sync_source_enabled=ON
#rpl_semi_sync_replica_enabled=ON

binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=sys
binlog-ignore-db=performance_schema

[client]
default-character-set=utf8mb4
EOF

運行Master

會自動下載最新版mysql

docker run -d --name mysql_master2 -p 3306:3306 -e MYSQL_ROOT_PASSWORD=admin123456 -e TZ="Asia/Shanghai" -v /home/mysql_config/master2/config:/etc/mysql/conf.d mysql --authentication_policy=mysql_native_password

啟用半同步插件

此步主要是為了將#rpl_semi_sync_source_enabled=ON#rpl_semi_sync_replica_enabled=ON的井號去掉

mysql會檢測semisync_source.sosemisync_replica.so插件的情況,如果沒有安裝就不能設置rpl_semi_sync_source_enabledrpl_semi_sync_replica_enabled

cat > /home/mysql_config/master2/config/my.cnf <<EOF
[mysqld]
server_id=111
user=mysql
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
default-authentication-plugin=mysql_native_password
max_connections=800
max_connect_errors=1000

log_bin=mysql_binlog_master2
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/slow.log

log_error=/var/lib/mysql/mysql.err
log_replica_updates=ON
enforce_gtid_consistency=ON
gtid_mode=ON

plugin-load="rpl_semi_sync_source=semisync_source.so;rpl_semi_sync_replica=semisync_replica.so"
rpl_semi_sync_source_enabled=ON
rpl_semi_sync_replica_enabled=ON

binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=sys
binlog-ignore-db=performance_schema

[client]
default-character-set=utf8mb4
EOF

重新開啟

docker restart mysql_master2
docker exec -it mysql_master2 mysql -uroot -padmin123456 -e "show variables like 'rpl_semi_sync_%';"
+---------------------------------------------+------------+
| Variable_name                               | Value      |
+---------------------------------------------+------------+
| rpl_semi_sync_replica_enabled               | ON         |
| rpl_semi_sync_replica_trace_level           | 32         |
| rpl_semi_sync_source_enabled                | ON         |
| rpl_semi_sync_source_timeout                | 10000      |
| rpl_semi_sync_source_trace_level            | 32         |
| rpl_semi_sync_source_wait_for_replica_count | 1          |
| rpl_semi_sync_source_wait_no_replica        | ON         |
| rpl_semi_sync_source_wait_point             | AFTER_SYNC |
+---------------------------------------------+------------+

部署Slave

準備Slave配置文件my.cnf

mkdir /home/mysql_config/slave2
mkdir /home/mysql_config/slave2/config
touch /home/mysql_config/slave2/config/my.cnf
chmod +x /home/mysql_config/slave2/config/my.cnf

cat > /home/mysql_config/slave2/config/my.cnf <<EOF
[mysqld]
server_id=121
user=mysql
character-set-server=utf8mb4
collation-server=utf8mb4_general_ci
default-authentication-plugin=mysql_native_password
max_connections=800
max_connect_errors=1000

log_bin=mysql_binlog_master2_slave2
slow_query_log=ON
slow_query_log_file=/var/lib/mysql/slow.log

log_error=/var/lib/mysql/mysql.err
log_replica_updates=ON     
enforce_gtid_consistency=ON
gtid_mode=ON

binlog-ignore-db=information_schema
binlog-ignore-db=mysql
binlog-ignore-db=sys
binlog-ignore-db=performance_schema

[client]
default-character-set=utf8mb4
EOF

運行Slave

會自動下載最新版mysql

docker run -d --name mysql_master2_slave2 -p 4306:3306 -e MYSQL_ROOT_PASSWORD=admin123456 -e TZ="Asia/Shanghai" -v /home/mysql_config/slave2/config:/etc/mysql/conf.d mysql --authentication_policy=mysql_native_password

主從配置

安裝MySQL客戶端

兩台Master都需要安裝,而且後續keepalived也需要安裝

在網站查詢https://dev.mysql.com/downloads/repo/yum/要安裝的mysql版本,以mysql80-community-release-el8-4.noarch.rpm舉例

yum module disable mysql
wget https://dev.mysql.com/get/mysql80-community-release-el8-4.noarch.rpm
rpm -ivh mysql80-community-release-el8-4.noarch.rpm
yum install mysql-community-client
yum module enable mysql

編寫腳本文件

touch /home/mysql_config/mysql_script.sh
chmod +x /home/mysql_config/mysql_script.sh

cat > /home/mysql_config/mysql_script.sh <<'EOF'
#!/bin/bash
MASTER_RPL_USER=rpl_admin
MASTER_RPL_PASSWORD=rpl_admin123456
# master and slaves admin user
ADMIN_USER=root
ADMIN_PASSWORD=admin123456
ALLOW_HOST=%

MASTER_HOST=192.168.10.130
MASTER_PORT=3306
SLAVE_HOST=192.168.10.130
SLAVE_PORT=4306

# master
DROP_USER_SQL="DROP USER '$MASTER_RPL_USER'@'$ALLOW_HOST';"
CREATE_USER_SQL="CREATE USER '$MASTER_RPL_USER'@'$ALLOW_HOST' IDENTIFIED BY '$MASTER_RPL_PASSWORD';"
GRANT_PRIVILEGES_SQL="GRANT REPLICATION SLAVE ON *.* TO '$MASTER_RPL_USER'@'$ALLOW_HOST';"
FLUSH_PRIVILEGES_SQL="FLUSH PRIVILEGES;"

mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$CREATE_USER_SQL"
mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$GRANT_PRIVILEGES_SQL"
mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "$FLUSH_PRIVILEGES_SQL"

# master's slave shell
RESULT=`mysql -h$MASTER_HOST -p$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "SHOW MASTER STATUS;" | grep -v grep |tail -n +2| awk '{print $1,$2}'`
LOG_FILE_NAME=`echo $RESULT | grep -v grep | awk '{print $1}'`
LOG_FILE_POS=`echo $RESULT | grep -v grep | awk '{print $2}'`

SYNC_SQL="change master to master_host='$MASTER_HOST', master_port=$MASTER_PORT, master_user='$MASTER_RPL_USER',master_password='$MASTER_RPL_PASSWORD',master_log_file='$LOG_FILE_NAME',master_log_pos=$LOG_FILE_POS;"
START_SYNC_SQL="start REPLICA;"
STATUS_SQL="show REPLICA status\G;"

mysql -h$SLAVE_HOST -P$SLAVE_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$SYNC_SQL"
mysql -h$SLAVE_HOST -P$SLAVE_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$START_SYNC_SQL"
mysql -h$SLAVE_HOST -P$SLAVE_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$STATUS_SQL"
EOF

執行腳本並檢查

sh /home/mysql_config/mysql_script.sh
*************************** 1. row ***************************
...
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
...

雙主配置

Master1作為主,Master2作為備份

Master1的IP地址為:192.168.10.129
Master2的IP地址為:192.168.10.130

安裝MySQL客戶端

兩台Master都需要安裝,而且後續keepalived也需要安裝

在網站查詢https://dev.mysql.com/downloads/repo/yum/要安裝的mysql版本,以mysql80-community-release-el8-4.noarch.rpm舉例

yum module disable mysql
wget https://dev.mysql.com/get/mysql80-community-release-el8-4.noarch.rpm
rpm -ivh mysql80-community-release-el8-4.noarch.rpm
yum install mysql-community-client
yum module enable mysql

編寫配置文件

touch /home/mysql_config/rplShell.sh
chmod +x /home/mysql_config/rplShell.sh

cat > /home/mysql_config/rplShell.sh <<'EOF'
#!/bin/bash
MASTER_RPL_USER=rpl_admin
MASTER_RPL_PASSWORD=rpl_admin123456
# master and slaves admin user
ADMIN_USER=root
ADMIN_PASSWORD=admin123456

MASTER_HOST=192.168.10.130
MASTER_PORT=3306
BACKUP_HOST=192.168.10.129
BACKUP_PORT=3306

RESULT=`mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "SHOW MASTER STATUS;" | grep -v grep |tail -n +2| awk '{print $1,$2}'`
LOG_FILE_NAME=`echo $RESULT | grep -v grep | awk '{print $1}'`
LOG_FILE_POS=`echo $RESULT | grep -v grep | awk '{print $2}'`

SYNC_SQL="change master to master_host='$MASTER_HOST', master_port=$MASTER_PORT, master_user='$MASTER_RPL_USER',master_password='$MASTER_RPL_PASSWORD',master_log_file='$LOG_FILE_NAME',master_log_pos=$LOG_FILE_POS;"
START_SYNC_SQL="start REPLICA;"
STATUS_SQL="show REPLICA status\G;"

mysql -h$BACKUP_HOST -P$BACKUP_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$SYNC_SQL"
mysql -h$BACKUP_HOST -P$BACKUP_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$START_SYNC_SQL"
mysql -h$BACKUP_HOST -P$BACKUP_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$STATUS_SQL"
EOF

執行腳本並檢查

sh /home/mysql_config/rplShell.sh
*************************** 1. row ***************************
...
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
...

Master2作為主,Master1作為備份

Master1的IP地址為:192.168.10.129
Master2的IP地址為:192.168.10.130

安裝MySQL客戶端

兩台Master都需要安裝,而且後續keepalived也需要安裝

在網站查詢https://dev.mysql.com/downloads/repo/yum/要安裝的mysql版本,以mysql80-community-release-el8-4.noarch.rpm舉例

yum module disable mysql
wget https://dev.mysql.com/get/mysql80-community-release-el8-4.noarch.rpm
rpm -ivh mysql80-community-release-el8-4.noarch.rpm
yum install mysql-community-client
yum module enable mysql

編寫配置文件

touch /home/mysql_config/rplShell.sh
chmod +x /home/mysql_config/rplShell.sh

cat > /home/mysql_config/rplShell.sh <<'EOF'
#!/bin/bash
MASTER_RPL_USER=rpl_admin
MASTER_RPL_PASSWORD=rpl_admin123456
# master and slaves admin user
ADMIN_USER=root
ADMIN_PASSWORD=admin123456

MASTER_HOST=192.168.10.129
MASTER_PORT=3306
BACKUP_HOST=192.168.10.130
BACKUP_PORT=3306

RESULT=`mysql -h$MASTER_HOST -P$MASTER_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e "SHOW MASTER STATUS;" | grep -v grep |tail -n +2| awk '{print $1,$2}'`
LOG_FILE_NAME=`echo $RESULT | grep -v grep | awk '{print $1}'`
LOG_FILE_POS=`echo $RESULT | grep -v grep | awk '{print $2}'`

SYNC_SQL="change master to master_host='$MASTER_HOST', master_port=$MASTER_PORT, master_user='$MASTER_RPL_USER',master_password='$MASTER_RPL_PASSWORD',master_log_file='$LOG_FILE_NAME',master_log_pos=$LOG_FILE_POS;"
START_SYNC_SQL="start REPLICA;"
STATUS_SQL="show REPLICA status\G;"

mysql -h$BACKUP_HOST -P$BACKUP_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$SYNC_SQL"
mysql -h$BACKUP_HOST -P$BACKUP_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$START_SYNC_SQL"
mysql -h$BACKUP_HOST -P$BACKUP_PORT -u"$ADMIN_USER" -p"$ADMIN_PASSWORD" -e"$STATUS_SQL"
EOF

執行腳本並檢查

sh /home/mysql_config/rplShell.sh
*************************** 1. row ***************************
...
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
...

配置Keepalived

Master1主機配置

安裝keepalived

yum install -y keepalived

編寫keepalived配置文件

cat > /etc/keepalived/keepalived.conf <<'EOF'
! Configuration File for keepalived

global_defs {
    router_id HA-M1
    script_user root
}

vrrp_script chk_mysql {
    script /etc/keepalived/chk_mysql.sh
    interval 3
    fall 3
    rise 2
}

vrrp_instance VI_MYSQL {
    state MASTER
    interface ens160
    virtual_router_id 100
    priority 100
    advert_int 1
    unicast_src_ip  192.168.10.129
    unicast_peer {
            192.168.10.130
    }
    
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    
    virtual_ipaddress {
        192.168.10.100/24 dev ens160 label ens160:vip
    }
    
    track_script {
        chk_mysql
    }
}
EOF
  • router_id:標識,兩台需不一樣
  • state MASTER:表明這台是Master角色
  • priority:優先順序,MASTER角色比BACKUP高
  • virtual_router_id:虛擬路由編號,兩台需要一致,兩個節點不能一樣
  • 192.168.10.100 dev ens32 label ens32:vip:VIP地址—192.168.10.100
  • script /etc/keepalived/chk_mysql.sh:MySQL的檢測腳本,定時去檢測MySQL進程是否掛掉,會重啟,interval是為間隔時間(2s檢測一次)

當Keepalived從BACKUP提升為MASTER時,那麼VIP就會漂移到自己身上,這個時候我們只需要將Slave掛載在自己身上即可

MySQL狀態監測腳本

安裝MySQL客戶端

在網站查詢https://dev.mysql.com/downloads/repo/yum/要安裝的mysql版本,以mysql80-community-release-el8-4.noarch.rpm舉例

wget https://dev.mysql.com/get/mysql80-community-release-el8-4.noarch.rpm
rpm -ivh mysql80-community-release-el8-4.noarch.rpm
yum module disable mysql
yum install mysql-community-client
yum module enable mysql

配置Keepalived的MySQL狀態監測腳本

touch /etc/keepalived/chk_mysql.sh
chmod +x /etc/keepalived/chk_mysql.sh

cat > /etc/keepalived/chk_mysql.sh <<'EOF'
#!/bin/bash
MYSQL=/usr/bin/mysql
MYSQL_HOST=192.168.10.129
MYSQL_USER=root
MYSQL_PASSWORD=admin123456
CHECK_TIME=3
  
#mysql  is working MYSQL_OK is 1 , mysql down MYSQL_OK is 0
  
MYSQL_OK=1
  
function check_mysql_helth (){
    $MYSQL -h $MYSQL_HOST -u$MYSQL_USER -p${MYSQL_PASSWORD} -e "show status;" >/dev/null 2>&1
    if [ $? = 0 ] ;then
    MYSQL_OK=1
    else
    MYSQL_OK=0
    fi
    return $MYSQL_OK
}
while [ $CHECK_TIME -ne 0 ]
do
    let "CHECK_TIME -= 1"
    check_mysql_helth
if [ $MYSQL_OK = 1 ] ; then
    CHECK_TIME=0
    exit 0
fi
if [ $MYSQL_OK -eq 0 ] &&  [ $CHECK_TIME -eq 0 ]
then
    systemctl stop keepalived
    exit 1
fi
sleep 1
done
EOF

Master2備機配置

安裝keepalived

yum install -y keepalived

編寫keepalived配置文件

cat > /etc/keepalived/keepalived.conf <<'EOF'
! Configuration File for keepalived

global_defs {
    router_id HA-M2
    script_user root
}

vrrp_script chk_mysql {
    script /etc/keepalived/chk_mysql.sh
    interval 3
    fall 3
    rise 2
}

vrrp_instance VI_MYSQL {
    state BACKUP
    interface ens160
    virtual_router_id 100
    nopreempt
    priority 50
    advert_int 1
    unicast_src_ip  192.168.10.130
    unicast_peer {
            192.168.10.129
    }
    
    authentication {
        auth_type PASS
        auth_pass 1111
    }
    
    virtual_ipaddress {
        192.168.10.100/24 dev ens160 label ens160:vip
    }
    
    track_script {
        chk_mysql
    }
}
EOF

註意router_id需要不一樣,state BACKUP表明是備機,virtual_router_id需要一致,priority要比MASTER低!

chk_mysql.sh內容如下,可以看到可以根據當前Keepalived的狀態分別處理,但是此處的處理都是啟動MySQL(如果MySQL進程已退出)

MySQL狀態監測腳本

安裝MySQL客戶端

在網站查詢https://dev.mysql.com/downloads/repo/yum/要安裝的mysql版本,以mysql80-community-release-el8-4.noarch.rpm舉例

wget https://dev.mysql.com/get/mysql80-community-release-el8-4.noarch.rpm
rpm -ivh mysql80-community-release-el8-4.noarch.rpm
yum module disable mysql
yum install mysql-community-client
yum module enable mysql

配置Keepalived的MySQL狀態監測腳本

touch /etc/keepalived/chk_mysql.sh
chmod +x /etc/keepalived/chk_mysql.sh

cat > /etc/keepalived/chk_mysql.sh <<'EOF'
#!/bin/bash
MYSQL=/usr/bin/mysql
MYSQL_HOST=192.168.10.130
MYSQL_USER=root
MYSQL_PASSWORD=admin123456
CHECK_TIME=3
  
#mysql  is working MYSQL_OK is 1 , mysql down MYSQL_OK is 0

MYSQL_OK=1
  
function check_mysql_helth (){
    $MYSQL -h $MYSQL_HOST -u$MYSQL_USER -p${MYSQL_PASSWORD} -e "show status;" >/dev/null 2>&1
    if [ $? = 0 ] ;then
    MYSQL_OK=1
    else
    MYSQL_OK=0
    fi
    return $MYSQL_OK
}
while [ $CHECK_TIME -ne 0 ]
do
    let "CHECK_TIME -= 1"
    check_mysql_helth
if [ $MYSQL_OK = 1 ] ; then
    CHECK_TIME=0
    exit 0
fi
if [ $MYSQL_OK -eq 0 ] &&  [ $CHECK_TIME -eq 0 ]
then
    systemctl stop keepalived
    exit 1
fi
sleep 1
done
EOF

啟動Keepalived

最後在Master1和Master2分別啟動Keepalived

systemctl start keepalived

查看Master1網路配置

ifconfig
ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.129  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::20c:29ff:fe23:aab2  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:23:aa:b2  txqueuelen 1000  (Ethernet)
        RX packets 4797  bytes 524410 (512.1 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2860  bytes 332307 (324.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

ens160:vip: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.100  netmask 255.255.255.255  broadcast 0.0.0.0
        ether 00:0c:29:23:aa:b2  txqueuelen 1000  (Ethernet)

查看Master2網路配置

ens160: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.10.130  netmask 255.255.255.0  broadcast 192.168.10.255
        inet6 fe80::20c:29ff:feb4:3ede  prefixlen 64  scopeid 0x20<link>
        ether 00:0c:29:b4:3e:de  txqueuelen 1000  (Ethernet)
        RX packets 4672  bytes 2048171 (1.9 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 2703  bytes 275576 (269.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

主機上有ens160:vip而備機上沒有vip

Keepalived可能會遇到的問題

  1. 主機能啟動,備機不能啟動
    1. 關閉防火牆
    2. 兩台機器的網卡uuid是否衝突(如果是vm ware複製的linux,因為網卡uuid一致導致的)
  2. 主機和備機keepalived都為master,有兩種方法
    • 關閉防火牆,或設置組播ip可用
    • 兩端keepalived設置為單播(使用unicast_src_ip )

測試

數據同步測試

進入Master1,創建資料庫test_db,表test_user ,並插入一條數據。

docker exec -it mysql_master1 mysql -uroot -padmin123456 -e "CREATE DATABASE test_db;"
docker exec -it mysql_master1 mysql -uroot -padmin123456 -e "CREATE TABLE test_db.test_user (id INT(11),name VARCHAR(25),age int(11) );"
docker exec -it mysql_master1 mysql -uroot -padmin123456 -e "INSERT INTO test_db.test_user values (1,'zhangsan',18);"
docker exec -it mysql_master1 mysql -uroot -padmin123456 -e "SELECT * FROM test_db.test_user;"

查看Master1及從庫master1_slave1、 查看Master2及從庫master2_slave2的數據同步情況

docker exec -it mysql_master1 mysql -uroot -padmin123456 -e "SELECT * FROM test_db.test_user;"
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   18 |
+------+----------+------+

docker exec -it mysql_master1_slave1 mysql -uroot -padmin123456 -e "SELECT * FROM test_db.test_user;"
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   18 |
+------+----------+------+

docker exec -it mysql_master2 mysql -uroot -padmin123456 -e "SELECT * FROM test_db.test_user;"
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   18 |
+------+----------+------+

docker exec -it mysql_master2_slave2 mysql -uroot -padmin123456 -e "SELECT * FROM test_db.test_user;"
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   18 |
+------+----------+------+

高可用測試

啟用備機測試

停止主機上的mysql

docker stop mysql_master1

主機上的Keepalived狀態

Keepalived[4213]: Stopping
Keepalived_vrrp[4214]: (VI_MYSQL) sent 0 priority
Keepalived_vrrp[4214]: (VI_MYSQL) removing VIPs.

備機的Keepalived狀態

Keepalived_vrrp[8986]: (VI_MYSQL) Backup received priority 0 advertisement
Keepalived_vrrp[8986]: (VI_MYSQL) Receive advertisement timeout
Keepalived_vrrp[8986]: (VI_MYSQL) Entering MASTER STATE
Keepalived_vrrp[8986]: (VI_MYSQL) setting VIPs.
Keepalived_vrrp[8986]: (VI_MYSQL) Sending/queueing gratuitous ARPs on ens160 for 192.168.10.100

註意
Master備機上做寫操作,第一次寫會發生半同步等待(10s左右),第二次寫會退化成非同步複製

主機恢複測試

啟動主機上的mysql和keepalived

docker start mysql_master1
systemctl start keepalived

主機上的Keepalived狀態

Keepalived_vrrp[5413]: (VI_MYSQL) Entering BACKUP STATE
Keepalived_vrrp[5413]: VI_MYSQL: sending gratuitous ARP for 192.168.10.129
Keepalived_vrrp[5413]: Sending gratuitous ARP on ens160 for 192.168.10.129
Keepalived_vrrp[5413]: (VI_MYSQL) received lower priority (50) advert from 192.168.10.130 - discarding
Keepalived_vrrp[5413]: (VI_MYSQL) received lower priority (50) advert from 192.168.10.130 - discarding
Keepalived_vrrp[5413]: (VI_MYSQL) received lower priority (50) advert from 192.168.10.130 - discarding
Keepalived_vrrp[5413]: (VI_MYSQL) Receive advertisement timeout
Keepalived_vrrp[5413]: (VI_MYSQL) Entering MASTER STATE
Keepalived_vrrp[5413]: (VI_MYSQL) setting VIPs.
Keepalived_vrrp[5413]: (VI_MYSQL) Sending/queueing gratuitous ARPs on ens160 for 192.168.10.100
Keepalived_vrrp[5413]: Sending gratuitous ARP on ens160 for 192.168.10.100
Keepalived_vrrp[5413]: Sending gratuitous ARP on ens160 for 192.168.10.100
Keepalived_vrrp[5413]: Sending gratuitous ARP on ens160 for 192.168.10.100
Keepalived_vrrp[5413]: Sending gratuitous ARP on ens160 for 192.168.10.100
Keepalived_vrrp[5413]: Sending gratuitous ARP on ens160 for 192.168.10.100


備機的Keepalived狀態

Keepalived_vrrp[8986]: (VI_MYSQL) Master received advert from 192.168.10.129 with higher priority 100, ours 50
Keepalived_vrrp[8986]: (VI_MYSQL) Entering BACKUP STATE
Keepalived_vrrp[8986]: (VI_MYSQL) removing VIPs.

結論

如果殺掉主機上的mysql

  • VIP會漂移到備機上,ifconfig能看到VIP信息
  • 備機的Keepalived從BACKUP狀態轉換為了MASTER狀態
  • Master備機上做寫操作,第一次寫會發生半同步等待(10s左右),第二次寫會退化成非同步複製

恢復主機mysql

  • ifconfig看下VIP會漂移回來,並且備機上的VIP會消失
  • 剛纔在Master備機上寫入的數據同步過來了
  • Keepalived的狀態是從FAULT轉變為BACKUP,最後變成MASTER

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

-Advertisement-
Play Games
更多相關文章
  • 就像黑火藥時代里突然誕生的核彈一樣,OpenAI的ChatGPT語言模型的橫空出世,是人工智慧技術發展史上的一個重要里程碑。這是一款無與倫比、超凡絕倫的模型,能夠進行自然語言推理和對話,並且具有出色的語言生成能力。 ...
  • 前言 之所以會搞這個手勢識別分類,其實是為了滿足之前群友提的需求,就是針對稚暉君的ElectronBot機器人的上位機軟體的功能豐富,因為本來擅長的技術棧都是.NET,也剛好試試全能的.NET是不是真的全能就想著做下試試了,MediaPipe作為谷歌開源的機器視覺庫,功能很豐富了,而且也支持c++, ...
  • 一:背景 1. 簡介 .NET 高級調試要想玩的好,看懂彙編是基本功,但看懂彙編和能寫點彙編又完全是兩回事,所以有時候看的多,總手癢癢想寫一點,在 Windows 平臺上搭建彙編環境不是那麼容易,大多還是用微軟的 MASM + DosBox 搭一個 8086 的環境,這玩意距今快 50 年了。 在以 ...
  • 原文鏈接 [https://www.cnblogs.com/densen2014/p/16964858.html] 在Blazor項目嵌入 pdf.js 時不能正確顯示中文,瀏覽器F12顯示如下錯誤 錯誤 l10n.js /web/locale/locale.properties not found ...
  • 大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家講的是存儲器大廠Micron的NOR Flash晶元特殊絲印設計(FBGA代碼)。 痞子衡之前寫過一篇文章 《J-Flash在Micron Flash固定區域下載校驗失敗的故事》,這篇文章里提及了 Micron 家的串列 NOR Flash 與 ...
  • 大家好,我是痞子衡,是正經搞技術的痞子。今天痞子衡給大家講的是國內外串列NOR Flash廠商官網Cross Reference功能。 串列 NOR Flash 是一個相對發展穩定的市場,目前全球市場約 90% 的份額被中國的三家廠商(Winbond華邦/MXIC旺巨集/GigaDevice兆易創新) ...
  • 我們前面採集的日誌數據已經保存到 Kafka 中,作為日誌數據的 ODS 層,從 Kafka 的ODS 層讀取的日誌數據分為 3 類, 頁面日誌、啟動日誌和曝光日誌。這三類數據雖然都是用戶行為數據,但是有著完全不一樣的數據結構,所以要拆分處理。將拆分後的不同的日誌寫回 Kafka 不同主題中,作為日 ...
  • 前言 "redis是單線程的" 這句話我們耳熟能詳。但它有一定的前提,redis整個服務不可能只用到一個線程完成所有工作,它還有持久化、key過期刪除、集群管理等其它模塊,redis會通過fork子進程或開啟額外的線程去處理。所謂的單線程是指從網路連接(accept) -> 讀取請求內容(read) ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...