Riak 是以 Erlang 编写的一个高度可扩展的分布式数据存储,Riak的实现是基于Amazon的Dynamo论文,Riak的设计目标之一就是高可用。Riak支持多节点构建的系统,每次读写请求不需要集群内所有节点参与也能胜任。像这样的系统,我们需要版本机制来确定哪个值是最新的。所以就引入了向量时钟(Vector Clock)

当存储一个对象到Riak时,都被打上向量时钟标签。通过向量空间祖先继承的关系比较,Riak可以自动的修复不同步的值,使数据保持最终一致性。

向量时钟的作用

有个比较经典的例子,说明向量时钟的作用。假设有如下场景:

Alice、Ben、Catby和Dave四人约定下周一起聚餐,四个人通过邮件商量聚餐的时间。
Alice首先建议周三聚餐。
之后Dave和Catby商量觉得周四更合适。
后来Dave又和Ben商量之后觉得周二也行。
最后Alice要汇总大家的意见,得到的反馈如下:
Cathy说,他和Dave商量的时间是周四
Ben说,他和Dave商量的时间是周三 此时恰好联系不上Dave,而且不知道Cathy和Ben分别与Dave确定时间的先后顺序,Alice就不能确定到底该定在哪天了。

Vector Clock就是为了解决这种问题而设计的,简单来说,就是为每个商议结果加上一个时间戳,当结果改变时,更新时间戳。所以加上时间戳之后,我们再一次描述上面的场景,如下:

当Alice第一次提议将时间定为周三时,可以这样描述信息
date = Wednesday
vclock = Alice: 其他三个人都收到了信息,Dave和Ben开始交流,Ben建议改成周二,把Alice的初试向量加进去标识Ben看到Alice的消息了
date = Tuesday
vclock = Alice:, Ben: Dave回复Ben,确定周二可以
date = Tuesday
vclock = Alice:, Ben:, Dave: 然后Cathy开始说话,也和Dave说建议周四,此时在Dave看来就收到了两个数据如下:
date = Tuesday
vclock = Alice:, Ben:, Dave: date = Thursday
vclock = Alice:, Cathy:
这两份数据,各自都不是互相的祖先,所以就产生了冲突,Dave要自动解决这个冲突,他选择了周四,然后将消息改成如下,继承来自Dave现在收到的两条消息,这个消息发回给Cathy
date = Thursday
vclock = Alice:, Ben:, Cathy:, Dave: 最后来了,Alice只问Ben和Cathy最后的决定:
Ben说
date = Tuesday
vclock = Alice:, Ben:, Dave: Cathy说
date = Thursday
vclock = Alice:, Ben:, Cathy:, Dave: Alice就明白了,因为第二个Cathy说的是完全继承于Ben说的,所以最后采纳Cathy说的决定,周四去。

以上这个决策用到了向量时钟,有个图还比较清晰了说明整个过程:

向量时钟的空间无限增长问题

以上的做法还比较完美的解决了问题,这里只列举了四个决策者的向量时钟,不过在现实生活中,如果有很多的决策者,相当于有很多的客户端,整个向量时钟的长度就无限制增长了,这对于存储系统来说,不是一个好消息。我们需要想办法解决。

一个直接的想法是,不要用client来标识向量空间,用server来标识向量空间,因为server的数量是可控的,这里用X,Y两台server来重现以上决策的过程,只是标签不再用客户端,而是用server标识,决策过程如下

此时Dave收到两个消息

Tue X:2,Y:1  with Ben

Thu X:1,Y1   from Cathy (这个消息比较新)

发现后者是前者的祖先,所以自然抛弃祖先,最终最新的,这样就悄无声息的把Cathy给他的消息给丢了。

所以尝试用server来做标识,以期减少向量时钟的空间是不可取的,因为会丢数据。实际情况还是需要用客户端的标识来做向量时钟。

向量时钟的剪枝

所以为了解决向量时钟空间的无限增长问题,引入了向量时钟的剪枝

Riak用四个参数来避免向量时钟空间的无限增长:

  • small_vclock
  • big_vclock
  • young_vclock
  • old_vclock

small_vclock和big_vclock参数标识向量时钟的长度,如果长度小于small_vclock就不会被剪枝掉,如果长度大于big_vclock就会被剪枝掉

young_vclock和old_vclock参数标识存储这个向量时钟时的时间戳,剪枝策略同理,大于old_vclock的才会被剪枝掉,剪枝策略如下图

这样只会丢掉一些向量时钟的信息,即数据更新过程的信息,但是不会丢掉实实在在的数据。只有当一种情况会有问题,就是一个客户端保持了一个很久之前的向量时钟,然后继承于这个向量时钟提交了一个数据,此时就会有冲突,因为服务器这边已经没有这个很久之前的向量时钟信息了,已经被剪枝掉了可能,所以客户端提交的此次数据,在服务端无法找到一个祖先,此时就会创建一个sibling。

所以这个剪枝的策略是一个权衡tradeoff,一方面是无限增长的向量时钟的空间,另一方面是偶尔的会有"false merge",对,但肯定的是,不会悄无声息的丢数据。综上,为了防止向量时钟空间的无限增长,剪枝还是比用server标识向量时钟工作的更好。

参考:

http://docs.basho.com/riak/latest/theory/concepts/Vector-Clocks/

http://basho.com/why-vector-clocks-are-easy/

http://basho.com/why-vector-clocks-are-hard/

《大型网站系统与Java中间件实践》

向量时钟Vector Clock in Riak的更多相关文章

  1. Dynamo分布式系统——「RWN」协议解决多备份数据如何读写来保证数据一致性,而「向量时钟」来保证当读取到多个备份数据的时候,如何判断哪些数据是最新的这种情况

    转自:http://blog.jqian.net/post/dynamo.html Dynamo是Amazon开发的一款高可用的分布式KV系统,已经在Amazon商店的后端存储有很成熟的应用.它的特点 ...

  2. NoSQL生态系统——一致性RWN协议,向量时钟,gossip协议监测故障

    13.5 一致性 在NoSQL中,通常有两个层次的一致性:第一种是强一致性,既集群中的所有机器状态同步保持一致.第二种是最终一致性,既可以允许短暂的数据不一致,但数据最终会保持一致.我们先来讲一下,在 ...

  3. Vector Clock/Version Clock

    physical clock 机器上的物理时钟,不同的机器在同一个时间点取到的physical clock不一样,之间会存在一定的误差,NTP可以用来控制这个误差,同一个机房内的机器之间的时钟误差可以 ...

  4. Dynamo涉及的算法和协议——p2p架构,一致性hash容错+gossip协议获取集群状态+向量时钟同步数据

    转自:http://www.letiantian.me/2014-06-16-dynamo-algorithm-protocol/ Dynamo是Amazon的一个分布式的键值系统,P2P架构,没有主 ...

  5. Vector Clock理解

    背景近期在重读"Dynamo: Amazon's Highly Available Key-value Store"(经典好文,推荐!).文章4.4 中聊到了Data Versio ...

  6. 向量时钟算法简介——本质类似MVCC

    转自:http://blog.chinaunix.net/uid-27105712-id-5612512.html 一.使用背景 先说一下需要用到向量时钟的场景.我们在写数据时候,经常希望数据不要存储 ...

  7. R语言编程艺术# 数据类型向量(vector)

    R语言最基本的数据类型-向量(vector) 1.插入向量元素,同一向量中的所有的元素必须是相同的模式(数据类型),如整型.数值型(浮点数).字符型(字符串).逻辑型.复数型等.查看变量的类型可以用t ...

  8. 精解Mat类(一):基本数据类型-固定大小的 矩阵类(Matx) 向量类(Vector)

    一.基础数据类型 1.(基础)固定大小矩阵类 matx 说明: ①    基础矩阵是我个人增加的描述,相对于Mat矩阵类(存储图像信息的大矩阵)而言. ②    固定大小矩阵类必须在编译期间就知晓其维 ...

  9. R语言编程艺术#01#数据类型向量(vector)

    R语言最基本的数据类型-向量(vector) 1.插入向量元素,同一向量中的所有的元素必须是相同的模式(数据类型),如整型.数值型(浮点数).字符型(字符串).逻辑型.复数型等.查看变量的类型可以用t ...

随机推荐

  1. iOS应用架构谈(三):网络层设计方案(上)

    iOS客户端应用架构看似简单,但实际上要考虑的事情不少.本文作者将以系列文章的形式来讨论iOS应用架构中的种种问题,本文是其中的第三篇,主要讲网络层设计以及安全机制和优化方案. 前言 网络层在一个Ap ...

  2. mongodb 3.2 用户权限管理配置

    使用mongodb 有段时间了,由于是在内网使用,便没有设置权限,一直是裸奔. 最近有时间,研究了下mongodb 3.2 的用户权限配置,网上有许多用户权限配置的文章,不过大多是之前版本,有些出入, ...

  3. SSH详解

    Secure Shell (SSH) 是一个允许两台电脑之间通过安全的连接进行数据交换的网络协议.加密保证了数据的保密性和完整性.SSH采用公钥加密技术来验证远程主机,以及(必要时)允许远程主机验证用 ...

  4. 模拟赛1030d2

    他[问题描述]一张长度为N的纸带, 我们可以从左至右编号为0 − N( 纸带最左端标号为0). 现在有M次操作, 每次将纸带沿着某个位置进行折叠, 问所有操作之后纸带的长度是多少.[输入格式]第一行两 ...

  5. stm32——NFC芯片--PN532的使用

    stm32——NFC芯片--PN532的使用 一.NFC简介 NFC(Near Field Communication)近场通信,是一种短距高频的无线电技术,在13.56MHz频率运行于20厘米距离内 ...

  6. Stanford大学机器学习公开课(三):局部加权回归、最小二乘的概率解释、逻辑回归、感知器算法

    (一)局部加权回归 通常情况下的线性拟合不能很好地预测所有的值,因为它容易导致欠拟合(under fitting).如下图的左图.而多项式拟合能拟合所有数据,但是在预测新样本的时候又会变得很糟糕,因为 ...

  7. ThinkPHP入门(二)

    smarty使用 smarty引入流程 1. 控制器IndexAction.class.php function index() $this -> display(); (父类Action的di ...

  8. codevs 2851 菜菜买气球

    dp加二分法 链接:http://codevs.cn/problem/2851/ #include<iostream> #include<vector> #include< ...

  9. mysql的存储过程

    mysql5中开始引入存储过程,存储过程是一组为了完成特定功能的sql语句集,经编译后存储在数据库中. 存储过程的特点(优点): 1:减小网络通信量.调用一个行数不多的存储过程与直接高用SQL语名的网 ...

  10. Jquery自定义图片上传插件

    1 概述 编写后台网站程序大多数用到文件上传,可是传统的文件上传控件不是外观不够优雅,就是性能不太好看,翻阅众多文件上传控件的文章,发现可以这样去定义一个文件上传控件,实现的文件上传的效果图如下: 2 ...