目录
一、Amazon Dynamo的问世
二、Amazon Dynamo主要技术概要
三、数据划分算法
四、数据复制
五、版本控制
六、故障处理
七、成员和故障检测
一、Amazon Dynamo的问世
Amazon Dynamo是由亚马逊在2007年开发的一种高度可扩展和分布式的键值存储系统,旨在解决公司面临的大规模、任务关键型服务的需求。其起源于亚马逊早期在运营电子商务业务时遇到的挑战,传统的关系型数据库无法满足其大规模、高可用性和分布式存储的需求。因此,亚马逊的工程团队开始寻找一种新的存储解决方案。Amazon Dynamo采用了分布式架构和键值存储模型,实现了高度的可扩展性、灵活性和可定制性,成为许多大型互联网公司处理大规模数据存储和访问的首选解决方案之一。
二、Amazon Dynamo主要技术概要
Amazon Dynamo是亚马逊公司基于分布式环境下的数据存储需求所开发的一套高度可靠、高性能的分布式存储系统。其设计和实现基于一系列关键技术,这些技术使得Dynamo能够在面对大规模的数据存储和处理时保持高可用性、一致性和可扩展性。其中包括数据划分、数据复制、数据读写操作、版本控制、故障处理以及成员和故障检测等关键技术,具体可见以下表格:
技术 | 描述 | 作用 |
---|---|---|
数据划分 | 利用一致性哈希算法将数据划分成多个分区,实现数据的分布式存储和处理,提高可扩展性和性能。 | 分布数据以实现增量可扩展性。 |
数据复制 | 将每个分区中的数据复制到多个节点上,提高容错性和可用性。使用NWR机制确定复制数量和一致性要求。 | 提高系统的容错性和可用性,确保数据的一致性。 |
数据读写操作 | 使用get和put操作实现数据的读取和写入,保证数据的一致性和可靠性。在写入时使用NWR机制确定写入的副本数,在读取时使用R参数指定读取的副本数。 | 确保数据的一致性和可靠性。 |
版本控制 | 使用向量时钟解决多副本之间的冲突,记录每个数据项的更新历史,帮助判断不同副本之间的数据版本关系。 | 解决多副本冲突,确保数据的一致性。 |
故障处理 | 采用暗示移交处理暂时性节点故障,将数据暂存于其他节点,故障恢复后将数据传递给正确节点。对于永久性故障,使用反熵机制确保副本一致性。 | 处理节点故障,确保数据的一致性和可用性。 |
成员和故障检测 | 使用Gossip协议进行成员和故障检测,定期通信维护成员列表,监测节点状态变化,保持系统稳定性和可用性。 | 检测节点状态变化,保持系统稳定性和可用性。 |
三、数据划分算法
在一致性哈希算法的基础上,Dynamo引入了虚拟节点的概念作为其分区方案的变体。在传统的一致性哈希算法中,每个节点只负责环中一个点的区域,这可能导致负载分布不均匀以及忽略了节点性能的异质性。因此,Dynamo将每个节点分配到环中的多个点,即虚拟节点。
具体来说,当一个新节点加入系统时,它会被分配多个虚拟节点,每个虚拟节点在环上占据不同的位置。这些虚拟节点的数量可以根据节点的容量和性能来调整。当节点不可用时,其负载将被均匀地分布到其他可用节点上,从而保持系统的稳定性和可用性。而当节点再次可用或新节点加入系统时,负载将会平均地分布到所有可用节点上,确保了系统的负载均衡。
虚拟节点的引入使得Dynamo能够更好地适应节点动态变化、负载均衡和异质性的情况,从而提高了系统的稳定性和可扩展性。通过调整节点负责的虚拟节点数量,可以更灵活地适应不同的物理基础架构和节点容量,进一步优化系统的性能和资源利用率。
如上图所示为一致性哈希采取的环形存储,箭头表示key计算出的值得分布。A,B,C是三个不同的节点,策略1是随机计算T个值并存储,策略2是随机计算并等分存储,而策略3则是有规律的计算并存储。Dynamo通过测试发现策略3相对来说有着最佳的负载均衡率,而策略2最差。具体测试结果如下图所示:
四、数据复制
在Dynamo中,为了实现高可用性和持久性,数据被复制到多个主机上。每个数据项都会在N个主机上进行复制,其中N是根据系统配置的参数确定的。每个数据项都被分配给一个协调器节点,该节点负责管理其范围内的数据复制。除了在本地存储数据之外,协调器还会将数据复制到环上N-1个顺时针后续节点上。这样,每个节点负责管理它和它的第N个前身之间的环的区域。
负责存储特定密钥的节点列表称为首选节点列表。为了应对节点故障,首选列表包含了N个以上的节点。需要注意的是,由于使用了虚拟节点,特定密钥的前N个后续位置可能由少于N个不同的物理节点拥有。为了解决这个问题,首选列表会跳过环中的位置,以确保列表中包含的节点是不同的物理节点。五、数据读写操作
- 对于PUT操作,协调员首先生成新的数据版本和向量时钟分量,然后将新数据保存到本地。接着,协调员将写入请求发送给首选列表中的所有节点,并在收到足够数量的确认后向用户返回成功。
- 对于GET操作,协调员向首选列表中的所有节点请求数据版本,等待足够数量的回复后,通过向量时钟处理有因果关系的数据版本,并将存在冲突的数据版本返回给用户。
在这个过程中,协调员起着关键的作用,通常是首选列表中的前N个节点中的第一个。如果请求是通过负载平衡器收到的,请求可能会被路由到环上的任何随机节点。在这种情况下,如果接收到请求的节点不是首选列表中的前N个节点之一,它将不会协调处理请求,而是将请求转发到首选列表中的第一个节点。
在Amazon Dynamo中,为了确保副本的一致性,采用了一种类似仲裁系统的一致性协议。这个协议涉及两个配置参数R和W,它们分别代表执行一次读取操作和写入操作所需的最少投票者数量。具体来说:
-
R(Read Quorum):R参数表示执行一次读取操作所需的最少投票者数量。当客户端发起读取操作时,需要至少从R个副本中读取数据。只有当至少从R个副本中读取到数据时,读取操作才被视为成功。
-
W(Write Quorum):W参数表示执行一次写入操作所需的最少投票者数量。当客户端发起写入操作时,需要向至少W个副本写入数据。只有当至少有W个副本成功写入数据后,写入操作才被视为成功。
在设置R和W时,必须满足R + W > N的条件,其中N是系统中总副本的数量。这个条件确保了一致性协议的正确执行。通过设置R和W参数,可以灵活地平衡一致性和可用性之间的关系。增加R和W的值可以提高一致性,但可能会增加操作的延迟,因为需要等待更多的节点响应。相反,减少R和W的值可以降低延迟,但可能会降低一致性。因此,在实际应用中,需要根据系统的需求和性能目标来选择适当的R和W值。
五、版本控制
在Dynamo中,向量时钟被用来捕捉同一对象的不同版本之间的因果关系。向量时钟实际上是一个(node, counter)对列表,与每个对象的每个版本相关联。通过检查向量时钟,我们可以确定一个对象的两个版本是平行分支还是有因果顺序。如果第一个时钟对象上的计数器在第二个时钟对象上小于或等于其他所有节点的计数器,那么第一个版本是第二个版本的祖先,可以被忽略。否则,这两个变化被认为是冲突的,并需要进行语义上的协调。
在Dynamo中,当客户端更新一个对象时,它必须指定要更新的版本(这是通过传递从早期读操作中获得的上下文对象来指定的,其中包含向量时钟信息)。当处理读请求时,如果Dynamo访问到多个无法语法协调的分支,它将返回分支叶子上的所有对象,以及它们对应的上下文版本信息。使用此上下文的更新操作将被认为是对前述不同版本更新操作的语义上的协调,其分支已收缩到一个新版本上。
为了说明使用向量时钟,考虑上图所示的例子:
- 客户端写入一个新的对象。节点(比如说Sx),它处理对这个key的写:序列号递增,并用它来创建数据的向量时钟。该系统现在有对象D1和其相关的时钟[(Sx,1)]。
- 客户端更新该对象。假定也由同样的节点处理这个要求。现在该系统有对象D2和其相关的时钟[(Sx,2)]。D2继承自D1,因此覆盖D1,但是其他节点中或许存在还没有看到D2版本的副本。
- 让我们假设,同样的客户端更新这个对象但不同的服务器(比如Sy)处理了该请求。目前该系统具有数据D3及其相关的时钟[(Sx,2),(Sy,1)]。
- 接下来假设不同的客户端读取D2,然后尝试更新它,并且另一个服务器节点(如Sz)进行写操作。该系统现在具有D4(D2的子孙),其版本时钟[(Sx,2),(Sz,1)]。
- 一个对D1或D2有所了解的节点可以决定,在收到D4和它的时钟时,新的数据将覆盖D1和D2,可以被垃圾收集。一个对D3有所了解的节点,在接收D4时将会发现,它们之间不存在因果关系。换句话说,D3和D4都有更新操作,但都未在对方的变化中反映出来。这两个版本的数据都必须保持并提交给客户端(在读时)进行语义协调。
- 现在假定一些客户端同时读取到D3和D4(上下文将会反映出这两个值是由read操作发现的)。读的上下文包含有D3和D4时钟的概要信息,即[(Sx,2),(Sy,1),(Sz,1)]的时钟总结。如果客户端执行协调,且由节点Sx来协调这个写操作,Sx将更新其时钟的序列号。D5的新数据将有以下时钟:[(Sx,3),(Sy,1),(Sz,1)]。
六、故障处理
故障处理在Dynamo中是一个关键的组成部分,用于处理临时性和永久性的节点故障。
对于临时性节点故障,Dynamo采用了暗示移交的机制。当一个节点出现暂时性故障时,例如由于网络中断或节点故障,Dynamo会将数据暂时存储在其他节点上,而不是立即将其丢弃。这些节点被称为“暗示”节点,它们临时承担了故障节点的数据负载。一旦故障节点恢复正常,暗示节点会将暂存的数据传递回故障节点,以确保数据的完整性和一致性。
对于永久性节点故障,Dynamo使用反熵机制来确保副本之间的一致性。这种机制涉及到周期性地比较和同步不同副本之间的数据。通过使用反熵机制,Dynamo可以快速检测到数据不一致的情况,并采取相应的措施来修复数据,从而确保系统的稳定性和可用性。
七、成员和故障检测
成员和故障检测在Dynamo中是通过Gossip协议实现的。Gossip协议是一种去中心化的通信协议,用于在分布式系统中进行成员和故障检测。Dynamo中的每个节点都定期与其他节点进行通信,交换有关成员状态和故障信息的信息。通过这种定期的通信,节点可以维护一个成员列表,并监测节点状态的变化。
具体而言,每个节点会周期性地向一组其他节点发送消息,告知它们自己的状态和可用性情况,并接收其他节点发送的类似信息。这些消息在整个系统中通过网络传播,并且被节点逐步接收和处理。通过这种方式,每个节点可以获取关于整个系统状态的信息,并且及时检测到其他节点的加入、离开或故障。
使用Gossip协议进行成员和故障检测具有以下优点:
-
去中心化:没有单一的中心节点负责管理成员和故障检测,而是每个节点都参与其中,从而提高了系统的稳定性和可用性。
-
实时性:节点之间定期通信,信息可以快速传播,从而及时检测到节点状态的变化。
-
容错性:即使部分节点无法正常工作,也不会影响整个系统的运行,因为其他节点仍然可以通过Gossip协议进行通信和检测。
通过使用Gossip协议,Dynamo可以确保成员列表的及时更新和节点状态的实时监测,从而保持系统的稳定性和可用性。
推荐阅读:
重读 Amazon Dynamo 论文有感 - 知乎
https://www.cnblogs.com/xybaby/p/13944662.html
Amazon Dynamo论文解读 — Dynamo数据划分算法 - CodeAntenna
《Dynamo》论文笔记 | 水木今山的博客
Dynamo:亚马逊的高可用键值存储_dynamo文件系统,使用哪个技术实现了版本控制-CSDN博客
分布式存储系统学习笔记(三)—分布式键值系统(1)—Amazon Dynamo_amazon s3 dynamo 哈希-CSDN博客
阅读笔记(十六)高可用KV数据存储Dynamo实现细节《Dynamo: Amazon’s Highly Available Key-value Store》_亚马逊 kv数据库-CSDN博客