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

简介:
转自:http://blog.chinaunix.net/uid-27105712-id-5612512.html

 

一、使用背景

先说一下需要用到向量时钟的场景。我们在写数据时候,经常希望数据不要存储在单点。如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会把数据同步给BC;于是最终同步结果如下

      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把更新同步给AB,因为某些问题,只同步到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,大的数值说明比较后更新,选择它作为最终数据。并对向量时钟进行订正。













本文转自张昺华-sky博客园博客,原文链接:http://www.cnblogs.com/bonelee/p/6248102.html,如需转载请自行联系原作者


相关文章
|
17天前
|
算法
时钟置换算法
【10月更文挑战第25天】时钟置换算法是一种简单而有效的页面置换算法,它通过使用位标志和环形链表的结构,在一定程度上平衡了算法的复杂性和性能表现。虽然它存在一些局限性,但通过改进和与其他算法的结合,可以在不同的系统环境中发挥重要作用,提高虚拟内存管理的效率和系统的整体性能。
44 8
|
17天前
|
机器学习/深度学习 算法 数据挖掘
提高时钟置换算法的性能
【10月更文挑战第25天】通过上述一种或多种方法的综合应用,可以在不同程度上提高时钟置换算法的性能,使其更好地适应各种复杂的系统环境和应用场景,提高虚拟内存管理的效率和系统的整体性能。
35 5
|
6月前
|
机器学习/深度学习 算法 TensorFlow
机器学习算法简介:从线性回归到深度学习
【5月更文挑战第30天】本文概述了6种基本机器学习算法:线性回归、逻辑回归、决策树、支持向量机、随机森林和深度学习。通过Python示例代码展示了如何使用Scikit-learn、statsmodels、TensorFlow库进行实现。这些算法在不同场景下各有优势,如线性回归处理连续值,逻辑回归用于二分类,决策树适用于规则提取,支持向量机最大化类别间隔,随机森林集成多个决策树提升性能,而深度学习利用神经网络解决复杂模式识别问题。理解并选择合适算法对提升模型效果至关重要。
249 4
|
2月前
|
算法 Java 数据安全/隐私保护
国密加密算法简介
国密指国家密码局认定的国产密码算法,主要包括SM1、SM2、SM3、SM4等,并持续完善。SM1是对称加密算法,加密强度与AES相当,需加密芯片支持;SM2是非对称加密,基于ECC算法,签名和密钥生成速度优于RSA;SM3为杂凑算法,安全性高于MD5;SM4为对称加密算法,用于无线局域网标准。本文提供使用Java和SpringBoot实现SM2和SM4加密的示例代码及依赖配置。更多国密算法标准可参考国家密码局官网。
186 1
|
1月前
|
存储 算法 安全
ArrayList简介及使用全方位手把手教学(带源码),用ArrayList实现洗牌算法,3个人轮流拿牌(带全部源码)
文章全面介绍了Java中ArrayList的使用方法,包括其构造方法、常见操作、遍历方式、扩容机制,并展示了如何使用ArrayList实现洗牌算法的实例。
16 0
|
4月前
|
人工智能 算法 大数据
算法金 | 推导式、生成器、向量化、map、filter、reduce、itertools,再见 for 循环
这篇内容介绍了编程中避免使用 for 循环的一些方法,特别是针对 Python 语言。它强调了 for 循环在处理大数据或复杂逻辑时可能导致的性能、可读性和复杂度问题。
53 6
算法金 | 推导式、生成器、向量化、map、filter、reduce、itertools,再见 for 循环
|
4月前
|
机器学习/深度学习 人工智能 自然语言处理
算法金 | 秒懂 AI - 深度学习五大模型:RNN、CNN、Transformer、BERT、GPT 简介
**RNN**,1986年提出,用于序列数据,如语言模型和语音识别,但原始模型有梯度消失问题。**LSTM**和**GRU**通过门控解决了此问题。 **CNN**,1989年引入,擅长图像处理,卷积层和池化层提取特征,经典应用包括图像分类和物体检测,如LeNet-5。 **Transformer**,2017年由Google推出,自注意力机制实现并行计算,优化了NLP效率,如机器翻译。 **BERT**,2018年Google的双向预训练模型,通过掩码语言模型改进上下文理解,适用于问答和文本分类。
157 9
|
4月前
|
算法
Raid5数据恢复—Raid5算法简介&raid5磁盘阵列数据恢复案例
Raid5算法也被称为“异或运算”。异或是一个数学运算符,它应用于逻辑运算。异或的数学符号为“⊕”,计算机符号为“xor”。异或的运算法则为:a⊕b = (¬a ∧ b) ∨ (a ∧¬b)。如果a、b两个值不相同,则异或结果为1。如果a、b两个值相同,异或结果为0。 异或也叫半加运算,其运算法则相当于不带进位的二进制加法。二进制下用1表示真,0表示假。异或的运算法则为:0⊕0=0,1⊕0=1,0⊕1=1,1⊕1=0(同为0,异为1),这些法则与加法是相同的,只是不带进位。 异或略称为XOR、EOR、EX-OR,程序中有三种演算子:XOR、xor、⊕。使用方法如下z = x ⊕ y z
Raid5数据恢复—Raid5算法简介&raid5磁盘阵列数据恢复案例
|
3月前
|
算法
【算法】贪心算法简介
【算法】贪心算法简介
|
3月前
|
算法
【算法】递归、搜索与回溯——简介
【算法】递归、搜索与回溯——简介

热门文章

最新文章