关于分布式概念的一些个人理解

起因

最近想了解分布式相关的概念,刚好之前也对像是线性一致性,顺序一致性,因果一致性,序列化,也就是CAP和ACID各种概念非常混乱和不解,有幸看到一些文章,有了一些新的认知,特此记录。

正文

CAP和ACID的研究对象不一样

首先,CAP和ACID二者讨论范围并不一样,

http://www.bailis.org/blog/linearizability-versus-serializability/

One of the reasons these definitions are so confusing is that linearizability hails from the distributed systems and concurrent programming communities, and serializability comes from the database community. Today, almost everyone uses both distributed systems and databases, which often leads to overloaded terminology (e.g., “consistency,” “atomicity”).

这篇文章里面很明确的说了就是CAP这个概念是从并发社区出来,然后ACID这个概念是数据库相关社区,最后由于技术发展,二者交融,产生了概念的过载(“overload”)。

CAP和ACID中的“一致性”

然后就是CAP里面的C究竟是什么了,还是参考的上面的文章,这个一致性主要是讨论的单个操作,单个对象,时间顺序之间的表现形式(single-operation, single-object, real-time order),也就是对不同分布式系统中这三项之间对外如何表现按照“一致性程度”进行建模,也就有了线性一致性(Linearizable),顺序一致性(Sequential),因果一致性(Casual)等等一致性模型,描述的是系统中读写对象的和标准时钟之间(每个一致性模型都会假设存在的一个标准的精确时钟【普通系统会有时钟漂移问题】)的可能情况。这篇文章里面有些简单的一致性模型介绍,感兴趣可以看看哦 https://www.cs.columbia.edu/~du/ds/assets/lectures/lecture12.pdf

接下来是ACID了,其实这个是数据库事务的概念,而事务研究的对象是多个操作,多个对象,以及这一系列操作加之对象之后对外呈现出的操作顺序性问题(multi-operation, multi-object, arbitrary total order)【注意:事务研究的时候是不怎么强调时间概念的】,如果是你去想这个问题的话,你肯定会好奇这么多操作之间怎么交互吧,我怎么描述这么多操作作为一个整体(A,原子性)相互交叉运行,也就是事务并发的时候的一些表现(I,也就是隔离性),于是按照严重程度进行了一定的分级,也就有了各种隔离级别,描述事务并发时候的读写表现,和上面的一致性模型一样,都是抽象出来方便研究的。补充一句,这里ACID的C更多的是一种对于事务的“期望”,就是我希望设计好的数据库能够满足一致性(满足数据库约束,业务执行过程中的一些不变量[比如金额总数不变])。

CAP和ACID有关系吗?

那ACID的I和CAP中的C到底有关系吗?毕竟二者研究对象都不太一样。还真有,看下面这张图

https://xzhu0027.gitbook.io/blog/misc/index/consistency-models-in-distributed-system#session-guarantees

 

 

 CAP的C和ACID里面的I在严格一致性(Strict Serializability)产生交集,这也是分布式系统最强的一致性模型,这里有个有趣的说法,就是严格一致性就是序列化加上了真实时间约束,然后当严格一致性中的事务操作只包含一个原子操作的时候就等同于线性一致性,有趣吧。

题外话:从上面图的标记也可以看出来,CAP理论中的CA不能够共存其实是指线性一致性和顺序一致性不能和可用性共存,因为如果对于MongoDB了解过的话,Mongo其实提供了Casual Consitency Session这样子一个一致性模型(个人感觉更像是这个图里面的PRAM级别)

Quorum机制、共识算法与CAP

- Quorum机制从维基百科看就是其实一种抽屉原理的应用,核心就是少数服从多数,在客户端访问服务进行读写请求(Mongo的read/write  concern)、其他共识算法选主过程等诸多方面都有应用。单独靠Quorum是没有办法很好解决并发冲突(就是多个修改请求同时进行)以及对外表现的一致性的( https://zhuanlan.zhihu.com/p/73371271 )。比如raft就是Quorum + 版本号管理实现的强一致性

- 共识算法就是常说的paxos,raft,gossip,这些算法是为了保证CAP中的C(各节点数据的一致性)的手段,是系统内部达成一致、进行数据同步的一系列算法,根据对外表现上,有强一致性的算法:raft,以及弱一致性的算法:gossip。注意这里的一致性是指系统内部各节点在同步过程中的不一致状态是否会被外界观察到

http://icyfenix.cn/distribution/consensus/gossip.html

Paxos、Raft、ZAB 等分布式算法经常会被称作是“强一致性”的分布式共识协议,其实这样的描述抠细节概念的话是很别扭的,会有语病嫌疑,但我们都明白它的意思其实是在说“尽管系统内部节点可以存在不一致的状态,但从系统外部看来,不一致的情况并不会被观察到,所以整体上看系统是强一致性的”。与它们相对的,还有另一类被冠以“最终一致性”的分布式共识协议,这表明系统中不一致的状态有可能会在一定时间内被外部直接观察到。一种典型且极为常见的最终一致的分布式系统就是DNS 系统,在各节点缓存的 TTL 到期之前,都有可能与真实的域名翻译结果存在不一致。在本节中,笔者将介绍在比特币网络和许多重要分布式框架中都有应用的另一种具有代表性的“最终一致性”的分布式共识协议:Gossip 协议 

 

分布式事务、外部一致性

分布式事务简单理解下就是多个节点间的事务,也有相应的ACID的说法,这里一致性就有外部一致性、内部一致性这种说法。

参考:https://blog.csdn.net/qq_41775852/article/details/115379491

https://www.zhihu.com/question/56073588

这一块由于不太深入了解过,所以不敢尝试下任何断言。换个思路尝试从一个实现者的角度,结合现有Mysql的实现去理解这个问题。

首先我们都知道事务是数据库讨论的一项技术,那么分布式事务其实对应的就是分布式数据库。

那么你会怎么去实现分布式数据库呢?

1. “缝合怪”,利用中间件(比如ShardingJDBC)整合各种现有的数据库

2. “原生”,比如Oceanbase,大致思路就是 复制状态机+2PC,也就是各分片间的一致性由共识算法保证,分片间的事务提交用二阶段提交来实现

http://files.catwell.info/misc/mirror/2014-ongaro-raft-phd.pdf

 

 

 数据库有了,事务提交也实现了,别忘了,事务是多个操作,多个对象,如果多个事务并发了,我怎么保证并发呢,也就是 I 隔离性?

一个常规的思路是基于锁去保护资源,简单粗暴。效率肯定不高。于是类比Mysql的MVCC实现,是否可以在分布式数据库里面实现快照呢?我们知道Mysql的快照是基于事务id的单调递增特性的,可是分布式的节点他们的事务id可不一定是单调的,为了找到这样一种单调递增特性的东西,很自然就想到了时间戳,到这里出现时间的概念,是不是和CAP的一致性模型开始关联上了?所以,从这层来讲我还是具体更倾向于 外部一致性 = 严格一致性(Strict Serializability)这种讲法的。

题外话:貌似就是这种快照实现,以及单机时钟不准确,牵扯出了一大堆原生分布式数据库的问题,比如什么逻辑时钟,True Time之类的

小结

其实我们在阅读分布式相关的问题时候,脑海中要有个简单的分布式的问题模型,就是多节点,多数据副本,多操作,最关键的是操作还要尽可能并发(并发意味着冲突,延伸出来需要锁,MVCC的概念)。然后每个理论、模型其实就是研究了这个问题的某个方面,尝试去说明一些东西或者特征。

希望和我有同样困惑的朋友看完这篇文章之后有所收获。

参考链接

 在上面都粘了的,这里就不写了。

https://jepsen.io/consistency

https://www.mongodb.com/docs/manual/reference/read-concern-majority/

posted @ 2022-12-06 04:10  MarshWinter  阅读(57)  评论(0编辑  收藏  举报