向量时钟算法简介——本质类似MVCC
一、使用背景
先说一下需要用到向量时钟的场景。我们在写数据时候,经常希望数据不要存储在单点。如db1,db2都可以同时提供写服务,并且都存有全量数据。而client不管是写哪一个db都不用担心数据写乱问题。但是现实场景中往往会碰到并行同时修改。导致db1和db2数据不一致。于是乎就有人想出一些解决策略。向量时钟算是其中一种。简单易懂。但是并没有彻底解决冲突问题,现实分布式存储补充了很多额外技巧。
这里反向叙述方式, 介绍向量时钟。先举实际例子让读者有个感性认识,然后再说算法规则。
二、举个例子
向量时钟实际是一组版本号(版本号=逻辑时钟),假设数据需要存放3份,需要3台db存储(用A,B,C表示),那么向量维度就是3,每个db有一个版本号,从0开始,这样就形成了一个向量版本 [A:0, B:0, C:0];
Step 1: 初始状态下,所有机器都是 [A:0, B:0, C:0];
DB_A——> [A:0, B:0, C:0]
DB_B——> [A:0, B:0, C:0]
DB_C——> [A:0, B:0, C:0]
Step 2: 假设现在应用是一个商场,现在录入一个肾6的价格 iphone6 price 5888; 客户端随机选择一个db机器写入。现假设选择了A。,数据大概是这样 :
{key=iphone_price; value=5888; vclk=[A:1,B:0,C:0]}
Step 3: 接下来A会把数据同步给B和C;于是最终同步结果如下
DB_A——> {key=iphone_price; value=5888; vclk=[ A:1,B:0,C:0]}
DB_B——> {key=iphone_price; value=6888; vclk=[ A:1, B:0,C:0]}
DB_C——> {key=iphone_price; value=5888; vclk=[ A:1,B:0,C:0]}
Step 4:过了分钟,价格出现波动,升值到6888;于是某个业务员更新价格。这时候系统随机选择了B做为写入存储,于是结果看起来是这样:
DB_A——> {key=iphone_price; value=5888; vclk=[A:1,B:0,C:0]}
DB_B——> {key=iphone_price; value=6888; vclk=[A:1,B:1,C:0]}
DB_C——> {key=iphone_price; value=5888; vclk=[A:1,B:0,C:0]}
Step 5:于是B就把更新同步给其他几个存储
DB_A——> {key=iphone_price; value=6888; vclk=[A:1, B:1,C:0]}
DB_B——> {key=iphone_price; value=6888; vclk=[A:1,B:1,C:0]}
DB_C——> {key=iphone_price; value=6888; vclk=[A:1, B:1,C:0]}
到目前为止都是正常同步,下面开始演示一下不正常的情况。
Step 6:价格再次发生波动,变成4000,这次选择C写入:
DB_A——> {key=iphone_price; value=6888; vclk=[A:1, B:1,C:0]}
DB_B——> {key=iphone_price; value=6888; vclk=[A:1,B:1,C:0]}
DB_C——> {key=iphone_price; value=4000; vclk=[A:1, B:1,C:1]}
Step 7: C把更新同步给A和B,因为某些问题,只同步到A,结果如下:
DB_A——> {key=iphone_price; value=4000; vclk=[A:1, B:1, C:1]}
DB_B——> {key=iphone_price; value=6888; vclk=[A:1,B:1,C:0]}
DB_C——> {key=iphone_price; value=4000; vclk=[A:1, B:1,C:1]}
Step 8:价格再次波动,变成6000元,系统选择B写入
DB_A——> {key=iphone_price; value=6888; vclk=[A:1, B:1, C:1]}
DB_B——> {key=iphone_price; value=6000; vclk=[A:1,B:2, C:0]}
DB_C——> {key=iphone_price; value=4000; vclk=[A:1, B:1,C:1]}
Step 9: 当B同步更新给A和C时候就出现问题了,A自己的向量时钟是 [A:1, B:1, C:1], 而收到更新消息携带过来的向量时钟是 [A:1,B:2, C:0], B:2 比 B:1新,但是C:0却比C1旧。这时候发生不一致冲突。不一致问题如何解决?向量时钟策略并没有给出解决版本,留给用户自己去解决,只是告诉你目前数据存在冲突。
三、规则介绍
版本号变更规则其实就2条,比较简单
1、 每次修改数据,本节点的版本号 加1,例如上述 step 8中 向B写入,于是从B:1 变成 B:2, 其他节点的版本号不发生变更。
2、 每次同步数据(这里需要注意,同步和修改是不一样的写操作哦), 会有三种情况:
a: 本节点的向量版本都要比消息携带过来的向量版本低(小于或等于) 如本节点为 [A:1, B:2,C:3]}, 消息携带过来为 [A:1, B:2,C:4] 或 [A:2, B:3,C:4]等。 这时候合并规则取每个分量的最大值。
b: 本节点的向量版本都要比比消息携带过来的向量版本高,这时候可以认为本地数据比同步过来的数据要新,直接丢弃要同步的版本。
c: 出现冲突,如上述step 9中,有的分量版本大,有的分量版本小,无法判断出来到底谁是最新版本。就要进行冲突仲裁。
四、冲突解决
其实没有一个比较好的解决冲突的版本:就笔者目前所了解,加上时间戳算是一个策略。具体方法是再加一个维度信息:数据更新的时间戳(timestamp)。[A:1, B:2,C:4,ts:123434354] ,如果发生冲突,再比较一下两个数据的ts,大的数值说明比较后更新,选择它作为最终数据。并对向量时钟进行订正。
向量时钟算法简介——本质类似MVCC的更多相关文章
- Dynamo涉及的算法和协议——p2p架构,一致性hash容错+gossip协议获取集群状态+向量时钟同步数据
转自:http://www.letiantian.me/2014-06-16-dynamo-algorithm-protocol/ Dynamo是Amazon的一个分布式的键值系统,P2P架构,没有主 ...
- NoSQL生态系统——一致性RWN协议,向量时钟,gossip协议监测故障
13.5 一致性 在NoSQL中,通常有两个层次的一致性:第一种是强一致性,既集群中的所有机器状态同步保持一致.第二种是最终一致性,既可以允许短暂的数据不一致,但数据最终会保持一致.我们先来讲一下,在 ...
- Dynamo分布式系统——「RWN」协议解决多备份数据如何读写来保证数据一致性,而「向量时钟」来保证当读取到多个备份数据的时候,如何判断哪些数据是最新的这种情况
转自:http://blog.jqian.net/post/dynamo.html Dynamo是Amazon开发的一款高可用的分布式KV系统,已经在Amazon商店的后端存储有很成熟的应用.它的特点 ...
- AES算法简介
AES算法简介 一. AES的结构 1.总体结构 明文分组的长度为128位即16字节,密钥长度可以为16,24或者32字节(128,192,256位).根据密钥的长度,算法被称为AES-128,AES ...
- 排列熵算法简介及c#实现
一. 排列熵算法简介: 排列熵算法(Permutation Entroy)为度量时间序列复杂性的一种方法,算法描述如下: 设一维时间序列: 采用相空间重构延迟坐标法对X中任一元素x(i)进行相空间 ...
- STL所有算法简介 (转) http://www.cnblogs.com/yuehui/archive/2012/06/19/2554300.html
STL所有算法简介 STL中的所有算法(70个) 参考自:http://www.cppblog.com/mzty/archive/2007/03/14/19819.htmlhttp://hi.baid ...
- PageRank 算法简介
有两篇文章一篇讲解(下面copy)< PageRank算法简介及Map-Reduce实现>来源:http://www.cnblogs.com/fengfenggirl/p/pagerank ...
- Gradient Boosting算法简介
最近项目中涉及基于Gradient Boosting Regression 算法拟合时间序列曲线的内容,利用python机器学习包 scikit-learn 中的GradientBoostingReg ...
- 向量时钟Vector Clock in Riak
Riak 是以 Erlang 编写的一个高度可扩展的分布式数据存储,Riak的实现是基于Amazon的Dynamo论文,Riak的设计目标之一就是高可用.Riak支持多节点构建的系统,每次读写请求不需 ...
随机推荐
- Leetcode: Longest Repeating Character Replacement && G 面经
Given a string that consists of only uppercase English letters, you can replace any letter in the st ...
- 刨根问底U3D---如何退出Play模式后保留数据更改
实际中遇到的需求 在做一款对抗类游戏,目前正在调整游戏的平衡性 所以就产生了一个需求 希望可以在Play模式时候对数据源做的更改可以在退出时候被保存下来. 举个Case, 比如 有一个炮塔 可以发射子 ...
- C# 实现 微软WebRequestMethods.Ftp类中的FTP操作功能
先奉献一个测试地址,ftp内的文件请勿删除,谢谢 FtpEntity fe = "); 由于代码量较多,只抽出一部分,详细代码请移步 ftp://wjshan0808.3vhost.net ...
- java权限修饰符
- elasticsearch基础
elastic使用lucene建立索引的步骤中,需要文件系统缓存需要同步到磁盘上.(多个segment->commit文件来维护) 当建立历史数据时,并不要求太高的实时性时,可以减小(默认1s) ...
- ms
meanShift的概念最早是由Fukunage[1]在1975年提出的,其最初的含义正如其名:偏移的均值向量:但随着理论的发展,meanShift的含义已经发生了很多变化.如今,我们说的meanSh ...
- listener.ora增加监听端口
一个简单的listener.ora # listener.ora Network Configuration File: d:\app\zyd\product\11.2.0\dbhome_1\netw ...
- POJ 2516:Minimum Cost(最小费用流)
https://vjudge.net/problem/11079/origin 题意:有N个商店和M个供应商和K种物品,每个商店每种物品有一个需求数,每个供应商每种物品有一个供应量,供应商到商店之间的 ...
- [转]Win7 64位搭建本地SVN服务器 Apache+Subversion
转载地址:http://blog.sina.com.cn/s/blog_4f072a7001015j5z.html 一.工具下载 01.SVN 服务器Subversion:Setup-Subversi ...
- Android 网络框架 volley源码剖析
转载请注明出处: http://blog.csdn.net/guolin_blog/article/details/17656437 经过前三篇文章的学习,Volley的用法我们已经掌握的差不多了, ...