分布式数据复制的三种方式

把数据分布到多个节点上有两种常见的方式:复制(Replication)和分区(Partitioning)。现在主要讲下分布式数据复制。

将数据库分布到多台机器上,有多种原因:
可扩展性:数据量、读取负载、写入负载超过单台机器的处理能力。
容错/高可用:单台机器(或多台机器、网络或整个数据中心)出现故障的情况下,仍然能继续工作。多台机器可以提供冗余,一台出现故障,另一台可以接管。
延迟:每个用户可以从地理上最近的数据中心获取服务,避免了等待网络数据包穿越半个世界。

复制(Replication)


不同的节点上保存相同的数据副本,提供了冗余。
复制的难点在于复制的数据变更。主要用三种流行的数据变更算法:单领导者(single leader)、多领导者(multi leader)、无领导者(leaderless)。

单领导者(单主复制)

客户端将所有写入操作发送到单个节点(领导者),该节点将数据更改事件流发送到其他副本(追随者)。读取可以在任何副本上执行,但从追随者读取可能是陈旧的。

存储数据库副本的每个节点称为副本(replica)。当存在多个副本的时候,就要确保所有数据都落在了所有副本上。最常见的解决方案称为基于领导者的复制(leader-based replication),也称主动/被动(active/passvie)或主从(master/slave)复制。主库(leaer/master/primary)负责客户端的数据写入,主库再将数据写入从库,只能从主库写入。从库(follower/read replicas/secondaries/hot-standby)主要负责客户端的数据读取。

复制分同步(synchronously)复制和异步(asynchronously)复制。
同步复制的有点是可以保证从库和主库最新数据的一致,缺点是如果从库没有响应(崩溃/网络故障/其他原因),主库就无法处理写入操作。任何一个节点的中断,都会导致整个系统的停滞不前。可以一个从库是同步,其他是异步,保证两个节点拥有最新数据(主库和同步从库),这种配置也被称为半同步(semi-synchronously)。

异步复制的优点是高可用,即使所有从库都落后了,主库也可以继续处理写入。缺点是如果主库失效,任何尚未复制到从库的数据都会丢失。弱化的持久性虽然是一个不好的折衷,但是异步复制已经被广泛使用,特别是有多个从库/异地分布时。

从库失效,例如宕机/更新补丁重启,需要追赶恢复,从库可以从日志中知道,在发生故障之前处理的最后一个事务。因此,从库可以连接到主库,并请求在从库断开连接时发生的 所有数据变更。

主库失效,需要故障转移,在从库里选一个主库。故障转移会出现不少麻烦,例如数据丢失、数据不一致、脑裂(多个主库)、主库失效时长判定等。

基于主库的复制底层有几种不同的复制方式:基于语句的复制、传输预写式日志(WAL)、逻辑日志复制(基于行)、基于触发器的复制。

复制延迟问题:
读己之写(写后读/读写一致性 read-after-write consistency):用户应该总是看到自己提交的数据。
单调读(时光倒流 moving backward in time):当用户在某个时间点看到数据后,他们不应该在较早的时间点看到数据。
一致前缀读(违反了因果律):用户应该将数据视为具有因果意义的状态:例如,按照正确的顺序查看问题及其答复。

复制延迟的解决方案:事务。

多领导者(多主复制)

客户端发送每个写入到几个领导节点之一,其中任何一个都可以接受写入。领导者将数据更改事件流发送给彼此以及任何跟随者节点。

多主复制的应用场景:运维多个数据中、需要离线操作的客户端、协同编辑。

多领导者复制的最大问题是可能发生写冲突,这意味着需要解决冲突。
避免冲突的方法:可以确保来自特定用户的请求始终路由到同一数据中心,并使用该数据中心的领导者进行读写。

收敛一致:多个主库同时更新,要确定一个是“更正确”的,所有副本必须在所有变更复制完成时收敛至一个相同的最终值。
解决途径:唯一的ID(LWW last write win),丢弃并发写入;一个副本一个唯一ID,也容易丢失数据;这些值合并;保留所有数据结构记录,自定义编写应用程序代码;
自定义冲突解决逻辑:写时执行、读时执行。

多主复制拓扑:复制拓扑描述写入从一个节点传播到另一个节点的通信路径。最普遍的拓扑是全部到全部。

无领导者(无主复制)

客户端发送每个写入到几个节点,并从多个节点并行读取,以检测和纠正具有陈旧数据的节点。

无主复制没有主库的概念,允许任何副本直接接受来自客户端的写入。Cassandra和Voldemort是由Dynamo启发的无领导复制模型的开源数据存储,所以这类数据库也被称为Dynamo风格。使用此方法的数据库还有CouchDB。
当一个客户端从数据库中读取数据时,它不仅仅发送它的请求到一个副本:读请求也被并行地发送到多个节点。客户可能会从不同的节点获得不同的响应。即来自一个节点的最新值和来自另一个节点的陈旧值。版本号用于确定哪个值更新,合并同时写入的值。

在一个不可用的节点重新联机之后,它如何赶上它错过的写入?
1、读修复(Read repair):当客户端并行读取多个节点时,它可以检测到任何陈旧的响应。这种方法适用于频繁阅读的值。
2、反熵过程(Anti-entropy process):一些数据存储具有后台进程,该进程不断查找副本之间的数据差异,并将任何缺少的数据从一个副本复制到另一个副本。与基于领导者的复制中的复制日志不同,此反熵过程不会以任何特定的顺序复制写入,并且在复制数据之前可能会有显着的延迟。

区别

每种方法都有优点和缺点。单主复制是非常流行的,因为它很容易理解,不需要担心冲突解决。在出现故障节点,网络中断和延迟峰值的情况下,多领导者和无领导者复制可以更加稳健,但代价很难推测,只能提供非常弱的一致性保证。

复制可以是同步的,也可以是异步的,在发生故障时对系统行为有深远的影响。尽管在系统运行平稳时异步复制速度很快,但是在复制滞后增加和服务器故障时要弄清楚会发生什么, 这一点很重要。如果一个领导者失败了,并且你推动一个异步更新的追随者成为新的领导者,那么最近承诺的数据可能会丢失。

分区(Partitioning)

将大数据集拆分成较小的子集,这样的子集称为分区(partitions)或分片(shard),不同的分区可以指派给不同的节点(node)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小龙在山东

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值