分布式基础——复制

226 阅读6分钟

本章介绍分布式系统中「复制」的定义及其优缺点,重点阐述三种常用的复制类型:「单主复制」、「多主复制」和「无主复制」。 注:本文偏向于总结,适用于有一定基础的读者。

定义

复制是指将同一份数据冗余存储在多个节点上,节点间通过网络来同步数据,使之保持一致。一个存储了复制数据的节点称为副本(Replica)

优点

  • 增强可用性和安全性,在多节点的情况下,即使部分节点异常,系统也能继续工作。
  • 增加吞吐量,单节点能够处理的请求具有上限,可通过拓展多节点来增加系统的处理性能。
  • 减少往返时间,客户端可以请求距离较近的节点,以减少网络延迟。

缺点

  • 副本间的同步存在网络延迟,进而导致不一致性
  • 增加了系统的复杂度,需要考虑副本管理、故障恢复等问题。

复制类型

下面将介绍三种常用的复制类型:单主(Single-Master)复制、多主(Multi-Master)复制和无主(Leaderless)复制

单主复制

单主复制也叫「主从复制」或「主从同步」,即指定系统中的一个副本为主节点,客户端的写请求必须发送到主节点;其余的副本称为从节点,从节点只能处理读请求,并从主节点同步最新的数据。

优点

  • 简单易懂,易于实现。
  • 仅仅在主节点执行并发操作,能够保证操作的顺序,避免多节点并发写冲突。
  • 可通过增加从节点来提升读性能

缺点

  • 对于写请求较多的场景,难以进行扩展,因为只有一个主节点。
  • 当主节点宕机时,在选举新主节点期间系统是不可用的

根据系统以何种方式同步数据,可以将单主复制分为三类,分别为同步复制异步复制半同步复制

1. 同步复制

主节点执行完一个写请求(或一个事物)后,必须等待所有的从节点都执行完毕,并收到确认信息后,才可以回复客户端写入成功。

优点提升数据可用性,即使主节点在写入后立即宕机,这次写入的数据也不会丢失。

缺点降低写请求性能,如果某个从节点处理请求缓慢,那么将严重影响整个写请求。

2. 异步复制

主节点执行完写请求后,会立即将结果返回给客户端,无须等待其他副本是否写入完成。

优点不会影响写请求的性能。

缺点:可能影响系统的一致性和持久性,如果客户端发送写请求之后立即向从节点发送读请求,那么读到的数据可能会是未修改的数据。再比如,如果客户端发送写请求后,主节点立即宕机,那么这个写请求作出的修改将会丢失。

3. 半同步复制

是介于同步复制和异步复制的之间的一种复制机制,主节点只需要等待一部分从节点同步写操作并返回成功响应后即可将结果返回客户端。

优缺点自然也是前两者的折衷

多主复制

基于「单主复制」,具有多个节点充当主节点的数据复制方式称为「多主复制」。

优点

  • 增加主节点容错,一个主节点发生故障,其他主节点仍能够工作。
  • 增加写请求性能,多个主节点都能够处理写请求。
  • 减少往返时间,可以将写请求路由到距离自己最近的主节点,减少网络延迟。

缺点

  • 极大增加复杂性,由于多个主节点都能执行写操作,故需要复杂的机制来处理并发冲突问题。

「多主复制」和「单主复制」最显著的区别是,由于多主复制不止一个节点处理写请求,且网络存在延迟,这就意味着节点可能会对某些请求的正确顺序产生分歧,导致多个节点上的数据不一致,这种现象简称为「数据冲突」。一些常见的解决方案有客户端解决冲突最后写入胜利因果关系追踪

  1. 客户端解决冲突。客户端下次读取系统中数据的时候,如果数据存在冲突,则将所有冲突的数据返回给客户端,由客户端选择合适的数据并返回给存储系统。(例如购物车)
  2. 最后写入胜利(LWW,Last Write Win) 。让系统中的每个节点为每个写入请求标记上唯一时间戳或唯一自增ID,当冲突发生时,选择具有最新时间戳或最新ID的数据,并丢弃其他写入的数据。
  3. 因果关系跟踪。系统使用一种算法来跟踪不同请求之间的因果关系,并以此判断请求的先后顺序。例如「发帖」写请求一定在「回帖」写请求之前。

另外,还有一种被称为**无冲突复制数据类型(Conflict-Free Replicated Data Type, CRDT)**的数据结,能够根据一定规则自动解决冲突,副本之间不需要额外的协调和冲突处理。

无主复制

顾名思义,该复制技术完全没有主节点,它的基本思想是,客户端不仅向一个节点发送写请求,而是将请求发送到多个节点,之后一旦得到其中一些节点的确认响应,就认为这次写成功了。

优点

  • 对节点故障的容忍度更高,只要节点数量满足「写入数量」,系统就可以正常运行。(「写入数量」这一词后文将在后文作出解释)

缺点

  • 带来的并发冲突更多,因为每个节点都可以处理写操作。

基于Quorum的数据冗余机制

Quorum(法定人数)机制是分布式系统中用来保证数据冗余最终一致性的一种算法。在无主复制中,Quorum机制用于多副本数据的一致性维护,即前面提到的客户端要向一些节点发送读写请求,Quorum机制用于确定到底要多少个节点才足够,以及如果我们增加或减少读写请求的节点数量,系统会发生怎样的变化。

基于Quorum的数据冗余机制保证了在一个由N个节点组成的系统中,我们要求至少W个节点写入成功,并且需要同时从R个节点中读取数据,只要W+R>NW>N/2,则读取的R个返回值中至少包含一个最新的值。(例如,在3节点系统中,如果要求2个节点写入成功,那么至少要从2个节点读取数据,才能保证读取到的值中至少包含一个最新值。如果只从1个节点读取数据,那么就有可能只读到旧值)