读写分离
基本的读写分离有两种模式
- 一种是client主动做负载均衡
- 一种是在client和mysql之间有一个proxy来做代理层,两者的区别
- 客户端直连的方式,查询的性能好一点点,架构简单,排查问题容易些,但是数据迁移,主备切换
等,都会被感知且调整数据库连接信息 - 带proxy的方式,就后端只需要注意在开发逻辑上,连接维护,后端信息维护等,都直接proxy做,但是对维护团队要求比较高
有时候还是会从从库那边读到主库过期的数据,解决方案有以下几种方案
强制走主库方案
- 将查询分类,有的强一致的就走主库,业务可以允许弱一致的就走从库,业务用的最多
sleep方案
- 在更新主库后,读从库前,然后页面sleep1s左右,以让从库更新到主库的信息
判断主备无延迟方案
- 读从库之前,先判断second _behind_master是否为0,是的话才读,不是就等待
- Master_Log_File和Read_Master_Log_Pos表示读的是主库最新的位点
Relay_Master_Log_File和Exec_Master_Log_Pos表示从库执行的位点,
对比这四个值,相等即可 - Auto_Position,表示对主备使用GTID协议
Retrieved_Gtid_Set表示备库收到所有日志的GTID集合
Executed_Gtid_Set:表示备库已经执行的所有GTID集合
后两个相等即可
配合semi-sync方案
- 启用semi-sync replication,主库事务提交时,会将binlog发给从库,从库收到之后,返回ack,
- 主库收到ack之后,才给客户端返回事务成功确认
- 所以semi-sync加点位判断的方案,就可以确认一主一从的情况保证从库无延迟,
- 但是在一主多从的情况下,无法保证其他从库是否同步,而且持续延迟的情况,容易出现过度等待
等主库位点方案(判断主库和备库差几秒的延迟,之后再做处理)
- 在从库执行,file和pos表示主库的日志文件和偏移量,timeout表示最多等待几秒,返回一个整数n.表示命令开始到应用完file和pos的位置,已经执行了多少事务,
- 如果同步发生异常,返回null,
- 超过n秒,返回-1,
- 刚开始执行的时候,发现已经执行过了,返回0
select master_pos_wait(file, pos[, timeout]);
等GTID方案
select wait_for_executed_gtid_set(gtid_set, 1);
//等待.直到这个库执行的事务包含传入的gtid_set,返回0,超时返回1
- 和等主库位点方案一样,先从主库查到gtid_set,然后再到从库执行上面那命令,返回0就执行查询,如果返回1,就到主库执行