这是我参与2022首次更文挑战的第21天,活动详情查看:2022首次更文挑战
数据复制【数据库数据同步与一致性】
在引言中提到了数据分布的两种方式:复制与分区
复制的优势:
- 可以选取与用户更接近的主机为用户提供服务,降低访问的延迟
- 冗余提高可用性
- 以集群的方式提供服务,可以增加带宽、吞吐量
主从模式
主从复制过程:
-
先写入主数据库
-
由主数据库将新的数据发送给从数据库\
-
- 同步与异步复制
\
- 读取数据可以从主数据库也可以从从数据库进行读取
同步与异步复制
主要的区别在于主节点是否需要等待其他从节点的完成复制的确认,如果需要等待,为同步复制,如果不需要则为异步复制
-
异步复制的缺点\
-
- 在异步复制中从节点与主节点会有一定的延迟,并且无法保证两者之间的延迟的详细情况,从数据库和主数据库会出现数据不一致的情况
- 如果主节点与从节点没有完成复制,主节点发生失败且不可恢复,则会导致数据丢失
\
-
同步复制的缺点\
-
- 单点阻塞问题,一个从节点没有完成复制,会阻塞整个数据库系统的吞吐能力
\
-
异步复制的优点\
-
- 从节点未完成复制,主节点依旧可以进行响应,有着更好的吞吐性能
- 对于在地理位置分布广泛,数据之间延迟较大的情况,有着更好的服务性能
\
-
同步复制的优点\
-
- 数据一致性的保证
新节点的配置
比较简单,在Redis、MySQL中采用的都是类似的思想
- 主数据库产生快照数据
- 新的节点接受主数据库快照
- 主数据库记录下产生快照之后的命令,等新节点完成快照数据的加载之后,发送给新的节点
- 新节点接受主数据库的追加写入命令
思考题:当主数据库接受新的写入命令很快的时候,以至于带宽超过了新节点的写入速度,怎么处理?
失效节点处理
-
从节点失效\
-
- 和新节点配置中的追加数据备份类似
\
-
主节点失效(切换主节点)\
-
-
确认主节点失效,在不同的系统中失效的判断有所不同,如Redis Sentinel中分为主观下线和客观下线,每一级别的判断标准都不一样
-
主节点选举,也是一个很广泛的大问题
-
配置新的主节点,让原来的主节点降级,并且将路由导向新的主节点
-
其中存在的问题\
-
- 新主节点没有完全和主节点同步之后就升级称为了主节点,如果采取和其他的节点进行同步的同时,接受客户端发来的请求,可能会出现命令冲突的情况,在多数数据库采用的方法是放弃同步
- 主节点选举中出现脑裂的问题
- 超时检测如何设置,过长的超时时间,会导致数据恢复或者缺失数据的时间越长,如果超时时间设置过短,会导致不必要的切换,可能会加剧网络负担
-
\
思考题:如何解决上述问题
主从复制的实现
-
基于修改语句的复制\
-
-
主节点会将写请求都发送给从节点
-
不适用的场合\
-
- 调用与非确定时间相关的语句
- 在同步执行语句的时候,对已有数据的变动操作,执行顺序需要和主节点保持一致
-
\
-
基于预写日志(WAL)传输\
-
-
前文所提到了两种引擎的数据库系统(基于LSM-Tree、基于BTree),在写入数据库之间,会把数据先写入缓存区域,可以将这些缓存区域的数据发送给从节点进行数据的备份
-
缺点\
-
- 较为底层,与数据库引擎、版本紧耦合
-
\
-
基于行的逻辑日志复制\
-
- 将复制与存储分离,复制引擎独立于存储引擎,相当于做机器翻译增加中间的共同语言层
- 对于删除和更新,可以通过主键或者是其他唯一标识信息来得到对应的行
- 如果涉及到多行的操作,会产生多条日志
\
-
基于触发器的复制\
-
- 由应用层进行复制控制权的管理,通过工具获取数据库的变更情况,触发自己写的应用层代码,有更高的自由度、灵活度
- 性能更差
复制中的可用性与一致性问题
一致性问题
在实际使用中,冗余主要有两个目的,一个是提高系统的可用性,一个是提高系统的吞吐能力
- 如果使用同步复制,越多的节点意味着越多的不确定性,单点阻塞问题带来的可用性降低
异步复制可能会出现从数据库与主数据库数据不一致的情况,当客户端使用从数据库,数据就对不上了
- 如果一段时间都没有写命令,从数据库通过接收主数据库发送的追加命令,可以达到最终一致
\
抽象越高,兼容性越强