“可迁移会话的双令牌准入把已读R与已写W分别保存,按RYW/MR/MW/WFR选择本次下界;C001达不到110时明确拒绝,复制消息b1还须等待a1才能公开。它解释如何保存这里的会话知识,完整…”
形式陈述
同一会话怎样换一台服务器
因果一致性已经说明:客户端先前的写与读来源不能在迁移时凭空遗忘。本页把这份知识做成请求携带的两个令牌。目标是让客户端在副本间移动时,明确判断某次操作能否满足所请求的会话保证;不够新的副本要报告未完成,而不是返回一个恰好能查到的旧值。
固定m个写入来源和若干完整数据库副本。来源身份不复用,每个来源自己的写依次编号1、2、3、…。写的身份为(o,s),其中o是来源、s是其序号。来源自己串行产生写;接收端不会凭消息到达顺序重新编号。固定配置内没有状态回滚、身份更换或拜占庭伪造。收到的写由合法来源产生;参考器的字段检查不认证任意外部构造的消息。
副本保存已应用前缀F:F[o]=s表示该来源的1到s号写全部已经应用。这里复用向量的逐分量比较与最大合并,但只对写编号,不对每个网络事件递增。F=(2,0,1)表示来源A前两项和来源C第一项;它不能拿来冒充“收到A的2号,所以A的1号也已收到”。
写还携带创建时的依赖向量dep。只有该写是本来源下一项,并且dep≤F时,副本才公开它。否则返回WAIT,调用方保留消息以后重试。这个规则使每个公开前缀对写依赖向下闭合;到达网络缓冲与已经可见是两种状态。
两个令牌和四个准入位置
会话串行执行操作,始终保存两个初始为零的向量:R记已经读取的知识,W记该会话已经成功写入的身份。本文每次成功读返回与值来自同一原子状态的完整服务器F,再令R←max(R,F)。成功写(o,s)后只令W[o]←max(W[o],s)。这两个向量不会因为换服务器而清零。[1,§§4–5与Figure1]
四项保证在会话开始时选择,此后保持不变。检查规则如下,未启用的项贡献零向量:
| 操作 | 需要覆盖的令牌 | 保证 |
|---|---|---|
| 读 | W | RYW,读己之写 |
| 读 | R | MR,单调读 |
| 写 | W | MW,单调写 |
| 写 | R | WFR,写随读 |
若一项操作启用了两个检查,就逐分量取两令牌的最大值作为下界L。服务器当前F≥L才准入;否则返回INCOMPLETE,说明哪几个分量不足,本次准入不产生读结果、不创建写,也不更新会话令牌。服务端的检查与执行作为一次原子步骤,期间不会用另一个较旧版本回答。
RYW要求后续读所用数据库包含本会话先前写;MR要求后续读不丢失先前读的相关写。MW要求任何副本若公开后一会话写,就已公开前一会话写,且把前者排在后者之前。WFR对先前读所依赖的写施加同样的传播和排序要求。后两项约束还保护会话外的观察者,不能只在发起客户端检查一次。
写的依赖和顺序怎样落实
成功准入新写时,来源把当前完整F放进dep,生成自己的下一序号,并使用Lamport式逻辑顺序:新标量比本副本已知所有写的标量大一,再以来源身份打破并列。所有副本按这个总序解释同键覆盖,保留顺序最大的值;它不是墙上时钟,不能从排序反推出因果。
接收方必须继续执行dep≤F的公开规则,并推进无洞来源前缀。若MW或WFR的下界已经在创建者F里,就进入新写的dep;任何后来公开该写的副本也必须先具备这些前驱。新标量又大于所有前驱,所以传播次序与冲突解释顺序分别获得证据。[1,§4的C1/C2及其较弱充分条件说明]
本页把一次本地检查/写入看成可靠操作,没有实现网络RPC结果去重或掉电恢复。明确的INCOMPLETE是在准入检查处拒绝;请求发出后网络超时的“是否生效未知”仍要按原RPC合同处理,不能把超时也填成这项拒绝结果。
直觉
“我写过”和“我读过”不能混成一张收据
编辑器保存文件后,即使还没读回,也希望下一次打开时不会退到保存前。它需要W。另一位用户只浏览他人发布的内容,没有任何自己的写,但页面刷新也不应忽然忘掉已经见过的更新。它需要R。
写随读把这份知识继续传给别人。例如先看到原帖再发布回复,只给回复标一个更大的数字还不够:远端若先展示回复,原帖仍可能不存在。依赖向量要求远端先补原因,逻辑顺序则保证两个更新共同出现时不会反着解释。
令牌是下界,不是指定唯一副本
若R=(1,0,0)、W=(1,1,0),同时要求MR和RYW的读需要F≥(1,1,0)。F=(1,1,4)与F=(3,2,0)都可以;并不要求回到原服务器,也不要求停在恰好(1,1,0)。如果所有当前可达副本都达不到下界,等待、换路由或明确未完成才符合合同。
因此会话保证也会损失某些可用性。没有依赖信息的读可以立刻返回旧值,携带令牌的同一次读可能无法立即完成。只说“客户端已经连上一台健康服务器”不足以证明这台服务器掌握所需历史。
例子与边界
A、B、C之间的一次迁移
三个来源与副本同名,下面把三维向量简写为100、110等。会话启用全部四项保证。初始各副本000,键均未赋值。
- 在A写a1:x=draft。A变为100,会话W=100,R仍000
- 转向B读x。B只有000,小于W,返回INCOMPLETE;不能把“B查不到”当成功缺键
- B应用a1后成为100,读x成功返回draft;R变100
- C独立接受c1:z=side,C成为001。此时会话没有读到它
- 在B写b1:y=reply。其dep为100,B变110,W变110
- 转向C写z=done。C001达不到110,准入被拒;把b1先发给C也只能得到WAIT
- C先应用a1成为101,再接收b1成为111,才可以接受c2:z=done;c2的dep为111,W变112
这时A仍100,后续会话读需要112,仍不能在A成功。它收到b1、c1、c2并满足逐项依赖之后才能追上。注意c1由别人写,却因C创建c2时已经知道它而进入c2的依赖;完整F是一种保守但简单的表示。
四项保证分别挡住什么
RYW的最短失败是同一会话在A写x=1,然后到未同步B读到初值0。MR的失败则不需要会话自己写:先在A读到别人写的x=1,再到B读0。后一例W仍零,因此仅检查W不能替代R。
MW的失败要看第三观察者:同一会话先在A写库文件,再在B写使用新接口的程序。若B没有先获取A的写,第三副本C可以先公开程序却没有库。只保证该客户端后续读不退步,无法修复已经对别人公开的程序。
WFR的失败是客户端在A读到原帖,然后在尚不知原帖的B发布回复。若回复没有继承R,C可能先看到回复。该会话此前没有自己的写,W=0,检查MW也挡不住。终点分别构造这些执行,不把四个缩写当成四种重复定义。
同一键值并不等于同一份知识
本文成功读把整个F加入R,这比只记录真正影响所读键的写更保守。A的F=101时,x仍是a1的draft,另一个分量只是无关键z的c1。读A的x后R=101,再向F=100的B读相同x,MR准入仍会拒绝。B其实有同一个x版本,只是缺少整体令牌带入的z更新。
原论文允许用当前服务器向量作为相关写集合的上集;这样可能多等,却不会放行一个遗忘必要写的副本。若要缩小令牌,必须另给完整的相关写证据,包括删除和查询影响,不能只把“返回值相同”当作版本知识相同。[1,§5]
单调读也不要求业务数值单调增大。先读库存8,再读一个合法后继版本中的库存3,可以完全满足MR。RYW同样不承诺永远返回自己写的字面值:之后另一个更高顺序的写可以覆盖它,只要自己写过的历史没有被所用视图遗忘。
推论与应用
安全性来自两个归纳不变量
第一,副本F始终代表真实无洞前缀,且公开任何写之前已经公开其dep。初态为空满足;接收只推进来源下一项,并先核dep,所以保持。第二,R覆盖所有成功读所携历史,W覆盖所有本会话成功写身份;逐分量最大更新保持两者,不足出口不破坏它们。
读准入时F覆盖相关令牌,因此满足所选RYW/MR。写准入时F覆盖所选W/R,随后这些前驱进入dep;第一不变量迫使每个观察者先公开它们,递增逻辑顺序又使前驱早于新写,得到MW/WFR。没有选中的保证不会由名称自动补齐,但某个具体执行可能碰巧满足它。
如果允许来源序号复用,或者副本重启回到较旧数据却继续声称原F,以上证书即失真。保存令牌不替代保存所指历史。客户端丢失令牌也不能假装仍是原会话;要么可靠恢复上下文,要么明确建立新会话并降低保证。
向量成本与等待范围
每个会话保存两个m维向量,占O(m)个整数。一次下界合并、准入检查、成功读令牌复制或写依赖创建需要O(m)项工作;当前值以散列表按键定位,期望常数,值字节复制和存储另计。整数是无界序号时,位宽随历史增长,也要另外收费。
参考器的receive每次只检查一条记录,工作O(m),不暗中扫描所有待收消息。WAIT后的再次提交由外部执行轨迹安排,次数与网络调度有关;本页没有用O(m)单次CPU工作冒充端到端时间界。服务器保存写历史、当前值和审计输出所占空间也不属于客户端的两个向量。
会话内四项保证不自动给一批分开的读一个共同快照。先读旧权限,再读依赖新权限的内容,即便服务器每次都正确保留会话知识,两个返回值组合仍可能不一致。两轮因果多键读取补的是这一个调用内部的结果合同;完整迁移与失败见会话读取终点。
参考资料
- [1] Douglas B. Terry、Alan J. Demers、Karin Petersen、Mike J. Spreitzer、Marvin M. Theimer、Brent B. Welch,Session Guarantees for Weakly Consistent Replicated Data,PDIS1994,pp.140–149;§3四项规格,§4读/写集合与服务器顺序/传播要求,§5及Figure1的两个向量、无洞前缀和保守整库读令牌
- [2] Leslie Lamport,Time, Clocks, and the Ordering of Events in a Distributed System,CACM21(7),1978,pp.558–565,印刷559–561页的Logical Clocks与Ordering the Events Totally:逻辑顺序与全序扩展。本文只给写分配身份和标签,未把来源前缀向量当作逐事件时钟