- 随着用户体量不断增大,一个库压力可能越来越大,可以考虑使用读写分离。
- 一般是一主多从,主机用于写,从机用于读。因为需要保证数据库一致性,多个写的主机考虑一致性会很麻烦。主从机的备份我们可以
- 对于需要实时读取最新的,我们可以指定使用主库进行读,主库并非只能用于写
- 读写分离对于不断加大的体量可能也会力不从心,最后还是需要分库分表。不一开始就分库分表的原因是读写分离相对而言容易实现
- 分库分表有2种方式:垂直分区和水平分区。水平分区如果同一个表数据分布于不同节点,那么跨节点连接数据集性能较差
- 读写分离的基础是mysql的主从复制,就如同redis哨兵机制的基础是redis的主从复制一样
读写分离的实现一般有2种:
主从复制有很多种模式,这里以一主多从为例
- 主从机的版本最好保持一致
- 读写分离的变化只会由主库到从库,主库创建表,创建库等都会同步到从库
主服务器需要:1、开启数据库二进制日志功能;2、配置数据库认证唯一服务id;3、获得主库的二进制日志文件名及位置;4、在主库上面创建一个用于主库和从库通信的用户账号,安全管理。
从服务器需要:1、在从库中配置唯一服务id;2、使用主库创建分配的用户账号读取主库的二进制日志;3、启用slave功能,用于主从通信。
配置
- 主库与从库都要添加或者修改
my.cnf
配置,一般位于/etc/my.cnf
修改完然后重启主库与从库服务,并执行
show variables like 'server_id'
查看配置是否生效log-bin=mysql-bin #开启二进制日志,日志文件名为mysql-bin
server-id=1 #设置当前mysql服务的server-id,别重复
binlog-do-db=test #同步的库
binlog-ignore-db=mysql #不同步的库
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
binlog-ignore-db=sys
# 自动清理30天前的log文件
expire_logs_days=30
在主节点进行如下命令:
show master status
查看主库的相关信息,记录日子名称和pos授权
mysql8授权里创建与授权是分开进行的,不能一句执行。网络上很多一句执行不行
#不知道为什么还要创建用户,但是不创建会报错
create user 'root'@'10.40.92.22' identified by 'kstdymjd0Mysql=';
#给从库用户授权,允许主从
grant replication slave,replication client on *.* to 'root'@'10.40.92.22';
进行主从关联
在所有的从节点执行
change master to
master_host = '主节点ip',
master_user= '主库用户名',
master_password='密码',
master_log_file='日志名称',
master_log_pos=日志变化的位置(数字); #对应从库的Read_Master_Log_Pos
show slave status; # 查看从库主从复制是否成功,slave_io_running与slave_sql_running都为yes时才是正确的
start slave #开启主从复制
stop slave#关闭主从复制
网络问题
云服务器上的一般提供了公网ip,而本地主机很有可能没有公网ip。所以会出现本地ping的通云服务器,云服务器ping不通本地的情况
重启问题
主库如果重启了,pos会变化,从库如果正在进行主从,则
stop slave io_thread 关闭从库同步的进程
重新进行change ...
start slave
主从延迟问题
方法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 集合。