zoukankan      html  css  js  c++  java
  • 通过一个大型项目来学习分布式算法(5)

    这也引入了一个耐用性漏洞(vulnerability)窗体:即使它仅仅是在少数几个节点上持久化了但写入请求成功返回到client。

    传统的观点觉得。耐用性和可用性关系总是很紧密(hand-in-hand手牵手^-^)。可是,这并不一定总是真的。比如。耐用性漏洞窗体能够通过增加W来降低。但这将增加请求被拒绝的机率(从而降低可用性)。由于为处理一个写请求须要很多其它的存储主机须要活着。

    被好几个Dynamo实例採用的(n。R。W)配置通常为(3,2,2)

    选择这些值是为满足性能,耐用性,一致性和可用性SLAs的需求。

    全部在本节中測量的是一个在线系统,其工作在(3,2,2)配置并执行在几百个同质硬件配置上。如前所述,每一个实例包括位于多个数据中心的Dynamo节点。这些数据中心一般是通过快速网络连接。

    回忆一下,产生一个成功的get(或put)响应,R(或W)个节点须要响应协调员。显然,数据中心之间的网络延时会影响响应时间,因此节点(及其数据中心位置)的选择要使得应用的目标SLAs得到满足。

    6.1平衡性能和耐久性 

    尽管Dynamo的基本的设计目标是建立一个高度可用的数据存储,性能是在Amazon平台中是一个相同重要的衡量标准。如前所述,为客户提供一致的客户体验,Amazon的服务定在较高的百分位(如99.9或99.99),一个典型的使用Dynamo的服务的SLA要求99.9%的读取和写入请求在300毫秒内完毕。

    由于Dynamo是执行在标准的日用级硬件组件上,这些组件的I/O吞吐量远比不上高端企业级server,因此提供一致性的高性能的读取和写入操作并非一个简单的任务。

    再加上涉及到多个存​​储节点的读取和写入操作。让我们更加具有挑战性,由于这些操作的性能是由最慢的R或W副本限制的。图4显示了Dynamo为期30天的读/写的平均和99.9百分位的延时。

    正如图中能够看出。延时表现出明显的昼夜模式这是由于进来的请求速率存在昼夜模式的结果造成的(即请求速率在白天和黑夜有着显着差异)。此外,写延时明显高于读取延时。由于写操作总是导致磁盘訪问。此外,99.9百分位的延时大约是200毫秒。比平均水平高出一个数量级。这是由于99.9百分位的延时受几个因素。如请求负载,对象大小和位置格局的变化影响。

     
    图4:读。写操作的平均和99.9百分点延时。2006年12月高峰时的请求。

    在X轴的刻度之间的间隔相当于连续12小时。延时遵循昼夜模式相似请求速率99.9百分点比平均水平高出一个数量级。

    尽管这样的性能水平是能够被大多数服务所接受,一些面向客户的服务须要更高的性能。

    针对这些服务。Dynamo能够牺牲持久性来保证性能。

    在这个优化中,每一个存储节点维护一个内存中的对象缓冲区(BigTable 中的memtable)。每次写操作都存储在缓冲区,“写”线程定期将缓冲写到存储中。在这个方法中。读操作首先检查请求的 key 是否存在于缓冲区。

    假设是这样,对象是从缓冲区读取。而不是存储引擎。

    这样的优化的结果是99.9百位在流量高峰期间的延时降低达5倍之多。即使是一千个对象(參见图5)的很小的缓冲区。

    此外。如图中所看到的,写缓冲在较高百分位具有平滑延时。显然,这个方法是平衡耐久性来提高性能的。在这个方法中,server崩溃可能会导致写操作丢失,即那些在缓冲区队列中的写(还未持久化到存储中的写)。为了降低耐用性风险。更细化的写操作要求协调员选择N副本中的一个执行“持久写”。

    由于协调员仅仅需等待W个响应(译,这里讨论的这样的情况包括W-1个缓冲区写,1个持久化写),写操作的性能不会由于单一一个副本的持久化写而受到影响。

     
    图5:24小时内的99.9百分位延时缓冲和非缓冲写的性能比較。在x轴的刻度之间的间隔连续为一小时。

    6.2确保均匀的负载分布 

    Dynamo採用一致性的散列将key space(键空间)分布在其全部的副本上,并确保负载均匀分布。

    假设对key的訪问分布不会高度偏移,一个统一的key分配能够帮助我们达到均匀的负载分布。特别地, Dynamo设计假定。即使訪问的分布存在显着偏移,仅仅要在流行的那端(popular end)有足够多的keys。那么对那些流行的key的处理的负载就能够通过partitioning均匀地分散到各个节点。

    本节讨论Dynamo中所出现负载不均衡和不同的划分策略对负载分布的影响。

    为了研究负载不平衡与请求负载的相关性,通过測量各个节点在24小时内收到的请求总数-细分为30分钟一段。在一个给定的时间窗体。假设该节点的请求负载偏离平均负载没有超过某个阈值(这里15%)。觉得一个节点被觉得是“平衡的”。否则。节点被觉得是“失去平衡”。图6给出了一部分在这段时间内“失去平衡”的节点(下面简称“失衡比例”)。

    作为參考,整个系统在这段时间内收到的对应的请求负载也被绘制。

    正如图所看到的。不平衡率随着负载的增加而下降。比如,在低负荷时,不平衡率高达20%。在高负荷高接近10%。直观地说,这能够解释为。在高负荷时大量流行键(popular key)訪问且由于key的均匀分布,负载终于均匀分布。然而。在(当中负载为高峰负载的八分之中的一个)低负载下。当更少的流行键被訪问,将导致一个比較高的负载不平衡。

     

    图6:部分失去平衡的节点(即节点的请求负载高于系统平均负载的某一阈值)和其对应的请求负载。

    X轴刻度间隔相当于一个30分钟的时间。

    本节讨论Dynamo的划分方案(partitioning scheme)是怎样随着时间和负载分布的影响进行演化的。

    策略1:每一个节点T个随机Token和基于Token值进行切割:这是最早部署在生产环境的策略(在4.2节中描写叙述)。在这个方法中。每一个节点被分配T 个Tokens(从哈希空间随机均匀地选择)。全部节点的token,是依照其在哈希空间中的值进行排序的。每两个连续的Token定义一个范围。最后的Token与最開始的Token构成一区域(range):从哈希空间中最大值绕(wrap)到最低值。由于Token是随机选择,范围大小是可变的。节点增加和离开系统导致Token集的改变,终于导致ranges的变化,请注意,每一个节点所需的用来维护系统的成员的空间与系统中节点的数目成线性关系。

    在使用这一策略时。遇到了下面问题。首先,当一个新的节点增加系统时,它须要“窃取”(steal)其它节点的键范围。

    然而,这些须要移交key ranges给新节点的节点必须扫描他们的本地持久化存储来得到适当的数据项。请注意,在生产节点上执行这样的扫描操作是很复杂。由于扫描是资源高度密集的操作,他们须要在后台执行,而不至于影响客户的性能。这就要求我们必须将引导工作设置为最低的优先级。然而,这将大大减缓了引导过程,在繁忙的购物季节,当节点每天处理数百万的请求时,引导过程可能须要差点儿一天才干完毕。第二,当一个节点增加/离开系统。由很多节点处理的key range的变化以及新的范围的MertkleTree须要又一次计算,在生产系统上,这不是一个简单的操作。最后。由于key range的随机性。没有一个简单的办法为整个key space做一个快照。这使得归档过程复杂化。

    在这个方法中。归档整个key space 须要分别检索每一个节点的key,这是很低效的。

    这个策略的根本问题是,数据划分和数据安置的计划交织在一起。比如。在某些情况下,最好是增加很多其它的节点到系统。以应对处理请求负载的增加。可是,在这样的情况下,增加节点(导致数据安置)不可能不影响数据划分。理想的情况下。最好使用独立划分和安置计划。为此。对下面策略进行了评估:

    策略2:每一个节点T个随机token和同等大小的分区:在此策略中。节点的哈希空间分为Q个相同大小的分区/范围,每一个节点被分配T个随机Token。

    Q是通常设置使得Q>>N和Q>>S*T,当中S为系统的节点个数。在这一策略中,Token仅仅是用来构造一个映射函数该函数将哈希空间的值映射到一个有序列的节点列表。而不决定分区。分区是放置在从分区的末尾開始沿着一致性hash环顺时针移动遇到的前N个独立的节点上。图7说明了这一策略当N=3时的情况。在这个样例中,节点A。B,C是从分区的末尾開始沿着一致性hash环顺时针移动遇到的包括key K1的节点。这一策略的主要长处是:(i)划分和分区布局脱耦 (ii)使得在执行时改变安置方案成为可能。


  • 相关阅读:
    QTP的那些事连接oracle的方法
    QTP的那些事判定页面是否存在某个文本内容
    java计算的小数加减法计算有错误解决
    自由者-Hdsome安身立鸣博客园
    转:经典URL重写
    常见的类整理
    TD tree体验
    《大道至简》读后感
    SqlDataReader使用
    ExecuteScalar
  • 原文地址:https://www.cnblogs.com/zsychanpin/p/7137937.html
Copyright © 2011-2022 走看看