读写分离主要目的就是分摊主库的压力。
读写分离主要有两种架构:客户端直连和中间代理层proxy
- 客户端直连:性能好、架构简单、排查方便,伴随组件Zookeeper一起用
- proxy架构:对客户端友好,客户端不需要关注后端细节,架构复杂,需要高可用架构
应对主备延迟的几种方案
- 强制走主库
- sleep
- 判断主备无延迟
- 配合semi-sync
- 等主库位点
- 等GTID
1. 强制走主库
将查询分类,对必须要拿到最新结果的查询,就强制走主库,其它就走从库
2. sleep
主库更新后,读从之前先sleep一下
3. 判断主备无延迟
每次从库执行查询请求前,先判断 seconds_behind_master 是否已经等于 0。如果还不等于 0 ,那就必须等到这个参数变为 0 才能执行查询请求。
seconds_behind_master 的单位是秒,如果你觉得精度不够的话,还可以采用对比位点和 GTID 的方法来确保主备无延迟,也就是我们接下来要说的第二和第三种方法。
4. 配合semi-sync
要解决这个问题,就要引入半同步复制,也就是 semi-sync replication。
semi-sync 做了这样的设计:
- 事务提交的时候,主库把 binlog 发给从库;
- 从库收到 binlog 以后,发回给主库一个 ack,表示收到了;
- 主库收到这个 ack 以后,才能给客户端返回“事务完成”的确认。
也就是说,如果启用了 semi-sync,就表示所有给客户端发送过确认的事务,都确保了备库已经收到了这个日志。
5. 等主库位点
- trx1 事务更新完成后,马上执行 show master status 得到当前主库执行到的 File 和 Position;
- 选定一个从库执行查询语句;
- 在从库上执行 select master_pos_wait(File, Position, 1);
- 如果返回值是 >=0 的正整数,则在这个从库执行查询语句;
- 否则,到主库执行查询语句。
6. 等GTID
从MySQL 5.6.5 开始新增了一种基于 GTID 的复制方式。通过 GTID 保证了每个在主库上提交的事务在集群中有一个唯一的ID。这种方式强化了数据库的主备一致性,故障恢复以及容错能力。
GTID (Global Transaction ID)是全局事务ID,当在主库上提交事务或者被从库应用时,可以定位和追踪每一个事务。
GTID 的执行流程就变成了:
- trx1 事务更新完成后,从返回包直接获取这个事务的 GTID,记为 gtid1;
- 选定一个从库执行查询语句;
- 在从库上执行 select wait_for_executed_gtid_set(gtid1, 1);
- 如果返回值是 0,则在这个从库执行查询语句;
- 否则,到主库执行查询语句。
网友评论