1. 为什么需要MySQL从库负载均衡?
在数据库架构设计中,MySQL主从复制是常见的读写分离方案。但随着业务增长,单一的从库往往难以承受所有读请求的压力。我曾经管理过一个电商系统,在促销活动期间,从库的CPU利用率长期保持在90%以上,导致查询响应时间从平时的50ms飙升到800ms。这就是典型的从库性能瓶颈问题。
LVS(Linux Virtual Server)配合Keepalived实现的负载均衡方案,能够将读请求均匀分发到多个从库节点。这种架构带来三个核心优势:
- 横向扩展能力:通过添加从库节点即可线性提升读性能,我们曾经通过增加2个从库实例将QPS从5k提升到15k
- 高可用保障:当某个从库故障时,LVS会自动剔除故障节点,确保服务连续性
- 透明访问:应用层只需连接虚拟IP,无需感知后端从库的增减变化
2. LVS+Keepalived架构解析
2.1 核心组件分工
在这个方案中,各组件扮演着不同角色:
- LVS:作为四层负载均衡器,工作在TCP层,根据配置的调度算法(如wrr)将MySQL连接请求分发到后端Real Server
- Keepalived:实现高可用的关键,通过VRRP协议维护VIP的漂移,并在Director Server故障时自动切换
- Real Server:实际的MySQL从库实例,需要在本地回环接口绑定VIP
2.2 DR模式的工作原理
我们选择DR(Direct Routing)模式主要基于其性能优势。与NAT模式相比,DR模式的数据包流向具有显著特点:
请求路径:
- 客户端 → Director Server(LVS)→ Real Server
- Director Server只修改目标MAC地址,不改变IP包内容
响应路径:
- Real Server → 客户端(直接返回,不经过Director Server)
这种非对称路径使得Director Server不会成为带宽瓶颈。在实际压力测试中,DR模式比NAT模式的吞吐量高出3倍以上。
3. 环境准备与配置细节
3.1 基础环境规划
建议使用以下服务器配置:
| 角色 | 数量 | 推荐配置 | 网络要求 |
|---|---|---|---|
| LVS Director | 2 | 2C4G | 同一网段,开启IP转发 |
| MySQL Real Server | ≥2 | 根据负载需求确定 | 绑定VIP到lo接口,关闭ARP响应 |
3.2 关键配置步骤
3.2.1 Real Server配置
每个MySQL从库需要执行以下配置:
# 创建Real Server启动脚本 cat > /etc/init.d/realserver <<'EOF' #!/bin/bash VIP=182.148.15.239 case "$1" in start) echo 1 > /proc/sys/net/ipv4/conf/lo/arp_ignore echo 2 > /proc/sys/net/ipv4/conf/lo/arp_announce ifconfig lo:0 $VIP netmask 255.255.255.255 up route add -host $VIP dev lo:0 ;; stop) ifconfig lo:0 down route del $VIP >/dev/null 2>&1 ;; *) echo "Usage: $0 {start|stop}" exit 1 esac EOF # 设置权限并启动 chmod +x /etc/init.d/realserver /etc/init.d/realserver start echo "/etc/init.d/realserver start" >> /etc/rc.local关键参数说明:
arp_ignore=1:只响应目标IP配置在接收网卡上的ARP请求arp_announce=2:始终使用网卡的最合适本地地址作为ARP源地址
3.2.2 Director Server配置
主备Director都需要安装ipvsadm和keepalived:
# 安装依赖 yum install -y ipvsadm keepalived # 开启IP转发 echo "net.ipv4.ip_forward = 1" >> /etc/sysctl.conf sysctl -pKeepalived配置示例(主节点):
cat > /etc/keepalived/keepalived.conf <<'EOF' ! Configuration File for keepalived global_defs { router_id LVS_MASTER } vrrp_instance VI_1 { state MASTER interface eth0 virtual_router_id 51 priority 100 advert_int 1 authentication { auth_type PASS auth_pass 1111 } virtual_ipaddress { 182.148.15.239 } } virtual_server 182.148.15.239 3306 { delay_loop 6 lb_algo wrr lb_kind DR persistence_timeout 50 protocol TCP real_server 192.168.1.101 3306 { weight 3 TCP_CHECK { connect_timeout 3 connect_port 3306 } } real_server 192.168.1.102 3306 { weight 2 TCP_CHECK { connect_timeout 3 connect_port 3306 } } } EOF4. 生产环境优化建议
4.1 健康检查优化
默认的TCP_CHECK只能检测端口可用性,建议改用MYSQL_CHECK:
real_server 192.168.1.101 3306 { weight 3 MYSQL_CHECK { connect_timeout 3 user "monitor" passwd "password" database "test" } }需要先在MySQL创建监控账号:
CREATE USER 'monitor'@'%' IDENTIFIED BY 'password'; GRANT USAGE ON *.* TO 'monitor'@'%';4.2 会话保持配置
对于需要会话一致性的应用,调整persistence_timeout:
virtual_server 182.148.15.239 3306 { persistence_timeout 300 # 5分钟会话保持 persistence_granularity 255.255.255.255 }4.3 监控指标采集
建议监控以下关键指标:
LVS层面:
# 查看连接分布 ipvsadm -ln --stats # 查看每秒请求数 ipvsadm -ln --rateMySQL层面:
SHOW STATUS LIKE 'Threads_connected'; SHOW STATUS LIKE 'Queries';
5. 常见问题排查
5.1 VIP无法访问
排查步骤:
- 检查Director Server是否绑定了VIP:
ip addr show - 验证Real Server的lo接口配置:
ifconfig lo:0 - 测试基础网络连通性:
telnet <VIP> 3306
5.2 负载不均衡
可能原因及解决方案:
- 权重设置不合理:根据服务器配置调整weight参数
- 会话保持时间过长:适当减小persistence_timeout
- 调度算法不合适:对于短连接场景建议使用lc算法
5.3 故障切换延迟
优化建议:
- 减小advert_int值(最低可设到1秒)
- 配置更敏感的健康检查超时:
TCP_CHECK { connect_timeout 2 retry 2 delay_before_retry 1 }
6. 性能压测数据参考
在我们的测试环境中,使用3台MySQL从库(16C32G)配合LVS DR模式,得到以下数据:
| 并发连接数 | 平均QPS | 平均延迟 | CPU利用率 |
|---|---|---|---|
| 500 | 12,000 | 45ms | 60% |
| 1000 | 28,000 | 38ms | 75% |
| 2000 | 52,000 | 42ms | 85% |
当单个从库故障时,系统自动切换时间在3-5秒内完成,期间仅有少量连接会报错。