Laravel+Mysql读写分离配置(主从复制)【转】

1,967 阅读3分钟
环境:
系统:Centos7
数据库:Mysql5.7
PHP:7.0
Laravel版本:5.5

##### 准备两台服务器或虚拟机,且两台数据库的数据库名称和类型都要一致。

192.168.1.10 (主写)
192.168.1.20 (主读)

#1 数据库配置

#1.1 主服务器配置

  • 编辑数据库配置文件
vim /etc/my.cnf
  • 在[mysqld]后添加以下配置
[mysqld]
# 主数据库端ID号
server-id = 1
# 开启二进制日志
log-bin = mysql-bin
# 需要复制的数据库名,如果复制多个数据库,重复设置这个选项即可
binlog-do-db = test_db

# 以下配置按需添加

#将从服务器从主服务器收到的更新记入到从服务器自己的二进制日志文件中
log-slave-updates
#控制binlog的写入频率。每执行多少次事务写入一次(这个参数性能消耗很大,但可减小MySQL崩溃造成的损失) 
sync_binlog = 1
#这个参数一般用在主同步中,用来错开自增值, 防止键值冲突
auto_increment_offset = 1
#这个参数一般用在主同步中,用来错开自增值, 防止键值冲突
auto_increment_increment = 1
#二进制日志自动删除的天数,默认值为0,表示“没有自动删除”,启动时和二进制日志循环时可能删除
expire_logs_days = 7
#将函数复制到slave
log_bin_trust_function_creators = 1
  • 重启数据库
systemctl restart mysqld
  • 进入数据库
mysql -uroot -p123456
  • 创建允许从从服务器同步数据的账户
   grant replication slave on *.* to 'slave'@'%' identified by '123456';

# 刷新权限
flush privileges;
  • 查看主服务器数据库状态,运行命令后不要再动主服务器数据库,接下来配置从服务器
show master status\G;

#1.2 从服务器配置

  • 编辑数据库配置文件
vim /etc/my.cnf

# 在[mysqld]后添加以下配置

# 主数据库端ID号
server-id = 2
# 开启二进制日志
log-bin = mysql-bin
# 如果从数据库名称要和主数据库名称不一样的话一定要加上这一条配置
replicate-rewrite-db = test_db -> test2_db
  • 重启数据库
systemctl restart mysqld
  • 进入数据库
mysql -uroot -p123456
  • 执行同步命令。
/** 配置同步服务器
master_host 主服务器ip
master_user 主服务器同步账户(在主服务器配置时创建的)
master_log_file 同步文件位置
*/
change master to master_host='xx.xx.xx.xx',master_user='slave',master_password='123456',master_log_file='mysql-bin.000012',master_log_pos=7418;

# 启动同步功能
start slave;

# 查看同步状态,Slave_IO_Running及Slave_SQL_Running的值都是YES代表配置成功
show slave status\G;

#2 laravel配置

  • 修改config/database.php文件 例如:
'connections' => [
    'sqlite' => [
        'driver' => 'sqlite',
        'database' => env('DB_DATABASE', database_path('database.sqlite')),
        'prefix' => '',
    ],

    'mysql' => [
        'write' => [
            'host' => '192.168.1.10',
            'database' => 'test_db',
        ],
        'read' => [
            'host' => '192.168.1.20',
            'database' => 'test2_db',
        ],
        'driver' => 'mysql',
        'port' => env('DB_PORT', '3306'),
        'username' => env('DB_USERNAME', 'forge'),
        'password' => env('DB_PASSWORD', ''),
        'unix_socket' => env('DB_SOCKET', ''),
        'charset' => 'utf8mb4',
        'collation' => 'utf8mb4_unicode_ci',
        'prefix' => '',
        'strict' => true,
        'engine' => null,
    ],
  • 修改根目录的.env文件,配置mysql数据库登陆信息
DB_CONNECTION=mysql
DB_PORT=3306
DB_DATABASE=test_db
DB_USERNAME=test
DB_PASSWORD=123456
  • 读写分离配置中的 sticky 配置项

在读写分离配置中,我们注意到新增了一个 sticky 配置项,这个是用来干嘛的呢? 我们配置数据库读写分离的时候,会配置读数据库(从库)从写数据库(主库)同步数据,由于不同主机之间数据同步是需要时间的,虽然这个时间很短,但是对于并发量很大的应用,还是可能出现写入写数据库的数据不能立即从读数据库读取到的情况,sticky 配置项在这个时候就派上用场了。如果该配置项设置为 true 的话,在同一个请求生命周期中,写入的数据会被立刻读取到,底层原理其实就是读操作也从写数据库读取,因为写数据库始终是最新数据,从而避免主从同步延迟导致的数据不一致。