文章目录
- 1.数据库系统架构发展
- (1)单库架构
- (2)主备架构
- (3)主从架构
- 2.主从复制
- 主从同步配置
- 主从复制模式
- (1)异步复制
- (2)半同步复制
- (3)全同步复制
- 主从复制原理
- 3.主从延时原因
- 4.主从延时解决办法
- (1)数据同步写方案
- (2)选择性强制读主
- (3)中间件选择路由法
- (4)缓存路由法
1.数据库系统架构发展
(1)单库架构
缺点:
- 若数据库出现故障,这段期间业务将会不可用。除了等待重启,没什么解决办法。
(2)主备架构
「主库」出了故障,通过人工方式,手动的将「主机」踢下线,将「备机」改为「主机」继续提供服务。部署维护简单,业务开发也无需任何改造。
缺点:
- 不过缺点也很明显,备库只有在主库有问题的时候才会被启用,存在一定的资源浪费的情况。
(3)主从架构
大多数业务都是读多写少,数据库读最容易成为系统瓶颈。为提高读的性能,可以增加从实例,主从数据同步,实现读写分离。
2.主从复制
主从同步配置
https://www.cnblogs.com/SimpleWu/p/10982640.html
主从复制模式
MySQL主从复制模式主要包含:异步复制、半同步、以及全同步复制三种复制模式。
(1)异步复制
MySQL默认复制是异步的,主库在执行完客户端提交的事务后会立即将结果返给给客户端。
MySQL异步复制并不关心从库是否已经接收并处理,这样就会有一个问题,主如果crash掉了,此时主上已经提交的事务可能并没有传到从库上。所以,后面又出来了一个半同步复制。
(2)半同步复制
半同步复制介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relaylog中才返回给客户端。
相对于异步复制,半同步复制提高了数据的安全性,同时它也造成了一定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。所以,半同步复制最好在低延时的网络中使用。
(3)全同步复制
是指当主库执行完一个事务,然后所有的从库都复制了该事务并成功执行完才返回成功信息给客户端。
因为需要等待所有从库执行完该事务才能返回成功信息,所以全同步复制的性能必然会收到严重的影响。
主从复制原理
- master创建一个dump线程向slave推送binlog。
- slave连接到master的时候,会创建一个IO线程接收binlog,并记录到relay log中继日志中。
- slave再开启一个sql线程读取relay log事件并在slave执行,完成同步。
- slave记录自己的binglog。
3.主从延时原因
一个服务器开放N个链接给客户端来连接的,这样有会有大并发的更新操作, 但是从服务器的里面读取 binlog 的线程仅有一个,当某个 SQL 在从服务器上执行的时间稍长 或者由于某个 SQL 要进行锁表就会导致,主服务器的 SQL 大量积压,未被同步到从服务器里。这就导致了主从不一致, 也就是主从延迟。
4.主从延时解决办法
(1)数据同步写方案
主从数据同步方案,一般采用异步方式同步给从库。可将其修改为同步方案,主从同步完成,主库上的写才能返回。这种方案,我们只需要修改数据库之间同步配置即可,业务层无需修改,相对简单。
- 业务系统发起写操作,数据写主库
- 写请求需要等待主从同步完成才能返回
- 数据读从库,主从同步完成就能读到最新数据
缺点:
- 由于主库写需要等待主从完成,写请求的时延将会增加,吞吐量将会降低。对于在线业务,可能无法接受。
(2)选择性强制读主
对于需要强一致的场景,将其读请求都操作主库,这样「读写都在主库」,就没有不一致的情况。这种方案业务层需要改造一下,将其强制性读主,相对改造难度较低。
缺点:
- 浪费了另一个数据库,增加主库的压力
(3)中间件选择路由法
这种方案需要使用一个中间件(淘宝TDDL,ShardingSphere client版本),所有数据库操作都先发到中间件,由中间件再分发到相应的数据库。
- 写请求,中间件将会发到主库,同时记录一下此时写请求的 key( 操作表加主键等)
- 读请求,如果此时 key 存在,将会路由到主库
- 一定时间后( 经验值),中间件认为主从同步完成,删除这个 key,后续读将会读从库
缺点:
- 系统架构增加了一个中间件,整体复杂度变高,业务开发也变得复杂,学习成本也比较高。
(4)缓存路由法
这种方案与中间件的方案流程比较类似,不过改造成本相对较低,不需要增加任何中间件。
- 写请求发往主库,同时缓存记录操作的 key,缓存的失效时间设置为主从的延时
- 读请求首先判断缓存是否存在
- 若存在,代表刚发生过写操作,读请求操作主库
- 若不存在,代表近期没发生写操作,读请求操作从库
缺点:
- 这种方案相对中间件的方案成本较低,但是呢我们此时又引入一个缓存组件,所有读写之间就又多了一步缓存操作。