参考:https://pdos.csail.mit.edu/6.824/notes/l-craq.txt
6.824 2020 Lecture 9: 链式复制,CRAQ
一、比较
防脑裂 | 立刻容错 | 读速度 | |
---|---|---|---|
Raft | ✔ | ✔ | 慢 |
CRAQ | × | × | 快 |
立刻容错指的是少数机器掉线并不需要整个系统停下来等。余下的机器仍可立刻正常服务。
二、链式复制
一组服务器排成一条线,A(头部) -> B -> … -> H(尾部)。
客户端要写,是在链的头部写,它会沿着一级一级传下去。(我想:传到尾部才算是commited)
客户端要读,是在尾部读。
缺点很明显,如果只在尾部读,也不快。
三、CRAQ要解决:能从任意一台机器读仍满足可线性化
保存对象的多个版本
对于存储的同一个对象,每台服务器保存多个版本。
1个干净版,多个脏版。每个脏版对应一次未commit的写。
(我想:尾部只有干净版)
脏版的意思就是还不确认尾部已经写入了。尾部写入以后,沿着链条反向传递ACK,确认写入
(我想:这个被确认版本就成了新的干净版,原来的干净版可以丢掉了)
从非尾部服务器读取
如果没有脏版,最近版是干净版(也就是已经commit的)那么就直接回复client了。
问题:如果最新版是脏版,可以直接答复客户端吗?
回答:不可以。举例,假设我是倒三服务器。比如说尾部已经发ACK通知倒二某版本ACK了,而我尚未知晓。外界客户端可能已经从倒二读到那个新的干净版。此时如果我答复客户我所知的干净版,则会返回一个旧版本。
CRAQ是怎么做的呢?
中间服务器应该向尾部发一条消息,询问它所认为的最新版本号。(是我们掌握的某个脏版)
四、脑裂
CRAQ不能防止脑裂。一条蚯蚓中间斩断,可能变成两条蚯蚓,各自再长出头、尾来。所以需要1台配置服务器。大家统一听从配置服务器指挥,以它能联系上/联系不上谁为服务器活还是当掉的标准,以它确定的头/中/尾顺序为标准。
这台配置服务器如果要容错,可以用一个Raft组来实现。