單一從庫無法承載高併發讀請求,且缺乏自動故障切換。本文記錄生產環境驗證過的 Keepalived + LVS (DR 模式) 方案,實現 MySQL 從庫讀流量負載分發與節點健康檢查自動摘除,配合 VIP 透明化應用連線。
| 角色 | IP | 說明 |
|---|---|---|
| LVS Master (Keepalived) | 192.168.1.180 | 掛載 VIP、分發流量、健康檢查 |
| MySQL Slave 1 | 192.168.20.182 | Real Server,掛載 VIP on lo:0 |
| MySQL Slave 2 | 192.168.20.183 | Real Server,掛載 VIP on lo:0 |
| 應用/測試端 | 192.168.20.181 | 連線 VIP 192.168.20.253:3306 |
核心原理 (DR 模式):LVS 僅修改 MAC 地址轉發封包,Real Server 直接回應客戶端,回包不經 LVS,極大減輕 LVS 網卡壓力,適合高讀流量場景。
# 關閉 SELinux 與防火牆 (生產建議改用 iptables 精細放行)
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config
systemctl stop firewalld && systemctl disable firewalld
# 開啟核心轉發
echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf
sysctl -p
yum install -y ipvsadm gcc openssl-devel popt-devel
# Keepalived 建議編譯安裝獲取最新版
wget https://www.keepalived.org/software/keepalived-2.2.8.tar.gz
tar xzf keepalived-*.tar.gz && cd keepalived-*
./configure --with-kernel-dir=/usr/src/kernels/$(uname -r)
make && make install
/etc/keepalived/keepalived.conf! Configuration File for keepalived
global_defs {
router_id LVS_MASTER_01
}
vrrp_instance VI_MYSQL {
state MASTER
interface eth0
virtual_router_id 51
priority 100
advert_int 1
authentication {
auth_type PASS
auth_pass S3cur3P@ss
}
virtual_ipaddress {
192.168.20.253/24 dev eth0 label eth0:VIP
}
}
virtual_server 192.168.20.253 3306 {
delay_loop 6
lb_algo wlc # 加權最少連線,適合長連線資料庫
lb_kind DR # Direct Routing 模式
protocol TCP
persistence_timeout 0 # 無持久連線,讀請求無狀態
real_server 192.168.20.182 3306 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 3306
}
}
real_server 192.168.20.183 3306 {
weight 1
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 3306
}
}
}
systemctl enable keepalived && systemctl start keepalived
ipvsadm -Ln
# 輸出應顯示 VIP:3306 -> 兩個 Real Server,狀態為 Route
/etc/rc.d/init.d/realserver#!/bin/bash
# chkconfig: - 80 90
# description: LVS Real Server VIP binding
VIP=192.168.20.253
. /etc/rc.d/init.d/functions
case "$1" in
start)
ifconfig lo:0 $VIP netmask 255.255.255.255 broadcast $VIP
route add -host $VIP dev lo:0
# ARP 抑制關鍵參數:防止 Real Server 搶答 ARP 請求
echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 1 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 2 > /proc/sys/net/ipv4/conf/all/arp_announce
sysctl -p >/dev/null 2>&1
echo "RealServer VIP $VIP bound OK"
;;
stop)
ifconfig lo:0 down
route del $VIP >/dev/null 2>&1
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/lo/arp_announce
echo 0 > /proc/sys/net/ipv4/conf/all/arp_ignore
echo 0 > /proc/sys/net/ipv4/conf/all/arp_announce
echo "RealServer VIP released"
;;
*)
echo "Usage: $0 {start|stop}"
exit 1
esac
/etc/sysctl.confnet.ipv4.ip_forward = 1
# LVS DR 模式 ARP 抑制
net.ipv4.conf.lo.arp_ignore = 1
net.ipv4.conf.lo.arp_announce = 2
net.ipv4.conf.all.arp_ignore = 1
net.ipv4.conf.all.arp_announce = 2
chmod +x /etc/rc.d/init.d/realserver
chkconfig realserver on
service realserver start
mysql -h 192.168.20.253 -u user -p 連線成功,多次連線觀察分發至兩台從庫 (可查 SHOW VARIABLES LIKE 'server_id')。systemctl stop mysqld,ipvsadm -Ln 顯示該節點狀態變 Down,流量全轉 Slave2。Route 狀態。| 現象 | 原因 | 解決 |
|---|---|---|
| VIP ping 通但 telnet 3306 不通 | 在 LVS Master 本機測試,回包被 lo 接走 | 必須從「第三方客戶端」測試,LVS 本機不走 DR 轉發路徑 |
| Real Server 收不到請求 | ARP 抑制參數未生效 | 檢查 sysctl -a | grep arp,確認 lo/all 參數為 1/2 |
| ipvsadm -L 只顯示 localhost | 預設解析 IP 為主機名 | 使用 ipvsadm -Ln 直接顯示 IP |
| 從庫同步延遲大但仍在服務 | TCP_CHECK 僅檢查端口存活 | 若業務極度敏感,可改用腳本檢查 Seconds_Behind_Master,但會增加複雜度 |
mysqld_exporter + node_exporter 監控 Seconds_Behind_Master、Slave_IO_Running、LVS 連線數。