标签:另一个 term 文件 高可用 体系结构 分片 分布式 设计理念 无法
复制意味着在通过网络连接的多台机器上保留相同数据的副本。复制的困难之处在于处理复制数据的变更。我们将
讨论三种流行的变更复制算法:单领导者,多领导者和无领导者。几乎所有分布式数据库都使用这三种方法之一。
存储数据库副本的每个节点称为副本。当存在多个副本时,会不可避免的出现一个问题:如何确保所有数据都落在了所有的副本上?
每一次向数据库的写入操作都需要传播到所有副本上,否则副本就会包含不一样的数据。最常见的解决方案被称为基于领导者的复制也称主动/被动 或 主/从复制,它的工作原理如下:
这种复制模式是许多关系数据库的内置功能,如PostgreSQL,MySQL,Oracle Data Guard 和SQL Server的AlwaysOn可用性组。 它也被用于一些非关系数据库,包括MongoDB,RethinkDB和Espresso。 最后,基于领导者的复制并不仅限于数据库:像Kafka和RabbitMQ高可用队列这样的分布式消息代理也使用它。 某些网络文件系统,例如DRBD这样的块复制设备也与之类似。
同步复制的优点是,从库保证有与主库一致的最新数据副本。如果主库突然失效,我们可以确信这些数据仍然能在从库上上找到。缺点是,如果同步从库没有响应(比如它已经崩溃,或者出现网络故障,或其它任何原因),主库就无法处理写入操作。主库必须阻止所有写入,并等待同步副本再次可用。
因此,将所有从库都设置为同步的是不切实际的:任何一个节点的中断都会导致整个系统停滞不前。实际上,如果在数据库上启用同步复制,通常意味着其中一个跟随者是同步的,而其他的则是异步的。如果同步从库变得不可用或缓慢,则使一个异步从库同步。这保证你至少在两个节点上拥有最新的数据副本:主库和同步从库。 这种配置有时也被称为半同步。
通常情况下,基于领导者的复制都配置为完全异步。 在这种情况下,如果主库失效且不可恢复,则任何尚未复制给从库的写入都会丢失。 这意味着即使已经向客户端确认成功,写入也不能保证持久。 然而,一个完全异步的配置也有优点:即使所有的从库都落后了,主库也可以继续处理写入。
客户端不断向数据库写入数据,数据总是在不断变化,标准的数据副本会在不同的时间点总是不一样。复制的结果可能没有任何意义。可以通过锁定数据库(使其不可用于写入)来使磁盘上的文件保持一致,但是这会违背高可用的目标。拉起新的从库通常并不需要停机。从概念上讲,过程如下所示:
其中一个从库需要被提升为新的主库,需要重新配置客户端,以将它们的写操作发送给新的主库,其他从库需要开始拉取来自新主库的数据变更。步骤如下:
在最简单的情况下,主库记录下它执行的每个写入请求并将该语句日志发送给其从库。对于关系数据库来说,这意味着每个 INSERT , UPDATE 或 DELETE 语句都被转发给每个从库,每个从库解析并执行该SQL语句,就像从客户端收到一样。但有很多问题会搞砸这种复制方式:
WAL包含哪些磁盘块中的哪些字节发生了更改。这使复制与存储引擎紧密耦合。如果数据库将其存储格式从一个版本更改为另一个版本,通常不可能在主库和从库上运行不同版本的数据库软件。
另一种方法是,复制和存储引擎使用不同的日志格式,这样可以使复制日志从存储引擎内部分离出来。这种复制日志被称为逻辑日志,以将其与存储引擎的(物理)数据表示区分开来。
关系数据库的逻辑日志通常是以行的粒度描述对数据库表的写入的记录序列:
修改多行的事务会生成多个这样的日志记录,后面跟着一条记录,指出事务已经提交。MySQL的二进制日志(当配置为使用基于行的复制时)使用这种方法
触发器是注册在数据库系统中,发生数据更改(写入事务)时自动执行的自定义应用程序代码。触发器有机会将更改记录到一个单独的表中,使用外部程序读取这个表,再加上任何业务逻辑处理,会后将数据变更复制到另一个系统去。
基于主库的复制要求所有写入都由单个节点处理,但只读查询可以由任何副本处理。所以对于读多写少的场景,一个选择是创建很多从库。在这种扩展体系结构中,只需添加更多的追随者,就可以提高只读请求的服务容量。但是,这种方法实际上只适用于异步复制。不幸的是,当应用程序从异步从库读取时,如果从库落后,它可能会看到过时的信息。下面是一些可能的解决方案
如果用户重新加载页面,他们总会看到他们自己提交的任何更新。它不会对其他用户的写入做出承诺:其他用户的更新可能稍等才会看到。它保证用户自己的输入已被正确保存。
如果用户从不同从库进行多次读取,就可能发生这种情况。首先查询了一个延迟很小的从库,然后是一个延迟较大的从库。
单调读取仅意味着如果一个用户顺序地进行多次读取,则他们不会看到时间后退,即,如果先前读取到较新的数据,后续读取不会得到更旧的数据。
如果一系列写入按某个顺序发生,那么任何人读取这些写入时,也会看见它们以同样的顺序出现。
这是分区(分片)数据库中的一个特殊问题:不同的分区独立运行,因此不存在全局写入顺序,当用户从数据库中读取数据时,可能会看到数据库的某些部分处于较旧的状态,而某些处于较新的状态。
在数据中心之间,每个数据中心的主库都会将其更改复制到其他数据中心的主库中。
多领导者复制的最大问题是可能发生写冲突,这意味着需要解决冲突。实现冲突合并解决有多种途径:
在一些无领导者的实现中,客户端直接将写入发送到到几个副本中,而另一些情况下,一个协调者节点代表客户端进行写入。但与主库数据库不同,协调者不执行特定的写入顺序。在无领导配置中,故障切换不存在。
假设三个副本中的两个承认写入是足够的:在用户已经收到两个确定的响应之后,我们认为写入成功。客户简单地忽略了其中一个副本错过了写入的事实。
如果有n个副本,每个写入必须由w节点确认才能被认为是成功的,并且我们必须至少为每个读取查询r个节点,(在我们的例子中,n = 3,w = 2,r = 2)。只要w + r>n,我们期望在读取时获得最新的值,因为r个读取中至少有一个节点是最新的。遵循这些r值,w值的读写称为法定人数(quorum) 的读和写。
标签:另一个 term 文件 高可用 体系结构 分片 分布式 设计理念 无法
原文地址:https://www.cnblogs.com/Ryan16231112/p/12305934.html