无主节点备份
目前讨论的备份方法都基于这样一个想法,客户端将写入请求发送至一个节点,然后数据库系统将写入备份至其他节点;主节点决定了写入顺序。
一些数据库系统采用了其他方法,允许所有节点接收客户端的写入,无主从节点之分,也就是无主节点。这个想法在关系型数据库时代几乎被遗忘。它曾经在Amazon用于内部的 Dynamo系统后流行过, Riak, Cassandra, 和Voldemort这些无主节点备份模型也受Dynamo启发,这类数据库称为Dynamo-style。
一些无主节点的实现中,客户端直接将请求发送至多个节点,然后由调节节点发送至剩下的节点,不同于主节点,调节节点不会强制写入顺序。我们会看到,设计上的不同会有用途上的极大差异。
在节点停机时写入数据库
假设一个数据库有三个备份,如果是采用主从结构备份,主节点故障时,故障转移后才能继续写入数据库。在无主节点模式下,不需要故障转移,写入会平行发送至所有的三个节点,两个节点收到请求,故障节点丢失了;我们认为单个备份中有两个收到则写入成功,客户端忽略掉故障节点,如图5-10:
如果故障节点恢复了,客户端开始从该节点读取,那么客户端会收到过时的数据。为应对这个问题,客户端会同时向三个节点发送请求,或从正常节点那里收到最新的数据,从刚恢复的节点那里收到过时的数据,然后使用版本数据判断哪个值是最新的。
读取修复和负熵
备份模式应该保证最终所有节点上的数据相同,当一个故障节点重新加入集群,它该如何赶上丢掉的写入?
有两种机制:
写修复:当客户端平行地从多个节点读取时,会探测到哪个返回的数据是过时的。如图5-10, 用户2345从节点1,2读取到版本7的数据,从节点3读取到版本6的数据,可以判断节点3上的数据是过时的,然后将新值写入节点3。这个方法适用于读频繁的系统。
负熵进程:一些数据库系统有后台进程持续检查各个备份间的数据差异。不同于有主节点的日志备份系统,负熵进程复制数据是无顺序的,而且复制完成前的延迟很长。
不是所有的系统都能实现两种机制。没有负熵进程,读取很少的系统一些备份可能会丢失值,因为只有读取应用才会进行读取修复。
Quorums for reading and writing
在例5-10中,如果三个节点中有两个写入成功,那么判断写入成功,如果三个中只有一个成功呢?我们如何推断?
如果我们知道三个中有两个写入成功,那么可以判断至多只有一个节点写入失败;如果从至少两个节点读取,那么可以保证读取到的节点至少有一个是最新的,不论第三个节点是故障或者响应慢,我们保证能获取到最新的值。
假设有n个节点,每次写入保证至少w个节点写入成功,每次至少从r个节点读取数据,示例中n=3,w=2,r=2. 只要w+r>n, 我们预计能在读取时获取最新的值,因为读取的节点至少有一个是最新的。r和w被分别称为读取和写入的quorum。
在 Dynamo类型数据库中,参数n,w,r一般是人为配置的。一般n设置为奇数,w和r等于(n+1)/2. 当然也可以视情况而定,比如在读取频繁的系统中,可以设置为w=n,r=1,这能加快读取,但是只要一个节点故障,系统的写入就停止了。
满足w+r>n的条件,可以让系统允许以下故障:
如果 w<n, 我们可以在一个节点不能用的情况下处理写入。
如果 r< n, 我们可以在一个节点不能用的情况下处理读取。
n=3&#