https://blog.csdn.net/m0_53157173/article/details/128061594
https://blog.51cto.com/feishujun/5522225
单节点
单节点模式存在的问题:
- 并发量太小,大量读写请求打在同一个节点,处理不过来。
- 假如果节点挂了(无论什么原因),那么就可能会丢失数据。
主从复制
主节点可写可读,从节点只可读。从节点通过复制日志(replication log)记录或变更流(change stream)进行复制同步主节点数据。
解决了什么问题
- 读写分离,并发能力提高。
- 主从备份,可以增加数据安全性。
产生了什么问题
- 主节点挂了,怎么选举从节点?
- 从节点与主节点的数据不是强一致性,可能落后一段时间。(新增从节点或者复制网络延迟)
新增从节点怎么办?
- 不能直接复制某个节点快照,因为数据一直在发生变化。
- 不能将数据库停机复制,这将违反高可用
解决方式: Redis的思想RBD+AOF
- 主节点产生一个快照
- 从节点对快照数据进行同步
- 从节点将主节点快照以后的数据更改日志再进行同步
- 主从节点数据复制完成
主节点挂了怎么办?
-
确认主节点挂了。
基于超时机制,发送心跳包 -
选举新的主节点。
选取与主节点同步最完整(数据滞后最少)的从节点 -
配置使新主节点生效,原主节点降为从节点
产生问题
- 从节点不可能时时刻刻与主节点完全同步,这就导致会有数据丢失。
- 如果Redis先缓存了数据,而节点数据丢失,那么会发生缓存不一致的问题。
- 会出现脑裂的问题,同时有多个主节点。
- 超时时间的选择问题。
从节点挂了怎么办?
待从节点恢复后,根据本地复制日志,查找到崩溃前一个事务,然后请求主库同步所有变更,这样从库就能追赶上主库。
复制日志的实现
- 基于语句的复制
主节点将语句发送给从节点
- 传输预写日志
数据将写入都存进日志,主节点发送日志给从节点。 - 逻辑日志复制(基于行)
mysql binlog - 基于触发器的复制
数据库发生变化时,自动执行触发器中的代码,消耗较大。
复制滞后
读自己写
在主从复制架构中,主节点与从节点的数据不可能强一致性(除非是同步写),这样就会出现一种情况:
clientA 写进主节点数据,然后在从节点读数据时候消失不见。(自己写进去的,自己却读不到了)
解决方式:
- 访问可能修改的数据时直接从主节点进行读取,但是假如可能修改的数据过多,那么主从架构的优势就没显示出来
- 统计主从复制需要的时间,如果读取时间间隔超过复制时间,那么直接在从线程读,否则主线程。