上周本打工人写了一篇SpringBoot实现读写分离和事务处理的文字,为了赶项目的功能和进度,颇有点囫囵吞枣的意思,只是实现了,但是没有机会和时间坐下来喝杯咖啡好好的研究一下其中的问题,所以才有了这篇续集。
什么是读写分离?
读写分离为了产品的高扩展、高稳定性,而实现的一种的一种数据库架构,一般我们在主库master写数据,在从库slave读数据。常用的是一主多从。
读写分离的原理及主从复制
Mysql 中主从复制时有两个很重要的日志文件:
binlog(二进制日志文件)
relay log(中继日志文件)
上图
在主从同步的过程中,会进行这样的步骤
(1)主库会将所有的操作事件记录在 binlog 中,从库通过开启一个 I/O 线程保持与主库的通信,并在一定时间间隔内探测 binlog 日志文件是否发生改变。
(2)binlog 日志发生了变化,主库生成一个 binlog dump 线程向从库 I/O 线程传送 binlog。
(3)从库上的 I/O 线程将 binlog 复制到自己的 relay log 中。
(4)最终由从库中的 SQL 线程读取 relay log 中的事件重放到从库上。
主从数据库会遇到哪些问题呢?
看到这里,我不禁会想,这样的架构有什么问题,怎么解决?
1.主从库的数据同步会不会有延迟?
2.如果主库挂了咋办?
(1)主从数据延迟产生的原因
1.数据重放过程是随机的,如果relay log来不及重放,就会产生延迟
2.主库高并发。当大量的写数据请求打到主库上,从库这边的线程就会来不及去做数据同步,那么就会造成延迟
3.从库锁等待。当从库执行复杂的读操作,例如数据报表,那么就会锁表,从而造成延迟。
(2)主从数据延迟解决方案建议
既然 SQL 单线程进行重放时速度有限,那我们就采用多线程来进行数据重放。
降低主库的并发,可以采用缓存来缓解主库的压力
读主库
(3)主库挂了
如果我们采用一主多从的架构,那么当我们的主库宕机了,采用什么操作可以将损失降低到最少?
查询了这篇资料,主要分下面几个步骤:
(1)确保所有的relay log全部更新完毕,在每个从库上执行show processlist
(2)更新完毕后,登录所有从库查看master.info文件,对比选择pos最大的作为新的主库,
(3)然后登录这个新的主库,执行stop slave;进入主目录,删除master.Info和relay-log.info配置my.cnf文件开启log-bin文件
(4)创建用于同步的用户并授权slave
(5)登录另外一台从库,执行stop slave停止同步
(6)执行start slave
(7)修改新的master数据,测试slave是否同步更新
从库宕机:
(1)查看从库上mysql的错误日志,里面有记录主从挂掉时的binlog信息。
(2)有了binlog和postion信息后,只需要重新在从库上进行change master to配置即可。配置后开启slave状态,没有报错
(3)查看slave状态,发现slave已经正常了,开始进行延时数据恢复。
最后总结一下,主从数据库的优点
①读写分离,降低主服 务器压力;
②在从主服务器进行备份,避免备份期间影响主服务器服务;
③当主服务器出现问题时,可以切换到从服务器。所以我在项目部署和实施中经常会采用这种方案;鉴于生产环境下的mysql的严谨性。