PHP项目ThinkPHP主从读写分离配置

wen PHP项目 4

本文目录导读:

PHP项目ThinkPHP主从读写分离配置

  1. 基础配置(config/database.php)
  2. 使用use配置文件方式
  3. 高级配置(读写分离策略)
  4. 在模型中使用
  5. 使用Db类操作
  6. 封装的DbHelper类示例
  7. 注意事项
  8. 完整配置示例

在ThinkPHP框架中配置主从读写分离,可以按照以下步骤进行:

基础配置(config/database.php)

<?php
return [
    // 默认使用主库
    'default' => 'mysql',
    // 数据库连接配置
    'connections' => [
        'mysql' => [
            // 主库配置
            'type' => 'mysql',
            'host' => '127.0.0.1',
            'port' => '3306',
            'database' => 'main_db',
            'username' => 'root',
            'password' => 'password',
            'charset' => 'utf8mb4',
            'prefix' => '',
            // 从库配置(关键配置)
            'slave' => [
                // 从库连接
                [
                    'type' => 'mysql',
                    'host' => '192.168.1.100', // 从库1地址
                    'port' => '3306',
                    'database' => 'slave_db',
                    'username' => 'slave_user',
                    'password' => 'slave_password',
                    'charset' => 'utf8mb4',
                ],
                // 可以配置多个从库
                [
                    'type' => 'mysql',
                    'host' => '192.168.1.101', // 从库2地址
                    'port' => '3306',
                    'database' => 'slave_db',
                    'username' => 'slave_user',
                    'password' => 'slave_password',
                    'charset' => 'utf8mb4',
                ],
            ],
        ],
    ],
    // 开启读写分离
    'rw_separate' => true,
    // 从库负载均衡策略(可选:random, round-robin)
    'slave_load_balance' => 'random',
    // 查询是否走从库
    'read_master' => false,
];

使用use配置文件方式

// config/database.php
return [
    'connections' => [
        'mysql' => [
            'type' => 'mysql',
            'host' => '127.0.0.1',
            'port' => '3306',
            'database' => 'main_db',
            'username' => 'root',
            'password' => 'password',
            'charset' => 'utf8mb4',
            'prefix' => '',
            // 从库配置
            'slave' => [
                'host' => '192.168.1.100',
                'port' => '3306',
                'database' => 'slave_db',
                'username' => 'slave_user',
                'password' => 'slave_password',
                'charset' => 'utf8mb4',
                'prefix' => '',
                // 可以使用逗号分隔多个从库
                // 'host' => '192.168.1.100,192.168.1.101',
            ],
        ],
    ],
];

高级配置(读写分离策略)

return [
    // 数据库连接配置
    'connections' => [
        'mysql' => [
            // 主库配置
            'type' => 'mysql',
            'host' => '127.0.0.1',
            'port' => '3306',
            'database' => 'main_db',
            'username' => 'root',
            'password' => 'password',
            // 从库配置
            'slave' => [
                // 从库1
                [
                    'type' => 'mysql',
                    'host' => '192.168.1.100',
                    'port' => '3306',
                    'database' => 'slave_db1',
                    'username' => 'slave_user',
                    'password' => 'password',
                    'weight' => 2, // 权重配置(用于负载均衡)
                ],
                // 从库2
                [
                    'type' => 'mysql',
                    'host' => '192.168.1.101',
                    'port' => '3306',
                    'database' => 'slave_db2',
                    'username' => 'slave_user',
                    'password' => 'password',
                    'weight' => 1,
                ],
            ],
            // 读写分离配置
            'params' => [
                // 强制主库操作(写入操作)
                'force_master' => true,
            ],
        ],
    ],
    // 全局读写分离配置
    'global_rw_separate' => true,
    // 异常处理
    'exception_handle' => true,
    // 主从同步延迟检查
    'check_slave_delay' => true,
    'max_slave_delay' => 5, // 最大延迟秒数
];

在模型中使用

<?php
namespace app\model;
use think\Model;
class User extends Model
{
    // 指定主库操作(写入)
    protected $connection = 'mysql';
    // 指定从库操作(读取)
    protected $readConnection = 'mysql';
    // 手动指定使用从库
    public function getUsersFromSlave()
    {
        $slave = $this->db();
        $slave->setConnection('mysql#slave');
        return $slave->select();
    }
    // 强制使用主库
    public function forceMaster()
    {
        return $this->db()->query('SELECT * FROM users', [], true);
    }
}

使用Db类操作

use think\facade\Db;
// 默认自动选择:读操作走从库,写操作走主库
$users = Db::name('users')->select(); // 读操作(优先从库)
// 强制使用主库
$user = Db::name('users')->forceMaster()->find(1);
// 手动指定用主库
Db::name('users')->useMaster()->find(1);
// 手动指定用从库
Db::name('users')->useSlave()->select();
// 事务操作(自动使用主库)
Db::transaction(function () {
    Db::name('users')->insert(['name' => 'test']);
    Db::name('logs')->insert(['action' => 'insert']);
});

封装的DbHelper类示例

<?php
namespace app\helper;
use think\facade\Db;
class DbHelper
{
    /**
     * 强制从主库读取
     * @param string $table
     * @param array $where
     * @return mixed
     */
    public static function master($table, $where = [])
    {
        return Db::name($table)->useMaster()->where($where)->select();
    }
    /**
     * 强制从从库读取
     * @param string $table
     * @param array $where
     * @return mixed
     */
    public static function slave($table, $where = [])
    {
        return Db::name($table)->useSlave()->where($where)->select();
    }
    /**
     * 自动选择(推荐)
     * @param string $table
     * @param array $where
     * @return mixed
     */
    public static function auto($table, $where = [])
    {
        return Db::name($table)->where($where)->select();
    }
}

注意事项

需要修改时强制使用主库

// 数据修改后需要立即读取,强制使用主库
Db::name('orders')->insert($data);
$order = Db::name('orders')->useMaster()->find($orderId);

开启debug日志

// config/app.php
'debug' => true,
// config/log.php
'levels' => ['error', 'info', 'sql'],

监控连接状态

// 查看当前使用的连接
$connection = Db::getConfig();

完整配置示例

return [
    'default' => 'mysql',
    'connections' => [
        'mysql' => [
            'type' => 'mysql',
            'host' => '127.0.0.1',
            'port' => '3306',
            'database' => 'main_db',
            'username' => 'root',
            'password' => 'password',
            'charset' => 'utf8mb4',
            'prefix' => '',
            // 从库配置
            'slave' => [
                'host' => '192.168.1.100,192.168.1.101',
                'port' => '3306',
                'database' => 'slave_db',
                'username' => 'slave_user',
                'password' => 'password',
                'charset' => 'utf8mb4',
                'prefix' => '',
            ],
            // 连接池配置
            'pool' => [
                'max_connections' => 10,
                'min_connections' => 2,
                'max_idle_time' => 60,
                'max_wait_time' => 10,
            ],
            'params' => [
                PDO::ATTR_TIMEOUT => 5,
                PDO::ATTR_PERSISTENT => false,
                PDO::ATTR_EMULATE_PREPARES => false,
            ],
            'break_match' => [
                'error' => ['HY000'],
            ],
        ],
    ],
    // 自动读取从库
    'rw_separate' => true,
    // 从库负载均衡
    'slave_load_balance' => 'round-robin',
];

这套配置可以实现ThinkPHP的读写分离,有效分散数据库压力,提升系统性能。

抱歉,评论功能暂时关闭!