数据复制--多主架构

单主架构有一个很明显的问题:单一主节点处理所有写操作,导致主节点成为写操作的瓶颈,也就是单点问题。这就引出了多主节点的设计,同样的,每次修改发送到任一主节点上,并由这个主节点将修改同步到其他所有节点上。下面是使用多主架构的一些场景:

  1. 跨数据中心的操作
    按照之前所说的单主架构,主节点只能在一个数据中心,从节点则可能分布在不同数据中心,这意味着一次写操作的同步操作需要跨数据中心进行。
    而在多主架构中,可以为每个数据中心都设立主节点。在各个数据中心内类似主从架构,数据中心之间,由主节点负责同步数据。


    跨数据中心的多主架构

简单比较一下多数据中心场景下单主架构和多主架构:

  • 性能:单主架构在发生写操作时,需要很多网络传输进行数据更新操作,单主节点的设计导致多个数据中心对外提供写操作的能力无法扩展;多主架构由就近数据中心主节点处理写入操作,并异步更新到其他数据中心,数据中心之间的网络可以用企业专线来降低延迟,对外提供写服务的能力可以根据主节点数量进行扩展。
  • 数据中心级别的容错:在单主架构中农,若主节点所在数据中心出错,需要从其他数据中心的从节点中选出新的主节点,而在多主架构中,由于各个数据中心都有自己的主节点,可以独立的处理读写请求。

多主架构有个显著的问题:写操作在不同数据中心进行,可能会导致写入冲突的发生。

解决写入冲突

假设在一个协作文档中(比如Google docs,腾讯文档等等),用户1将题目从A修改成了B,用户2将题目从A修改成了C,两次操作时间接近,分别成功的提交到了就近的数据中心并操作成功。当数据中心之间异步同步数据的时候,发生了写入冲突。


写入冲突
同步冲突探测与异步冲突探测

在单主架构中,用户2的写入操作将会被抛弃要求重新写入;而在多主架构中,两个操作可能都会写入成功(在不同的数据中心),在数据中心之间数据同步的时候探测出写入冲突。
显而易见,单主架构可以同步探测到数据冲突,因为所有的写入操作可以看做是串行的,多主架构则是异步探测到冲突。

写入冲突避免

最简单的冲突避免策略就是串行化所有可能会发生冲突的写入操作。比如上面的例子,在路由层按照文档id的哈希值进行路由,保证同一文档的所有写入操作由同一数据中心的同一个主节点处理。这时的多主结构从用户角度来看就是一个单主架构。

数据最终一致性

对于多主架构而言,由于各个主节点接受到的写入操作顺序无法保证,可能会导致不同数据中心的数据更新顺序不同,这时的解决方法是:

  • 给每次写入一个全局唯一id,多个有关联的写入发生时,按id最大的为准,如果这个id是时间戳的话,这种方式叫做最后写入为准
  • 给每个数据中心分配id,对于有关联的写入操作,按数据中心id大的写入为准。
  • 保留所有数据,将冲突解决逻辑交由逻辑代码处理。

冲突自动解决:

  • 无冲突复制数据类型( Conflict-free replicated datatypes, CRDTs)提供了一个数据类型的集合,包括:集合,映射,列表等等。用来自动处理写入冲突。
  • 可合并的持久化数据结构(Mergeable persistent data structures)借鉴了GIT版本控制里的冲突合并方式。
  • 流程转换( Operational transformation)是Google docs背后的冲突合并算法

你可能感兴趣的:(数据复制--多主架构)