周末不定期更新:分布式系统中的幻觉

2018-03-31  本文已影响119人  科学Jia

Phantoms: 第一眼看到这个词的时候,就被它的美打动,什么样的幻影造就这个虚幻的世界?

Phantoms

最近我的兴趣稍微有点广泛,从分布式系统中的副本,分片,事务,不可靠的时钟,到Docker打包和Kubernete的编排文件,其间还偶尔看看Haskell的趣味编程书籍,老实说,我的好奇心真不是一般人能比。。。

Concurrency

Version Vectors

英文解释: We need to use a version number per replica as well as per key. Each replica increments its own version number when processing a write, and also keep track of version number it has seen from each of the other replicas.

中文解释:存在版本向量V1和V2,如果V1中所有节点的逻辑修改时间都不小于、且至少有一个大于V2中对应节点的逻辑修改时间,则V1比V2新。
例如系统中有两个节点N1、N2,开始时两个节点记录的数据项的版本都是V1((N1,10),(N2,20)),N1修改了数据,版本变成V2((N1,11),(N2,20)),V2比V1新;如果N2记录的版本是V3((N1,10),(N2,21)),则V3与V2发生了冲突。

如果是像中文解释里的情况,修改的是两个不的节点,V2((N1,11),(N2,20)),V3((N1,10),(N2,1))产生的冲突,也只能告诉有冲突,所以并不能解决冲突。

目前解除冲突的方法推荐:
客户端合并冲突Merging, 然后把合并后的结果发送回数据库。

总之,比较副本replica之间的状态,Version Vectors是正确的数据结构。(希望有人告诉我有更好的方式)

Lamport timestamps

网上有人评价lamport timestamps是一个partial order, 但是它的英文定义是:

A lamport timestamps bears no relationship to a physical time-of-day clock, but it provides total ordring.

再来体会一段Ta和version vector的区别:

Although there are some similarities, they have a different purpose: version vectors can distinguish whether two operations are concurrent or whether one is causally dependent on the other, whereas Lamport timestamps always enforce a total ordering.

所以它是一个通过强制手段让事件获得全序关系的方法么?

防止数据 Lost Update

啊,以前又有一个误区,觉得并发读不需要锁的概念,其实如果读不加锁,那么可能会存在这样的问题:如果有一个线程A在读数据, 譬如,某个视频的访问量:100,而这时候,另外一个线程B在写数据,修改此刻这个视频的访问量,101, 然后A读完以后,也对数据进行修改+1,变成了101,那么其实数据是有丢失的,因为正确的访问数据应该是102。所以并发读如果不加入类似读读共享锁,就会造成数据丢失。

解决办法

  1. Atomic write operations: Atomic operations are usually implemented by taking an exclusive lock on the object when it is read so that no other transaction can read it until the update has been applied.

e.g. 一般关系型数据库里都用到了并发安全指令:

UPDATE counters SET value = value + 1 WHERE key = 'foo'

  1. Explicit locking : 显示加锁机制
  2. Automatically detecting lost updates by DB: MySql不提供这样的检查。
  3. Compare-and-set: 通过比较新旧内容来判断是否你已经读到了最新的数据,如果你读到的旧数据已经发生了变化,比如被人家更新了,那么你这次操作将会失败。
    e.g.

UPDATE wiki_pages SET content = 'new content' WHERE id = 1234 AND content = 'old content'

需要注意的是:compare-and-set 并不安全,如果compare-and-set采取了隔离数据的方式,那么你可能取到的数据依然是old数据,有可能造成别人已经更新的数据丢失。这需要确认数据库Compare-and-set的机制是怎样的。

拜占庭问题的防止

分布式系统跟区块链不一样的地方在于,分布式系统是不允许拜占庭问题的出现,它默认为节点都是可信的,我们需要采取一些手段防止分布式系统中的不可信问题:

  1. 检查checksum;
  2. 检查输入;
  3. 增加多的NTP Server,保持时钟同步。(关于这里又是一个很长的课题要说。)

所谓网络延时(排队)的可能原因:

  1. 交换机网络排队;
  2. CPU处理排队;
  3. 虚拟机排队; 虚拟机共享资源,比如一个CPU导致的。
  4. TCP层面自己会进行网络控制排队(flow control)。

以上。

必须要放张我上工的照片: 周末不定期更新:分布式系统中的幻觉
上一篇下一篇

猜你喜欢

热点阅读