读写分离能扛住多少并发?别只看QPS数字
主从复制最直接的作用是把读请求分流到从库,缓解主库压力。4核8G的MySQL 5.7实例,在纯读场景下理论QPS可达10000,但实际中一旦混入慢查询(比如报表SQL),主库锁表会直接拖垮前台服务。用从库专跑报表、后台分析,主库就能专注处理订单、支付等核心事务。
实操建议:
• 写操作必须走
master,应用层需明确区分数据源;
• 从库数量不是越多越好,超过5个后IO和网络开销会明显上升;
• 不要依赖“自动读写分离中间件”,很多开源组件在事务内误发读请求到从库,导致查不到刚写的记录。
为什么主库宕机后数据可能丢?binlog同步机制是关键
默认异步复制下,主库写完
binlog就返回客户端成功,不等从库确认。如果主库突然断电,这部分未同步的binlog就永远丢失了。2025年某金融平台就因未启用半同步,在一次磁盘故障中丢失了3秒交易日志。
实操建议:
• 强烈开启
rpl_semi_sync_master_enabled=ON,并配
rpl_semi_sync_master_timeout=10000(单位毫秒);
• 检查是否生效:
SHOW VARIABLES LIKE 'rpl_semi%';+
SHOW STATUS LIKE 'Rpl_semi_sync%';;
• 注意:半同步会略微降低TPS,压测时务必对比开启前后的性能衰减。
从库延迟怎么看?别只信Seconds_Behind_Master
Seconds_Behind_Master显示为0,不代表数据已追平——它只反映IO线程拉取进度,SQL线程执行卡住时这个值照样是0。真实延迟得看
relay_log_pos和主库
master_log_pos的差值,再结合当前binlog事件的执行耗时。
实操建议:
• 定期执行:
SHOW SLAVE STATUS\G,重点盯
Read_Master_Log_Pos、
Exec_Master_Log_Pos、
Seconds_Behind_Master三者关系;
• 遇到延迟突增,先查从库是否在做
OPTIMIZE TABLE或大事务回滚;
• MySQL 5.7+ 可启用
slave_parallel_workers > 0加速SQL线程,但需确保
binlog_format=ROW且
slave_parallel_type=LOGICAL_CLOCK。
keepalived切换时,为什么从库不敢直接升主?
自动切换最大的陷阱是“脑裂”和“数据不一致”。比如主库只是网络闪断,keepalived已切VIP到从库,结果原主库恢复后还在继续写——两边同时写,自增ID冲突、唯一键报错、数据覆盖全来了。
实操建议:
• 主从都设
auto_increment_offset和
auto_increment_increment错开(如主库offset=1, increment=2;从库offset=2, increment=2);
• keepalived检测脚本必须包含
mysql -e "SELECT @@read_only;",只读状态为OFF才允许接管VIP;
• 切换前强制停止原主库的写入:
SET GLOBAL read_only=ON;+
FLUSH TABLES WITH READ LOCK;,否则宁可人工介入。 主从复制不是高可用的终点,而是起点。真正难的是在延迟、一致性、切换时机之间做取舍——比如半同步保数据但降性能,多线程复制提速但增加配置复杂度,keepalived快切却要严防脑裂。这些权衡点,往往比搭环境本身更消耗线上经验。
