• 随着用户体量不断增大,一个库压力可能越来越大,可以考虑使用读写分离。
    • 一般是一主多从,主机用于写,从机用于读。因为需要保证数据库一致性,多个写的主机考虑一致性会很麻烦。主从机的备份我们可以
    • 对于需要实时读取最新的,我们可以指定使用主库进行读,主库并非只能用于写
  • 读写分离对于不断加大的体量可能也会力不从心,最后还是需要分库分表。不一开始就分库分表的原因是读写分离相对而言容易实现
    • 分库分表有2种方式:垂直分区和水平分区。水平分区如果同一个表数据分布于不同节点,那么跨节点连接数据集性能较差
  • 读写分离的基础是mysql的主从复制,就如同redis哨兵机制的基础是redis的主从复制一样
  • 读写分离的实现一般有2种:

    • 代码里面动态切换数据源实现
    • 使用外部的中间层实现,如MycAT

      主从复制

  • 主从复制有很多种模式,这里以一主多从为例

    • 主从机的版本最好保持一致
    • 读写分离的变化只会由主库到从库,主库创建表,创建库等都会同步到从库

主服务器需要:1、开启数据库二进制日志功能;2、配置数据库认证唯一服务id;3、获得主库的二进制日志文件名及位置;4、在主库上面创建一个用于主库和从库通信的用户账号,安全管理。
从服务器需要:1、在从库中配置唯一服务id;2、使用主库创建分配的用户账号读取主库的二进制日志;3、启用slave功能,用于主从通信。

配置

  • 主库与从库都要添加或者修改my.cnf配置,一般位于/etc/my.cnf
  • 修改完然后重启主库与从库服务,并执行show variables like 'server_id'查看配置是否生效

    1. log-bin=mysql-bin #开启二进制日志,日志文件名为mysql-bin
    2. server-id=1 #设置当前mysql服务的server-id,别重复
    1. binlog-do-db=test #同步的库
    2. binlog-ignore-db=mysql #不同步的库
    3. binlog-ignore-db=information_schema
    4. binlog-ignore-db=performance_schema
    5. binlog-ignore-db=sys
    6. # 自动清理30天前的log文件
    7. expire_logs_days=30
  • 在主节点进行如下命令:

  • show master status查看主库的相关信息,记录日子名称和pos

    授权

  • mysql8授权里创建与授权是分开进行的,不能一句执行。网络上很多一句执行不行

    1. #不知道为什么还要创建用户,但是不创建会报错
    2. create user 'root'@'10.40.92.22' identified by 'kstdymjd0Mysql=';
    3. #给从库用户授权,允许主从
    4. grant replication slave,replication client on *.* to 'root'@'10.40.92.22';

    进行主从关联

  • 在所有的从节点执行

    1. change master to
    2. master_host = '主节点ip',
    3. master_user= '主库用户名',
    4. master_password='密码',
    5. master_log_file='日志名称',
    6. master_log_pos=日志变化的位置(数字); #对应从库的Read_Master_Log_Pos
    1. show slave status; # 查看从库主从复制是否成功,slave_io_running与slave_sql_running都为yes时才是正确的

    image.png

    1. start slave #开启主从复制
    2. stop slave#关闭主从复制

    网络问题

  • 云服务器上的一般提供了公网ip,而本地主机很有可能没有公网ip。所以会出现本地ping的通云服务器,云服务器ping不通本地的情况

    重启问题

  • 主库如果重启了,pos会变化,从库如果正在进行主从,则

    1. stop slave io_thread 关闭从库同步的进程
    2. 重新进行change ...
    3. start slave

    主从延迟问题

  • 方法1:

    1. 每次从库执行查询请求前,先判断seconds_behind_master (即show slave status结果中代表slave落后于master的秒数)是否已经等于 0。如果还不等于 0 ,那就必须等到这个参数变为 0 才能执行查询请求,seconds_behind_master 参数是用来衡量主备延迟时间的长短。
  • 方法2:
    • 对比位点确保主备无延迟。Master_Log_File 和 Read_Master_Log_Pos,表示的是读到的主库的最新位点,Relay_Master_Log_File 和 Exec_Master_Log_Pos,表示的是备库执行的最新位点。
  • 方法3
    • 对比 GTID 集合确保主备无延迟。Auto_Position=1 ,表示这对主备关系使用了 GTID 协议。Retrieved_Gtid_Set,是备库收到的所有日志的 GTID 集合;Executed_Gtid_Set,是备库所有已经执行完成的 GTID 集合。