线性一致性与全序广播------《Designing Data-Intensive Applications》读书笔记12

上一篇聊了聊构建分布式系统所面临的困难,这篇将着重讨论构建容错分布式系统的算法与协议。构建容错系统的最佳方法是使用通用抽象,允许应用程序忽略分布式系统中的一些问题。本篇我们先聊一聊线性一致性,以及与线性一致性有关的技术,后续需要了解的分布式协调服务,如:ZooKeeper等,都是基于分布式系统的线性一致性。

1.更强的一致性

大多数分布式数据库至少提供了最终一致性,这意味着如果停止对数据库的写操作并等待一段时间,最终所有读请求将返回相同的值。但是,这是一个非常弱的一致性保证,所谓的一段时间并不确定。如果写入一个值,然后立即读取它,就不能保证读取到刚才写入的值。

最终一致性的模型对于应用程序开发人员来说是个大烦恼,当使用只提供弱一致性的数据库时,开发人员需要意识到它的问题,数据库可能会有很微妙的错误,因为应用程序可能大部分时间都工作得很好。而当系统中有故障(例如网络中断)或高并发性时,最终一致性的数据模型将会暴露很多问题。所以数据系统可以选择提供的更强的一致性模型,但是又会引入新的Trade-off:有更强一致性的系统虽然更容易正确使用,但是它可能比弱一致性的系统的性能更差或容错性更低,我们需要更好的理解它并且选择最适合需求的数据模型。

线性一致性

线性一致性的思想很简单,我们用下面两幅图来说明:

在一个线性系统之中,一定会有某个时间点(开始和结束的写操作之间),x的值从0变成了1。因此,如果一个客户端的读取x时返回了新值1,所有后续的读取也必须返回新的值。

线性化与串行化

线性化与串行化不同,它不构成事务。因此不能完全保证并发写的安全性。数据库可以同时提供串行化和线性化,如两阶段锁便是可以同时提供串行化与线性化,而序列化的快照隔离不是线性化的。

线性一致性可以解决什么问题?

  • 分布式锁和Leader选举

    单Leader的系统需要确保只有一个Leader,多个Leader会导致脑裂的发生。而Leader选举的本质是锁的争用,每个节点试图获取锁,获取成功的节点成为Leader。而无论如何,这把锁必须是线性化:所有节点都必须同意哪个节点拥有锁,成为Leader

  • 唯一性约束

    唯一性约束在数据库中很常见:例如,用户名或电子邮件地址必须唯一地标识一个用户,而在文件存储服务中,不能有两个具有相同路径和文件名的文件。如果你想为数据写入执行这一约束(例如,如果两人试图同时创建一个用户或一个具有相同名称的文件,其中将返回一个错误),你需要线性化。

如何实现线性化系统?

线性化意味着:如同一个单拷贝的数据,并对其所有的操作都是原子的。最简单的答案就是真的只使用一个单一的数据复制。这种方式显然就失去了容错性,单一节点出现异常则系统将无法访问。而使系统容错的最常用方法是使用副本技术:

  • 单Leader多Follower机制

    在单Leader多Follower机制之中,Leader拥有主副本,Follower在其他节点上维护数据的备份副本。可以选择从Leader上读,或同步更新的Follower,可以在这个基础之上实现线性化系统。

  • 一致性算法

    通过协商一致性协议算法可以防止脑裂和读取过期数据,通过一致性算法可以实现核心数据线性化的安全存储。这是ZooKeeper与Chubby等分布式协调服务的基础算法。

CAP理论与一致性的代价

Eric Brewer在2000年提出CAP理论,简而言之便是:数据系统必须在一致性、可用性、分区容忍性的三角关系之中有所权衡,任何系统没有办法同时满足三种特性。

所以使用线性化的一致性自然会需要在可用性上做一些妥协, 在单Leader多Follower机制之下,需要满足线性化一致性的写入和读取的客户端必须连接到Leader。如果Leader产生中断,仍然可以读取Follower的数据,但此时就无法保证线性化的要求了。

2.全序广播

上文已经提到过,可以通过单Leader多Follower机制与一致性算法来实现一个线性化的系统,但是,这里还有一个很重要的内容我们需要探讨:全序广播

不过先不要着急,咱们先再聊一聊分布式系统之中的时序:

Lamport时间戳

Lamport时间戳是生成因果关系的序列号的一种方法,我们可以通过它理清分布式系统之中操作的顺序,Leslie Lamport 在1978年提出。Lamport时间戳的实现很简单,每个节点有一个唯一计数器标识符,并且每个节点都保存它的计数器。两个节点有时可能具有相同的计数器值,但在计数器值之中都包含节点id,所以每个计数器值都可以认为是唯一的时间戳。

Lamport时间戳没有确切的物理时间,但它可以分布式系统之中的事件排序:存在两个时间戳,一个更大计数器的时间戳是更新的值;如果计数器的值是相同的,一个更大的节点ID是更大的时间戳。下图展示了Lamport时间戳的工作原理,它能够符合分布式系统之中的因果关系:

但是从Lamport时间戳的总顺序来看,无法判断两个操作是并发的,还是它们是因果相关的。虽然Lamport时间戳能够确认操作的因果关系,但是在分布式系统之中仍然存在一些问题:

请考虑一个系统,该系统需要确保用户名唯一标识用户帐户。如果两个用户同时尝试创建具有相同用户名的帐户,则其中一个应该成功,另一个应该失败。显然,如果两个相同的用户名的账户创建,选择具有较低的时间戳的操作成功,因为Lamport时间戳是完全有序的,这种比较是有效的。但是为了确保没有其他节点在同时在较早的时间创建帐户,所以节点不得不与其他每个节点通信进行确认。如果出现网络问题,其他节点中的一个已经失效或无法到达,则系统也将失效。

Lamport时间戳的问题在于:需要收集所有操作之后,操作的总顺序才会出现。如果另一个节点有其他操作,在不知道的情况下,无法构造操作的最终顺序。

全序广播

全序广播的机制是使用:通过单Leader多Follower机制,在Leader节点上对所有操作进行排序,从而决定了整个操作顺序,并将操作顺序进行广播。全序广播可以保证全局知晓信息,而解决Lamport时间戳面临的问题。但是全序广播同样要解决这样几个问题:如果吞吐量大于单Leader的处理量,那么如何扩展系统,以及出现Leader失效的情况,如何进行故障转移。

全序广播要求满足如下两个属性总是被满足:

  • 可靠的交付,没有消息丢失:如果消息被传递到一个节点,它将被传递给所有节点。
  • 完全有序传递,消息以相同的顺序传递给每个节点。

一个正确的全序广播算法必须保证节点和网络故障时的可靠性和有序性。一旦出现网路分化的现象,算法可以保持重试,仍然保持信息的有序性。全序广播对于分布式系统来说有十分重要的意义:如果每个消息表示对数据库的写入,并且每个副本以相同的顺序处理相同的写入,则副本将保持彼此一致,而各个节点的状态机也能够保持一致,可以通过这样的方式来实现状态机复制。

3.通过全序广播实现线性化一致性

全序广播是异步的:消息保证以固定的顺序可靠地传递,但不能保证何时传递消息(因此存在节点可能落后于其他节点)。而线性化一致性能够保证:每次读操作能够读到最新值的写入。我们可以依托于全序广播,在存储上实现线性化一致性:

  • 1.将消息append到日志中,添加要声明的用户名。
  • 2.节点通过内存之中的状态机检查,如果该用户名的第一条消息,则用户名写入成功。否则,终止该操作。

由于全序广播保证了,消息是以相同的顺序传递给所有节点,假设存在并发写入,所有节点都会达成共识,第一个写入用户名的消息。虽然全序广播可以保证程序的线性写入,但是假设进行读操作的节点却不能保证线性读取,因为消息传递的延迟性,所以读操作的结果可能是过时的。

当然这里可以通过返回最新日志消息的位置,通过查询位置,等待所有条目需要读取的条目被写入,再进行读操作,便能够达到读操作的线性一致性。(在ZooKeeper中通过sync()操作实现),或者可以通过强制读取Leader节点的副,显然Leader节点上的数据一定是最新的结果。

小结:

通过全序广播的线性一致性,我们已经可以实现一个分布式系统的的协调服务了。下一篇将聊一聊分布式系统之中的一致性协议,也是分布式系统最核心的概念,我们怎么样能够让分布式的节点达成一致性,难者不会,会者不难,我们下一篇见。

原文地址:https://www.cnblogs.com/happenlee/p/8453659.html

时间: 2024-08-02 02:16:45

线性一致性与全序广播------《Designing Data-Intensive Applications》读书笔记12的相关文章

《Advanced Data Structures》读书笔记

1.基础数据结构 1.1.栈 1.2.队列 1.3 双端队列 1.4.动态分配节点 1.5.数组类的"阴影拷贝" 2.搜索树 3.平衡搜索树 4.区间集合 5.堆 6.并查集 7.变换 8.字符串 9.哈希表 10.附录

分布式系统的一致性算法------《Designing Data-Intensive Applications》读书笔记13

一致性算法是分布式系统中最重要的问题之一.表面上看,这似乎很简单,只是让几个节点在某些方面达成一致.在本篇之中,会带大家完整的梳理分布式系统之中的共识算法,来更加深刻的理解分布式系统的设计. 1.原子提交和两阶段提交(2PC) 原子提交防止了数据库处于半更新的状态,这对于需要满足多对象事务和维护次级索引的数据库尤为重要.每个次级索引都是从主数据中分离出来的数据结构,因此,如果修改某些数据,也需要在次级索引中做出相应的更改.通过原子性保证二级索引能够与原数据保持一致. 分布式系统下的原子提交 我们

《TCP/IP详解卷1:协议》第12章 广播和多播---读书笔记

<TCP/IP详解卷1:协议>第12章 广播和多播---读书笔记 1.引言 广播和多播仅用于UDP,他们对需将报文同时传往多个接受者的应用来说十分重要. 有时,一个主机要向网上的所有其他主机发送帧,这就是广播. 多播(multicast)处于单播和广播之间:帧仅传送给属于多播组的多个主机. 2.广播 2.1.受限的广播 受限的广播地址是255.255.255.255.该地址用于主机配置过程中IP数据报的目的地址,此时,主机可能还不知道它所在网络的网络掩码,甚至连它的IP地址都不知道. 在任何情

[Spring Data Repositories]学习笔记--定义自己的repository

有时,我们会需要用到自己定义的一些查询方法,可以按照下面几步进行. 1. 定义一个包含该方法的接口 Interface UserRepositoryCustom { public void someCustomMethod(User user); } 2. 定义实现 class UserRepositoryImpl implements UserRepositoryCustom { public void someCustomMethod(User user){ //Your custom im

[Spring Data Repositories]学习笔记--为repository添加通用的方法

如果想把一个方法加到所有的repository中,用前一篇提到的方法就不合适了. 英文原版,请看 http://docs.spring.io/spring-data/data-mongo/docs/1.5.2.RELEASE/reference/html/repositories.html#repositories.custom-behaviour-for-all-repositories 1. 定义自己的repository,要从基础的repository进行继承. public interf

[Spring Data Repositories]学习笔记--使用现有的repository

以下内容是在学习Spring-Data-mongoDB中的Spring Data Repositories时做的一些笔记.备忘! 感觉学习还是看官方的资料比较透彻一些. Spring Data Repositories目的:减少重复的持久化代码. 常用的几个repository interface, Repository <-- CurdRepository <-- PagingAndSortingRepository 最后一个主要是用来做分页和排序用的. Repository使用步骤 1.

可靠的、可扩展的、可维护的数据系统 ------《Designing Data-Intensive Applications》读书笔记1

坦白说也是机缘巧合,在硕士生阶段进入分布式系统领域学习.无论是大规模存储或计算,其核心也是运用分布式技术利用并行性来解决数据密集型应用的需求.最近开始在啃这本<Designing Data-Intensive Applications>大部头,作者Martin Kleppmann在分布式数据系统领域有着很深的功底,并在这本书中完整的梳理各类纷繁复杂设计背后的技术逻辑,不同架构之间的妥协与超越,很值得开发人员与架构设计者阅读. 很可惜的是国内目前并没有对应的中文版本,这个系列算是一个读书感悟,同

&lt;从PAXOS到ZOOKEEPER分布式一致性原理与实践&gt;读书笔记-ZAB协议

本文属于分布式系统学习笔记系列,上一篇笔记整理了paxos算法,本文属于原书第四章,梳理zookeeper的目标特性及ZAB协议. 1.介绍zookeeper 1.1ZooKeeper保证一致性特性 ZooKeeper是一个典型的分布式数据一致性的解决方案,分布式程序可以基于它实现诸如数据发布/订阅.负载均衡.命名服务.分布式协调通知.集群管理.master选举.分布式锁.分布式队列等功能.ZooKeeper可以保证如下分布式一致性特性. 1.顺序一致性: 从同一个客户端发起的事务请求,最终将严

《从Paxos到ZooKeeper 分布式一致性原理与实践》读书笔记

一.分布式架构 1.分布式特点 分布性 对等性.分布式系统中的所有计算机节点都是对等的 并发性.多个节点并发的操作一些共享的资源 缺乏全局时钟.节点之间通过消息传递进行通信和协调,因为缺乏全局时钟,很难定义两个事件谁先谁后 故障总是会发生.系统设计时,需要考虑到任何异常情况 2.分布式环境的各种问题 通信异常.分布式系统中的某些节点之间无法正常通信 网络分区.这有部分节点可以正常通信,有些无法正常通信.这种现象称为网络分区,也称为"脑裂" 三态.节点之间的一次通信存在三种状态:成功.失