DDIA 数据复制(多主节点 无主节点)

267 阅读5分钟

这是我参与2022首次更文挑战的第23天,活动详情查看:2022首次更文挑战

多主节点数据复制

主节点上面再增加一层主节点,第二层主节点依旧有主节点的特性,其下面有其他的从节点进行主从复制

和主从模式主要差异:

  • 多个库支持用户写入

在一般情况下使用地并不多,在进行数据库热备份时会用到,可以实现服务故障容灾

  • 两层的主节点都可以进行数据的写入读取,第一层主节点需要处理不同层主节点之间的数据差异

  • 用户体验更好,数据写入可以在本地这个更加靠近自己的数据库写入,拥有更高的性能,由中央主节点进行数据的冲突解决
  • 失效转移(容灾),中央主节点宕机可以选取其他主节点继续进行,异步的数据冲突解决工作
  • 网络问题容忍度更高,异步数据同步带来的好处

类似问题:

  • 本地与服务器数据
  • 协作编辑、在线文档

写冲突解决

前面提到中央主节点需要解决其他主节点之间的数据冲突问题(感觉有点像git的冲突解决)

如何检测

采用异步同步的时候进行异步的数据同步,在这个时候进行冲突检测

  • 如果采用同步的阻塞意味着不同的主节点之间需要相互等待彼此数据的写入完成,变成了类似主从模式导致失去了主主复制的优势

冲突避免

类似之前主从分布中,有关联的数据分布在不同的数据库分区中,可以通过相关的数据都在一个区同一写入,可以避免冲突的产生

收敛于一致状态

在主从分布中,对于需要注意使用最新数据的地方都采用了版本号时间戳的方式进行标记

  • 每一次修改都会带上当时的时间戳,解决冲突的时候,以最新的数据为准(或者制定一个不同版本数据计算最终结果的方案)

应用层解决

在有冲突的时候,许多数据库都提供切换到应用层进行冲突的解决

\

上述机制都是通过程序员约定的方式进行问题的解决,其实有专门的机制进行自动的冲突解决

  • 无冲突的复制数据类型(CRDT),数据结构本身就支持多用户同时进行编辑,有内置的方案进行数据冲突的解决
  • 可合并的持久数据结构,通过跟踪变更记录的方式进行版本控制,类似git
  • 操作转换(Operational transformation),常用于协作文档的冲突解决

拓扑结构

用于描述不同的主节点之间写入数据的传播过程

无主节点复制

所有的副本都支持直接接受客户端的请求

  • 客户端直接对多副本统一进行写操作
  • 由一个类似代理节点,帮助客户端进行统一的写操作

节点失效时写入数据

在客户端进行数据读取的时候,会从多个副本获取数据,可以通过时间戳标志的方式来判断最新数据

  • 这种方式不会有类似主从模式的单点阻塞问题吗?

数据修复

读修复:

读取到多个副本的时候,会重新向已过期的副本重新发起写入请求

不会出现读取到

  • 适合频繁读取的场合

反熵过程:

有专门的后台进程在寻找不同副本之间的区别

会有一定延迟,需要等到后台进程扫描到

读写确认

如果有n个节点,w个法定票数(判定是否写入成功),读取至少需要r个节点,则只要 w + r > n 则读取到的数据必然包含最新值

  • w + r定义了系统可容忍的失效节点数
  • 当w < n,如果一个节点不可用,仍然可以正常写入
  • 当r < n,如果一个节点不可用,仍然可以正常读取
  • 假定n=3,w=2,r=2,可以容忍一个节点失效
  • 假定n=5,w=3,r=3,可以容忍两个节点失效

(失效不一定读取和写入的时候失效的是同样的节点,有可能会尽可能错开)

需要保证的是r w在每次读的时候会有重叠节点

\

数据库一般会提供不同节点执行复制日志当前的偏移量,可以通过对比偏移量了解到当前的复制进度

在某一些场合,数据库大部分节点客户端都没有办法连接上,无法达到w r,那么可以采取更加宽松的策略,先有临时节点接收数据,当可以连接上数据库其他节点的时候,临时节点将这些数据发送给原始节点,可以提供更加高的可用性

\

并发写入

当多个客户端同时对无主节点集群发起写入信号,写信号到达不同节点的时间并不一样,实际无法确认哪一个是最新写入的,在这种情况下,并不关心一开始的发起顺序,每一个节点都使用该节点最新的写入数据,在读取的时候使用最大的时间戳数据,也即LWW(最后写入者获胜)

如何判断是否是并发写入

并发写入定义:写入操作之间没有明确的先后依赖顺序,都为并发写入,包括两者都不知道彼此的存在,发起了实际上有先后顺序的操作

并发判断算法

实际上是计算两个操作之间有没有前后依赖关系

\

复制中主要关注的几个问题:

  • 性能(同步与异步)
  • 如何进行数据同步?
    • 同步中读取数据的一致性问题
    • 同步中写命令的可靠性
    • 如何获取最新数据
  • 可用性与容灾
  • 节点重新上线的数据恢复