向量时钟算法简介——本质类似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支持多节点构建的系统,每次读写请求不需 ...
随机推荐
- GIS简单计算Helper类
using System; using ESRI.ArcGIS.Client.Geometry; namespace GISProject.Extensions { /// <summary&g ...
- Latex 学习
Latex 学习 @(05.2 Latex)[latex][基础教程] 这篇文章是关于latex基础教程.pdf的一个总结. 基本知识 基础 1. 空格 多个空格会被视为一个空格 单个回车会被视为一个 ...
- mssql手工注入及绕过术
报错注入: - 例子:http://www.kfgtfcj.xxx.cn/lzygg/Zixun_show.aspx?id=1 [1]首先爆版本:http://www.kfgtfcj.xxx.cn ...
- 如何保存CONSOLE LOG
很早以前就想过问题,但因为我们一直有自动化程序去做,所以没仔细研究. 今天学习了一下,其实很简单,在sdsf.da 里面搜索master会看到下面这样一个TASK *MASTER* STC0000 ...
- 提高Oracle的WHERE语句性能一些原则
索引是表的一个概念部分 , 用来提高检索数据的效率, ORACLE 使用了一个复杂的自平衡 B-tree 结构 . 通常 , 通过索引查询数据比全表扫描要快 . 当 ORACLE 找出执行查询和 Up ...
- PHP composer 安装流程
打开php的openssl扩展 可以在wamp管理器里直接打开openssl扩展,也可以使用php命令打开扩展,还可以通过修改php.ini后重启打开扩展. 下面给出命令打开扩展的示例: 可以通过以下 ...
- Unix/Linux编程实践教程(0:文件、终端、信号)
本来只打算读这本书socket等相关内容,但书写得实在好,还是决定把其余的内容都读一下. 阅读联机帮助的一个示例: open系统调用: read系统调用: Unix的time: 上面的printf可以 ...
- T-SQL 的简单查询语句
通配符: “_”: 代表匹配一个字符 “%”: 代表匹配多个字符: []:表示范围,可以包含多个数据 [^] 表示取反 “-“ 表示范围 逻辑与 and 逻辑或 or 逻辑非 not 聚会函数 : ...
- Script循环语句 的相关知识跟练习
循环语句有两种问题类型:穷举和迭代 穷举: 在不知道什么情况下才是我们需要的结果的时候,只能让它一个一个的都执行一遍 迭代:在现有的条件下,根据规律,不断求解中间情况,最终推选出结果 两个关键词 br ...
- manacher浅析
manacher算法的输入是一个字符串,可以计算出以每个字符为中心的最长回文子串的半径.为了避免讨论奇数偶数,将原串的每两个字母之间以及前后各加一个特殊字母,比如'#',那么对于abcbb就变成了 # ...