1. 安装 MySQL 主从复制
首先需要配置 MySQL 主从复制,以实现读写分离。具体配置步骤请参考 MySQL 官方文档,这里简单介绍一下基本的配置方法:
- 在主库上创建一个专门用于复制的用户,并授予其复制权限;
- 在主库的
my.cnf
配置文件中添加log-bin
和server-id
配置项; - 在从库的
my.cnf
配置文件中添加server-id
和relay-log
配置项; - 在从库上启动复制进程,连接到主库并开始复制数据。
2. 修改数据库配置文件
在 config/database.php
文件中设置数据库连接信息,包括主库和从库的连接信息。可以通过 connections
配置项设置主库,通过 slaves
配置项设置从库。然后开启读写分离功能,即设置 rw_separate
配置项为 true
。
例如:
env('database.default', 'mysql'),
// 主库连接
'connections' => [
'mysql' => [
// 数据库类型
'type' => 'mysql',
// 服务器地址
'hostname' => env('database.hostname', '127.0.0.1'),
// 数据库名
'database' => env('database.database', 'database'),
// 用户名
'username' => env('database.username', 'root'),
// 密码
'password' => env('database.password', ''),
// 端口
'hostport' => 3306,
// 数据库编码默认采用utf8
'charset' => 'utf8mb4',
// 数据库表前缀
'prefix' => '',
// 是否需要断线重连
'break_reconnect' => true,
],
],
// 从库连接
'slaves' => [
// 从库配置 1
[
// 数据库类型
'type' => 'mysql',
// 服务器地址
'hostname' => '192.168.1.101',
// 数据库名
'database' => 'database',
// 用户名
'username' => 'slave1',
// 密码
'password' => 'password',
// 端口
'hostport' => 3306,
// 数据库编码默认采用utf8
'charset' => 'utf8mb4',
// 数据库表前缀
'prefix' => '',
// 是否需要断线重连
'break_reconnect' => true,
],
// 从库配置 2
[
// 数据库类型
'type' => 'mysql',
// 服务器地址
'hostname' => '192.168.1.102',
// 数据库名
'database' => 'database',
// 用户名
'username' => 'slave2',
// 密码
'password' => 'password',
// 端口
'hostport' => 3306,
// 数据库编码默认采用utf8
'charset' => 'utf8mb4',
// 数据库表前缀
'prefix' => '',
// 是否需要断线重连
'break_reconnect' => true,
],
],
// 开启读写分离
'rw_separate' => true,
// 读写分离类型(仅支持 multi,不支持 select)
'type' => 'multi',
// 主从负载均衡策略(暂时只支持随机和轮询)
'lb_policy' => 'random',
];
其中,connections
配置项设置了主库的数据库连接信息,slaves
配置项设置了从库的数据库连接信息。rw_separate
配置项开启了读写分离功能,type
配置项设置读写分离的类型为 multi
,lb_policy
配置项设置从库的负载均衡策略为随机。
- 进行数据库操作
在代码中,使用 Db
类进行数据库操作。可以使用 Db::connect('mysql')
获取主库的数据库连接,使用 $db->table('table_name')->insert($data)
向主库插入数据,并使用 $db->connect('slave')->table('table_name')->select()
从从库读取数据。例如:
use think\facade\Db;
// 获取主库连接
$db = Db::connect('mysql');
// 插入数据到主库
$db->table('test')->insert(['name' => 'foo', 'age' => 18]);
// 获取从库连接,支持随机或轮询策略
$slaves = ['mysql'];
$slave = $db->connect($slaves[array_rand($slaves, 1)]);
// 从从库读取数据
$data = $slave->table('test')->where('age', '<=', 20)->select();
以上代码中,首先使用 Db::connect('mysql')
获取主库的数据库连接,使用 $db->table('test')->insert(...)
向主库插入数据。然后,使用 $db->connect('slave')
获取从库的数据库连接(也可以使用随机和轮询负载均衡策略),并从从库读取数据。
使用 Db
类进行数据库操作时,可以使用 $db->connect('slave')
切换到从库连接进行读操作:
table('user')->insert([
'name' => 'test',
'age' => 20,
]);
// 获取从库连接
$slaveDb = $db->connect('slave');
// 执行读操作
$users = $slaveDb->table('user')->select();
// 返回结果
return json($users);
}
}
在以上代码中,首先通过 Db::connect('mysql')
方法获取主库连接 $db
,使用 $db->table('user')->insert(...)
方法插入数据,并通过 $db->connect('slave')
切换到从库连接 $slaveDb
进行读操作。
这样就实现了基于 ThinkPHP6 的简单读写分离。需要注意的是,由于读写分离是在应用层面进行的,因此仍有可能存在一定程度上的数据不一致性问题,需要根据项目需求和实际情况进行权衡和选择。
本文共 个字数,平均阅读时长 ≈ 分钟,您已阅读:0时0分0秒。
649494848