php读写分离需先配稳mysql主从复制,再通过dbproxy类或maxscale中间件实现sql路由:select等读操作走从库,insert/update/delete及事务强制走主库,并处理主从延迟导致的“写后即读”一致性问题。

PHP网站实现读写分离,核心是两件事:先让MySQL主从复制跑稳,再让PHP请求自动走对库。主库只管写,从库专注读,压力就分开了。不依赖复杂中间件也能做,但得把逻辑理清楚。
一、主从复制必须先配稳
没同步,读写分离就是空谈。主库要记操作(binlog),从库要能连上、拉日志、重放数据。
- 主库my.cnf加三行:server-id=1、log-bin=mysql-bin、binlog-format=ROW,重启MySQL
- 主库建复制账号:CREATE USER 'repl'@'%' IDENTIFIED BY '密码'; GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%'; FLUSH PRIVILEGES;
- 执行SHOW MASTER STATUS;,记下File和Position值
- 从库my.cnf设server-id=2(不能和主库重复),重启服务
- 从库执行:CHANGE MASTER TO MASTER_HOST='主库IP', MASTER_USER='repl', MASTER_PASSWORD='密码', MASTER_LOG_FILE='刚才的File', MASTER_LOG_POS=刚才的Position;
- START SLAVE;后用SHOW SLAVE STATUS\G确认两个Running都是Yes,Seconds_Behind_Master接近0
二、PHP层路由读写请求
连接不能硬写死。得封装一个类,让SELECT自动找从库,INSERT/UPDATE/DELETE一律走主库。
- 配置里分开写主库和从库地址,比如$config['master']和$config['slaves']数组
- 写一个DbProxy类,构造时初始化主库PDO和从库PDO列表
- 关键判断逻辑:preg_match('/^\s*(select|show|describe|explain|desc)\b/i', trim($sql))——匹配开头是这些关键词就走从库
- 从库有多个时,用array_rand()随机选一个,避免单点压力过大
- 事务中所有操作必须强制走主库,否则数据不一致;可在执行前检查inTransaction()状态
三、用MaxScale中间件省事不改代码
如果不想动业务逻辑,MaxScale是成熟选择。它像一个智能网关,PHP只连它,它负责把请求分发到后端主从节点。
- 安装MaxScale后,编辑/etc/maxscale.cnf
- [server1]段填主库IP和端口,[server2]填从库IP和端口
- [monitor]启用复制监控,[service]用readwritesplit路由器,设max_slave_connections=100
- [listener]绑定端口如4006,协议设为MySQLClient
- PHP连接串改成host=127.0.0.1, port=4006,其余不变,启动服务即可
四、别忽略主从延迟带来的坑
写完立刻读,从库可能还没同步上。这类场景必须兜底。
- 用户刚注册完查个人信息,这种“写后立即读”应强制走主库
- 可加个简单标记,比如调用db()->masterRead()显式指定主库查询
- 检测Seconds_Behind_Master > 3时,临时把读请求降级到主库,避免脏数据
- 会话级一致性可通过在连接中加注释/* master */来提示路由层
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











