MySQL主从复制
作用
- 读写分离
Matser负责写
slave负责读
在读多写少的场景下,采用读写分离,可以实现更高的并发访问量。还可以进行负载均衡 - 数据备份
- 高可用性
数据备份实际上是一种冗余的机制,通过这种冗余的方式可以换取数据库的高可用性,也就是当服务器出现故障或宕机的情况下,可以切换到从服务器上,保证服务的正常运行
关于高可用性的程度,我们可以用一个指标衡量,即正常可用时间/全年时间。比如要达到全年99.999%的时间都可用,就意味着系统在一年中的不可用时间不得超过365+2460(1-99.999%) =5.256分钟(含系统崩溃的时间、日常维护操作导致的停机时间等),其他时间都需要保持可用的状态。
原文链接:https://blog.csdn.net/main_Scanner01/article/details/124259050
(跟CAP定理是不是有点关系),CAP定理指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性),最多只能同时三个特性中的两个,三者不可兼得。
原理
主从复制就是基于binlog来进行数据同步的。
binlog是逻辑日志,记录增删改的语句原始逻辑,属于MySQL server层。
图片来自:https://blog.csdn.net/main_Scanner01/article/details/124259050?spm=1001.2014.3001.5502
- 主节点将每次写入的数据都记录在
二进制日志(binlog)
- slave连接到Master,多少个从数据库就建立多少个
binlog dump(二进制日志转储线程)
从库 I/O 线程
会连接到主库,向主库发送请求更新 Binlog。这时从库的 I/O 线程就可以读取到主库的binlog dump thread发送的 Binlog 更新部分,并且拷贝到本地的中继日志(Relay log)
从库 SQL 线程
会读取从库中的中继日志,并且执行日志中的事件,将从库中的数据与主库保持同步。
在实际应用中,主节点和从节点之间的连接可能会出现中断,或者从节点也可能会宕机。为了解决这些问题,MySQL主从复制还提供了基于heartbeat的心跳检测机制,以及基于GTID(全局事务标识符)的数据同步机制,这些机制都可以保证数据的一致性和高可用性
如何实现
主机配置
- 必写
#[必须]主服务器唯一ID
server-id=1
#[必须]启用二进制日志,指名路径。比如:自己本地的路径/log/mysqlbin
log-bin=atguigu-bin
- 选写
#[可选] 0(默认)表示读写(主机),1表示只读(从机)
read-only=0
#设置日志文件保留的时长,单位是秒
binlog_expire_logs_seconds=6000
#控制单个二进制日志大小。此参数的最大和默认值是1GB
max_binlog_size=200M
#[可选]设置不要复制的数据库
binlog-ignore-db=test
#[可选]设置需要复制的数据库,默认全部记录。比如:binlog-do-db=atguigu_master_slave
binlog-do-db=需要复制的主数据库名字
#[可选]设置binlog格式
binlog_format=STATEMENT
从机配置
- 必写
#[必须]从服务器唯一ID
server-id=2
- 选写
#[可选]启用中继日志
relay-log=mysql-relay
主机建立账户并授权
#在主机MySQL里执行授权主从复制的命令
GRANT REPLICATION SLAVE ON *.* TO 'slave1'@'从机器数据库IP' IDENTIFIED BY 'dsg123';
#5.5,5.7
查询Master的状态,并记录下File和Position的值。
show master status;
从机配置需要复制的主机
CHANGE MASTER TO
MASTER_HOST='主机的IP地址',
MASTER_USER='主机用户名',
MASTER_PASSWORD='主机用户名的密码',
MASTER_LOG_FILE='mysql-bin.具体数字',
MASTER_LOG_POS=具体值;
#启动slave同步
START SLAVE;
主从数据延迟
在网络正常的时候,日志从主库传给从库所需的时间是很短的,即T2-T1的值是非常小的。即,网络正常情况下,主备延迟的主要来源是备库接收完binlog和执行完这个事务之间的时间差。
主备延迟最直接的表现是,从库消费中继日志(relay log)的速度,比主库生产binlog的速度要慢。
若想要减少主从延迟的时间,可以采取下面的办法:
- 优化业务逻辑,降低大并发概率;’
- 优化SQL,避免慢SQL, 减少批量操作 ,建议写脚本以update-sleep这样的形式完成。
- 提高从库机器的配置 ,减少主库写binlog和从库读binlog的效率差。
- 实时性要求的业务读强制走主库,从库只做灾备,备份。
主从数据的一致性问题
如果只有一个数据库,那么在数据写操作时可以通过加锁保证一致性。但是主从情况下呢?
1 半同步复制
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relaylog中才返回给客户端。相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。
2 数据库中间件
流程:
1)所有的读写都走数据库中间件,通常情况下,写请求路由到主库,读请求路由到从库
2)记录所有路由到写库的key,在主从同步时间窗口内(假设是500ms),如果有读请求访问中间件,此时有可能从库还是旧数据,就把这个key上的读请求路由到主库。
3)在主从同步时间过完后,对应key的读请求继续路由到从库。
相关的中间件有:
1)canal:是阿里巴巴旗下的一款开源项目,纯Java开发,基于数据库增量日志解析,提供增量数据订阅&消费,目前主要支持了MySQL。
2)otter:也是阿里开源的一个分布式数据库同步系统,尤其是在跨机房数据库同步方面,有很强大的功能。它是基于数据库增量日志解析,实时将数据同步到本机房或跨机房的mysql/oracle数据库。