复制
分区将数据和负载分配到多个节点,提高了系统的可扩展性和性能。为了提高可用性,除了分区还需要复制(Replication)。
复制是指将同一份数据冗余存储在多个节点上,节点间通过网络来同步数据,使之保持一致。一个存储了复制数据的节点称为副本(Replica)。复制可以和分区一起使用。
好处:(1)增强数据的可用性和安全性。(2)减少往返时间(Round-Trip Time,RTT)。(3)增加吞吐量。单台服务器存在物理上限,多台服务器可以提供更多的服务。
复制带来了高可用性、高性能的同时,也给系统带来了复杂性。
单主复制:
单主复制也叫主从复制或主从同步,客户端的写请求必须发送到主节点,从节点只能处理读请求,并从主节点同步最新的数据。
主节点收到写请求时,除了将数据写入本地存储,还有负责将这次数据变更同步给所有从节点,确保所有的副本保持数据一致。
按照同步方式分为:同步复制、异步复制和半同步复制。
同步复制:
主节点收到一个写请求后,必须等待所有从节点返回完成,主节点才会向客户端返回完成。(显然性能会收到影响)
异步复制:
主节点收到一个写请求后,会立即返回给客户端完成,无需等待从节点。(不会影响性能,但是潜在影响副本数据的一致性和持久性)
半同步复制:
主节点只需要等待至少一个从节点同步写操作并返回完成信息即可,不要求全部节点。
单主复制的优点:
简单易懂,易于实现。仅在主节点执行并发操作,能够保证操作的顺序,避免了考虑各个节点数据冲突。对大量读请求工作负载的系统,单主复制可以增加从节点提高读性能。
单主复制的缺点:
写请求存在瓶颈(依赖主节点)。当主机宕机时,从节点提升到主节点不是及时的,可能造成一些停机时间,甚至错误。
主机宕机时,切换主机一般有两种方法,一手动,需要人工介入,慢。二自动,不需要人工介入,相对危险。
倘若两个从节点同时检测到主节点失效,或者网络分区导致从节点认为主节点失效,但其实主节点仍然正常工作,这两种情况都会导致集群产生两个主节点。这种情况称为“脑裂(SplitBrain)”,两个主节点都在处理写请求,可能造成数据损坏之类的灾难性后果。
多主复制:
对于写请求负载要求严格的系统,一个自然的想法是增加多个主节点来分担写请求的负载。这种由多个节点充当主节点的数据复制方式称为多主复制。
由于多主复制不止一个节点处理写请求,且网络存在延迟,这就意味着节点可能会对某些请求的正确顺序产生分歧,导致多个节点上的数据不一致,这种现象简称为数据冲突。
常见的解决冲突的办法:
由客户端解决冲突:户端解决冲突。这种方法的具体解决方案是,在客户端下次读取系统中冲突数据的时候,将冲突的数据全部返回给客户端,客户端选择合适的数据并返回给存储系统,存储系统以此数据作为最终确认的数据,覆盖所有冲突的数据。、
最后写入胜利(LLW):每个写入请求标记上唯一时间戳或唯一自增ID,当冲突发生时,系统选择具有最新时间戳或最新ID版本的数据,并丢弃其他写入的数据。(分布式系统很难有一个统一的全局时间概念)
因果关系跟踪:系统使用一种算法来跟踪不同请求之间的因果关系,并以此判断请求的先后顺序。例如:一定是先有帖子然后有评论。
多主复制的优点:
增加主节点的容错性。
可以在多个节点上执行写请求,分担写负载的压力。
应用程序可以将写请求路由到不同的主节点,通常来说会路由到地理位置最近的节点,以减少往返时间,提升写请求的响应速度。例如:游戏服务器。
多主复制的缺点:
它的复杂性,由于可以在多个节点上执行写操作,可能经常产生数据冲突。随着节点数量的增加,有时无法很好地解决产生的数据冲突,需要人工干预。极端情况下可能造成数据损坏。。。。
无主复制:
无主复制的基本思想是,客户端不仅向一个节点发送写请求,而是将请求发送到多个节点,在某些情况下甚至会发送给所有节点,客户端将写请求并发地发送给几个节点后,一旦得到其中一些节点的确认响应(我们即将讨论具体需要多少个节点的确认信息),就认为这次写成功了,然后继续发送下一个请求。
无主复制有着不同的协调请求方式,一种是客户端直接将写操作发送到多个副本,而另一种是在节点中选出一个协调节点,客户端将请求发送到协调节点,再由协调节点代表客户端将写操作转发到多个副本,经过多个副本确认后再由协调节点响应客户端。与基于领导者的复制不同,无主复制不强制写操作的顺序。