laravel5.4读写分离+mysql主从复制实例

一、主从复制

1、原理:主从复制的原理其实就是把主服务器上的BIN日志复制到从服务器上执行一遍,这样从服务器上的数据就和主服务器上的数据相同了。

2、mysql准备:

这里准备的是两台在同一局域网下的mysql

主:10.10.38.110

从:10.10.38.112

3、大致步骤:

3.1、主库启用二进制日志,记录任何mysql数据修改操作。

3.2、从节点开启一个线程(I/O Thread)把自己扮演成mysql的客户端,通过mysql协议,读取主库的二进制日志文件中的事件

3.3、主库启动一个线程(dump Thread),检查自己二进制日志中的事件,跟对方请求的位置对比,如果不带请求位置参数,则库就会从第一个日志文件中的第一个事件一个一个发送给从节点。

3.4、从库读取到主库发送的操作数据把它放置到中继日志(Relay log)文件中。并记录该次请求到主节点的具哪个二进制日志文件的哪个位置。

3.5、从库启动另外一个线程(sql Thread ),把replaylog中的事件读取出来,并在本地再执行一次,从而完成和主库一样的数据修改操作达到和主库数据一致。

4、详细步骤:

  •      配置主库,启用二进制日志,为当前节点设置一个全局唯一的server_id,创建有复制权限的用户账号 REPLIACTION SLAVE ,REPLIATION CLIENT。如下:

4.1、 打开主库配置文件(mysql下是my.ini,linux下是my.cnf),配置文件中可以看到mysql很多基础配置(如:port:3306,default-storage-engine=MyISAM等),在配置文件中添加如下:

  •       添加:log-bin = mysql-bin
  •       添加:server-id =38110    //最好使用当前主机ip的后两位,否则会出现slave-IO启动失败的情况
  •       添加:innodb-file-per-table =ON
  •       添加:skip_name_resolve=ON

添加完这些配置之后,重启mysql,然后通过命令查看是否开启成功

  show global variables like “%log%”;

查看master信息,从库配置会用到这里的信息:

4.2 、创建有复制权限的用户,为从库准备

Grant REPLICATION SLAVE ,REPLICATION CLIENT on *.* to 'root'@'10.10.38.112' identified by password’;

flush privileges;

  •      配置从库,启动中继日志,设置一个全局唯一的server_id,使用有复制权限的用户账号连接至主节点,并启动复制线程,如下:

4.3、打开从库的配置文件,添加如下:

  •       添加:relay-log=relay-log
  •       添加:relay-log-index=relay-log.index
  •       添加:server-id=38112      //最好使用当前主机ip的后两位,否则会出现slave-IO启动失败的情况
  •       添加:innodb_file_per_table=ON
  •       添加:skip_name_resolve=ON

2.2、添加 主节点主机,访问主节点的用户名及密码,主节点二进制文件信息。

注意:主节点的二进制文件如果有多个一定要是二进制列表中的最后一个二进制文件。

CHANGE MASTER TO MASTER_HOST='10.10.38.110',MASTER_USER='root',MASTER_PASSWORD='password', MASTER_LOG_FILE='mysql-bin.000002',MASTER_LOG_POS=783;

start slave;  //启动slave

show slave status; //查看slave是否配置并启动成功

如上图结果,基本上就可以确定主从配置成功了。咱们就可以测试一下在主库创建一个新库,看看从库是否也会自动生成。

二、Laravel中配置并使用读写分离

在配置项目之前,我们首先要保证项目服务器拥有这两个数据库的对应权限,分别在主库和从库对应给项目服务器赋予权限。注意:如果我们是在已经配置好主从复制之后再给其它ip赋权限,那么从库会同步主库相同的权限操作,所以,若想主、从库给项目服务器开设不同的权限那就需要在数据库配置之前先开设好项目服务器的对应账号权限。

主库:GRANT ALL PRIVILEGES ON *.* TO 'username'@"项目ip地址" IDENTIFIED BY "password";
从库:GRANT ALL PRIVILEGES ON *.* TO 'username'@"项目ip地址" IDENTIFIED BY "password";//从库的权限我们完全可以只赋予读权限

1、打开项目根目录中config/database.php,配置如下

'mysql' => [
    'read' => [
        'host' => '10.10.38.245',//从库
    ],
    'write' => [
        'host' => '10.10.38.110',//主库
    ],
    'database' => 'database',
    'username' => 'username',
    'password' => 'password',
    'driver'    => 'mysql',
    'charset'   => 'utf8',
    'collation' => 'utf8_unicode_ci',
    'prefix'    => '',
    'port' => env('DB_PORT', '3306'),
    'unix_socket' => env('DB_SOCKET', ''),
    'strict' => true,
    'engine' => null,
],

当然,如果主库和从库赋予的账号密码不一样,可以在read和write数组中单独配置账号密码,配置成功后项目中就可以使用了。

发表评论