NoSQL学习笔记(原理)

著名的CAP理论,如图所示

CAP理论图示(摘取自人云亦云)

C:一致性。既更新和读取的一致性。

P:分区容忍。既分布式

A:可用性。(包括SLA和性能)

关于一致性:

客户端侧:

假设有三个进程PA,PB,PC。都具有向同一存储的读写权限,PA写入后。

1、若能保证PB,PC读取到的都是PA的最新的更新。则实现了强一致性。

2、若从PA写入,到PB、PC能够读取到最新数据之间,有时间。称为若一致性,之间的时间称为不一致性窗口。最终PA,PB,PC都能够读取到PA的更新,称为最终一致性。

3、通知PB,PB能够PA最新更新的值。而PC只需要得到最终一致性。称为因果一致性。

4、PA总能读到最新的值,称为读己所写一致性。

5、在PA与存储系统的一个会话中都能保证读己所写一致性,则实现回话一致性。

6、某一进程,只要读取到了最新的值,就不会再读取到之前的值。称为单调读一致性

7、PA的多次更新请求,存储系统都能够保证顺序执行。则为单调写一致性

服务端侧:

需要将更新发布到整个分布式存储,尽量减少不一致性窗口的大小。

N:数据复制的份数

W:更新数据时需要保证写完成的节点数

R:读数据时需要读取的节点数

之间的关系是这样的:

W+R>N,写和读节点重叠。强一致性。

W+R<=N,弱一致性

W越大,可用性越低。

比如hdfs,N=3,W=3,R=1。写一份数据成功,需要将3个datanode都写成功,读取是客户端选择读取一datanode。所以hdfs是一个偏重CP滴。

一般可用性和一致性平衡的值是W=R=N/2+1

关于RAM和磁盘的名言:

“内存是新的硬盘,硬盘是新的磁带”“对于随机访问,硬盘慢得不可忍受;但如果你把硬盘当成磁带来用,它吞吐连续数据的速率令人震惊;它天生适合用来给以RAM为主的应用做日志(logging and journaling)。”

分布式的分布算法发展:

第一阶段:hash() mod n,n为节点数。这种分布方法会造成单点故障。

第二阶段:hash() mod (n/2)。每个key可以对应两个节点。client可随机选择,在一个不可用时,可切换下一个。利用hash算法硬编码实现负载的最大弊端是无法在不停服务的情况下动态增删节点。

第三阶段:一致性hash算法。如下图所示

一致性hash算法图示

实现上述一致性的算法:

vector clock:所有节点都记录自己的版本信息,用一个vector来记录所有的变更记录。W=1,R=N=3的情况。如下图所示:

N=R=3W=1的vector示例图

读取是从三个节点读取,根据版本取舍和合并需要应用解决。所以最好使用W=N,简化系统设计(牺牲可用性)。

Gossip协议(状态转移模式):

每个节点都保持一个Vector clock和state version tree。在一定的时间窗之后,每个节点的状态是相同的,state version tree包含所有的冲突update。状态同步的阶段和算法大致如下:

1、客户端查询:客户端带自己的vector clock发送复制节点(一个or所有?),节点返回在这个clock之前的vector clock列表,然后客户端根据merge所有的列表跟新自己的vector clock

2、客户端更新:客户端发送自己的vector clock,接收到的节点就跟本地版本比较,若client版本比本地低,则丢弃,否则,更新。

3、节点间也交换vector clock来合并version tree。

Gossip协议(操作转移模式):

暂时没看

两阶段提交和三阶段提交:

当集群规模增大时,首先采取master/slaver架构,但是存在写操作依赖master,存在单点故障。改进采用多master结构,每个master都有读写能力,就存在一致性的问题。可采用的一致性算法有两阶段提交和三阶段提交。

两阶段提交:

一个或多个资源管理器的活动由一个成为事务协调器的组件控制:

某班要组织一个同学聚会,前提条件是所有参与者同意则活动举行,任意一人拒绝则活动取消。用2PC算法来执行过程如下

Phase 1
Prepare: 组织者(coordinator)打电话给所有参与者(participant) ,同时告知参与者列表。
Proposal: 提出周六2pm-5pm举办活动。
Vote: participant需vote结果给coordinator:accept or reject。
Block: 如果accept, participant锁住周六2pm-5pm的时间,不再接受其他请求。


Phase 2
Commit: 如果所有参与者都同意,组织者coodinator通知所有参与者commit, 否则通知abort,participant解除锁定。

Failure 典型失败情况分析
Participant failure:任一参与者无响应,coordinator直接执行abort
Coordinator failure:

Takeover: 如果participant一段时间没收到cooridnator确认(commit/abort),则认为coordinator不在了。这时候可自动成为Coordinator备份(watchdog)
Query: watchdog根据phase 1接收的participant列表发起query
Vote: 所有participant回复vote结果给watchdog, accept or reject
Commit: 如果所有都同意,则commit, 否则abort。

两阶段提交的问题:在coordinator做出commit决策并开始发送commit之后,某个participant突然crash,这时候没法abort transaction,
这时候集群内实际上就存在不一致的情况,crash恢复后的节点跟其他节点数据是不同的。改进为三阶段提交。

三阶段提交示意图

缺点:网络分离问题,比如preCommit消息发送后突然两个机房断开,这时候coodinator所在机房会abort, 另外剩余replicas机房会commit。

真正一致性的算法paxos:(具体待补充)

存储实现:

CouchDB(具体待补充)

在bigtable中,内存中存放的是最新的数据版本。当内存databuffer满时,会在落地到磁盘新建dataset。当datatset过多时,合并。查询时按照版本顺序,即先读取内存中的,若没有再读取本地磁盘的最新版本,若没有再读取次新版本,依此类推。当update数据时,更改内存中的数据,同时写入commitlog中。

bigtable