mysql深入学习:主从复制,读写分离原理
一、主从复制
1、为什么需要主从复制?
1、在业务复杂的系统中,有这么一个情景,有一句sql语句需要锁表,导致暂时不能使用读的服务,那么就很影响运行中的业务,使用主从复制,让主库负责写,从库负责读,这样,即使主库出现了锁表的情景,通过读从库也可以保证业务的正常运作。主库中负责写操作(INSERT,UPDATE,DELETE),从库负责(SELECT)
2.数据热备份,提升可靠性
- 从库相当于实时备份,主库宕机或数据丢失时,可以快速切换到从库。
3.架构扩展,提升吞吐
- 单机磁盘 I/O、CPU、内存有限。
- 通过增加从库,可以分担读压力,实现横向扩展。
2、什么是 MySQL 主从复制
MySQL 主从复制指的是 主库的数据变更(写操作)会被记录在 binlog 中,然后通过复制机制同步到从库,从库再执行这些操作来保持一致性。
- 默认是 异步复制(主库写成功就返回,不保证从库立即同步)。
- 后续 MySQL 也支持 半同步复制、组复制,提升一致性。
3.主从复制的原理(核心流程)
核心内容:master服务器上的二进制文件binlog
(1)master服务器将数据的改变记录二进制binlog日志,当master上的数据发生改变时,则将其改变写入二进制日志中;
(2)slave服务器会在一定时间间隔内对master二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/OThread请求master二进制事件
(3)同时主节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至从节点本地的中继日志中,从节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后I/OThread和SQLThread将进入睡眠状态,等待下一次被唤醒。
可以概括为三类线程+两类日志
- 主库线程:
- binlog dump 线程:专门把主库的 binlog 发送给从库。
- 从库线程:
- I/O 线程:从主库获取 binlog,写入到 relay log(中继日志)。
- SQL 线程:从 relay log 读取 binlog 内容,解析并执行,更新数据。
- 日志:
- binlog(二进制日志):主库记录的数据变更。
- relay log(中继日志):从库的临时存储,用来重放主库的 binlog。
还有!主从复制是“从库主动拉取+主库被动推送”
过程可以拆开来看:
- 从库主动发起连接
- 从库的 I/O 线程 会去连主库,告诉主库:
“我现在需要从 binlog 的某个位置(file+pos)开始复制。”
- 从库的 I/O 线程 会去连主库,告诉主库:
- 主库被动响应
- 主库接到请求后,就会创建一个 binlog dump 线程,专门负责把 binlog 中的内容源源不断地“推”给这个从库的 I/O 线程。
- 从库接收 & 存储
- 从库的 I/O 线程 把主库传来的 binlog 内容写到本地的 relay log(中继日志)。
- 从库执行
- 从库的 SQL 线程 再去读 relay log,把里面的内容执行一遍。
4.复制的具体步骤
1、从库通过手工执行change master to 语句连接主库,提供了连接的用户一切条件(user 、password、port、ip),并且让从库知道,二进制日志的起点位置(file名 position 号); start slave
2、从库的IO线程和主库的dump线程建立连接。
3、从库根据change master to 语句提供的file名和position号,IO线程向主库发起binlog的请求。
4、主库dump线程根据从库的请求,将本地binlog以events的方式发给从库IO线程。
5、从库IO线程接收binlog events,并存放到本地relay-log中,传送过来的信息,会记录到master.info中
6、从库SQL线程应用relay-log,并且把应用过的记录到relay-log.info中,默认情况下,已经应用过的relay 会自动被清理purge
注意事项
1--master将操作语句记录到binlog日志中,然后授予slave远程连接的权限(master一定要开启binlog二进制日志功能;通常为了数据安全考虑,slave也开启binlog功能)。
2--slave开启两个线程:IO线程和SQL线程。其中:IO线程负责读取master的binlog内容到中继日志relay log里;SQL线程负责从relay log日志里读出binlog内容,并更新到slave的数据库里,这样就能保证slave数据和master数据保持一致了。
3--Mysql复制至少需要两个Mysql的服务,当然Mysql服务可以分布在不同的服务器上,也可以在一台服务器上启动多个服务。
4--Mysql复制最好确保master和slave服务器上的Mysql版本相同(如果不能满足版本一致,那么要保证master主节点的版本低于slave从节点的版本)5--master和slave两节点间时间需同步
二、读写分离
读写分离一般是搭配主从复制使用的哦,基本原理就是使用master数据库处理写操作,slave数据库处理读操作,master将写操作的变更同步到各个slave节点中。
这样做能减少X锁,S锁冲突发生的概率
1.为什么要读写分离
因为数据库的“写”(写10000条数据可能要3分钟)操作是比较耗时的。
但是数据库的“读”(读10000条数据可能只要5秒钟)。
所以读写分离,解决的是,数据库的写入,影响了查询的效率。
2、读写分离原理
数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。
利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。
3、Mssql读写分离原理以及常见实现方式
读写分离就是只在主服务器上写,只在从服务器上读。
主数据库(Master)负责处理所有的写操作,它维护着完整的数据集。
而从数据库(Slave)通过复制主数据库的数据,提供只读的服务。
基本的原理是让主数据库处理事务性操作,而从数据库处理 select 查询。
实现方式
- 可以直接在Mycat或者其他组件中,根据方法的select,insert进行路由分类,insert路由去主库,select路由去从库,这样性能好,可以直接在程序代码中实现,不需要添加额外的设备作为硬件开支,缺点就是需要主动实现,复杂性高
- 第二种就是基于中间代理层实现,代理服务器接到请求后通过判断后转发到后端数据库,例如Mysql-Proxy(通过自带的lua脚本进行sql判断),或者mycat,Amoeba