Skip to content

Mysql 主从和读写分离

Mysql 主从

什么是 Mysql 主从复制?

主从复制是指数据可以从一个 MySQL 数据库服务器主节点通过 binlog 日志复制到一个或多个从节点,默认采用异步复制方式。

优点:

  1. 让主库负责写,从库负责读,当主库出现了锁表的情景,通过读从库也可以保证业务的正常运作;
  2. 可以做数据的热备;
  3. 进行架构的扩展,可降低磁盘 I/O 访问的频率,提高单个机器的 I/O 性能。

主从复制原理

  1. change ,start slave 语句后,从库获取主库复制信息,启动复制线程
  2. IO 线程,读取 master.info 获取连接信息,连接主库,主库分配 DUMP
  3. IO 线程,通过 http://master.info 获取复制信息,向主库 Dump 线程请求 binlog
  4. DUMP 返回 binlog 日志信息。
  5. IO 线程 接收日志。存储到 TCPIP 缓存中。
  6. IO 线程写日志到 relaylog 中,更新 master.info
  7. SQL 线程读取 relay-log.info ,执行新的 relay。更新 relay-log.info
  8. relaylog 定期自动删除
  9. 主库有通知从库有新日志产生。

Mysql 主从配置

参考 Mysql 主从部署

读写分离

什么是读写分离?

读写分离主要是为了将对数据库的读写操作分散到不同的数据库节点上。这样的话,就能够小幅提升写性能,大幅提升读性能。

一般情况下,我们都会选择一主多从,也就是一台主数据库负责写,其他的从数据库负责读。主库和从库之间会进行数据同步,以保证从库中数据的准确性。这样的架构实现起来比较简单,并且也符合系统的写少读多的特点。

读写分离会带来什么问题?如何解决?

问题:

读写分离对于提升数据库的并发非常有效,但是,同时也会引来一个问题:

主库和从库的数据存在延迟,比如你写完主库之后,主库的数据同步到从库是需要时间的,这个时间差就导致了主库和从库的数据不一致性问题。这也就是我们经常说的主从同步延迟

解决方案:

  • 强制将读请求路由到主库处理

既然你从库的数据过期了,那我就直接从主库读取嘛!这种方案虽然会增加主库的压力,但是,实现起来比较简单,也是我了解到的使用最多的一种方式。

比如 Sharding-JDBC 就是采用的这种方案。通过使用 Sharding-JDBC 的 HintManager 分片键值管理器,我们可以强制使用主库。

java
HintManager hintManager = HintManager.getInstance();
hintManager.setMasterRouteOnly();
// 继续 JDBC 操作
HintManager hintManager = HintManager.getInstance();
hintManager.setMasterRouteOnly();
// 继续 JDBC 操作

对于这种方案,你可以将那些必须获取最新数据的读请求都交给主库处理。

  • 延迟读取

还有一些朋友肯定会想既然主从同步存在延迟,那我就在延迟之后读取啊,比如主从同步延迟 0.5s,那我就 1s 之后再读取数据。这样多方便啊!方便是方便,但是也很扯淡。

不过,如果你是这样设计业务流程就会好很多:对于一些对数据比较敏感的场景,你可以在完成写请求之后,避免立即进行请求操作。比如你支付成功之后,跳转到一个支付成功的页面,当你点击返回之后才返回自己的账户。

ShardingSphere 实现读写分离

TODO