Hyperf 3.1 实现 MySQL 读写分离需配置多组独立连接池(如 master/slave1)并显式调用 Db::connection('master') 或 Db::connection('slave1'),不依赖自动 SQL 解析;推荐生产环境结合 ProxySQL 透明分流,事务及强一致性读必须走主库。

Hyperf 3.1 实现 MySQL 读写分离,不是靠“配置一个连接池”就能自动分流,而是通过 多组独立连接池 + 查询路由规则 协同完成。核心逻辑是:应用层明确区分读/写操作(或由代理/中间件识别 SQL 类型),再将请求分发到对应池——Hyperf 本身不内置 SQL 解析式读写分离,但提供了足够灵活的底层支持。
下面直接讲清楚怎么配:
✅ 明确主从连接池定义(config/autoload/databases.php)
Hyperf 的 hyperf/database 组件支持配置多个数据库连接,每个连接可指定独立的连接池参数:
return [
'default' => [
'driver' => env('DB_DRIVER', 'mysql'),
'host' => env('DB_HOST', 'localhost'),
'port' => env('DB_PORT', 3306),
'database' => env('DB_DATABASE', 'test'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => env('DB_CHARSET', 'utf8mb4'),
'collation' => env('DB_COLLATION', 'utf8mb4_unicode_ci'),
'prefix' => env('DB_PREFIX', ''),
'pool' => [
'min_connections' => 1,
'max_connections' => 20,
'connect_timeout' => 10.0,
'wait_timeout' => 3.0,
'heartbeat' => -1,
'max_idle_time' => (float)env('DB_MAX_IDLE_TIME', 60),
],
],
// 主库(仅写)
'master' => [
'driver' => 'mysql',
'host' => env('DB_MASTER_HOST', '192.168.0.10'),
'port' => (int)env('DB_MASTER_PORT', 3306),
'database' => env('DB_DATABASE', 'test'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'pool' => [
'min_connections' => 2,
'max_connections' => 30,
'wait_timeout' => 3.0,
],
],
// 从库(只读,可配多个,这里以 slave1 为例)
'slave1' => [
'driver' => 'mysql',
'host' => env('DB_SLAVE1_HOST', '192.168.0.11'),
'port' => (int)env('DB_SLAVE1_PORT', 3306),
'database' => env('DB_DATABASE', 'test'),
'username' => env('DB_USERNAME', 'root'),
'password' => env('DB_PASSWORD', ''),
'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci',
'prefix' => '',
'pool' => [
'min_connections' => 2,
'max_connections' => 25,
'wait_timeout' => 3.0,
],
],
];⚠️ 注意:
default连接在这里只是占位或兼容旧代码;实际读写分离中,不建议用default承担业务流量,应显式调用master或slave1。
✅ 在代码中手动选择连接(最常用、最可控方式)
Hyperf 的 Db 类支持传入连接名:
面向 CRM 系统的 MySQL 8 数据库模式设计。当用户需要为客户关系管理(CRM)系统设计、评审、优化或生成数据库模式时,应使用此项技能。
use Hyperf\DbConnection\Db;
// 写操作 → 走 master
Db::connection('master')->table('users')->insert(['name' => 'Alice']);
// 强制读操作 → 走 slave1
Db::connection('slave1')->table('users')->where('id', 1)->first();
// 也可以用 QueryBuilder 切换
$user = Db::connection('slave1')
->table('users')
->where('status', 1)
->orderByDesc('created_at')
->limit(10)
->get();✅ 优点:语义清晰、无歧义、不依赖 SQL 解析,适合大多数业务场景。
✅ 可选:结合 ProxySQL 做透明读写分离(推荐生产环境)
Hyperf 应用只需连 ProxySQL(如 127.0.0.1:6033),把读写分离逻辑下沉到中间件层:
- ProxySQL 配置好 hostgroup(如
10=master,20=slaves) - 配置
mysql_query_rules匹配SELECT→ 发往20,其余发往10 - Hyperf 中只配一个连接指向 ProxySQL:
'myproxy' => [
'driver' => 'mysql',
'host' => '127.0.0.1',
'port' => 6033,
'database' => 'test',
'username' => 'app_user',
'password' => 'xxx',
// 其他同上...
],然后统一使用 Db::connection('myproxy'),所有路由由 ProxySQL 完成。
✅ 优势:对业务代码零侵入、支持故障自动剔除、可动态扩缩从库、便于监控与灰度。
✅ 补充:避免常见坑
- 不要在事务中混用主从连接:事务必须全程走 master,否则会报错或数据不一致
-
从库延迟需业务容忍:Hyperf 不自动检测
seconds_behind_master,如有强一致性要求(如刚写完立刻查),应强制走 master -
连接池权重 ≠ 读负载均衡:Hyperf 本身不支持「同一个连接名下轮询多个从库」,如需多从库负载,要么:
- 自己封装一个
SlavePoolSelector,随机/加权返回'slave1'或'slave2' - 或直接用 ProxySQL / ShardingSphere 等代理层做后端节点管理
- 自己封装一个
不复杂但容易忽略:读写分离的价值不在“配出来”,而在于让读流量真正落到从库、主库压力明显下降。上线后务必用 SHOW PROCESSLIST 或 Prometheus + hyperf-mysql 插件验证各实例的实际 QPS 分布。

















