Content #
小明很喜欢在朋友圈分享自己的生活。这天是小明和女友小红的相识纪念日,小明特意在朋友圈分享了一张两人的情侣照。但是,小明发完朋友圈之后,小红一定能看到照片吗?会不会发生异常呢?
这次确实出问题了。
此时,小红也在刷朋友圈,看到了小明刚刚分享的照片,非常开心。然后,小红收到一条信息,简单回复了一下,又回到朋友圈再次刷新,发现照片竟然不见了!小红很生气,打电话质问小明,为什么这么快就把照片删掉?小明听了一脸蒙,心想我没有删除呀。
你猜这中间发生了什么呢?我用另一张流程图来演示这种异常。
在小明发布照片后的瞬间,小红也刷新了朋友圈,此时读取到副本 R1,所以小红看到了照片;片刻之后,小红再次刷新,此时读取到的副本是 R2,于是照片消失了。小红以为小明删除了照片,但实际上这完全是程序错误造成的,数据向后回滚,出现了“时光倒流”。
想要排除这种异常,系统必须实现单调读一致性(Monotonic Read Consistency)。关于单调读一致性的定义,常见的解释是这样的:一个用户一旦读到某个值,不会读到比这个值更旧的值。
是不是感觉有点蒙?让我来解释一下。
假如,变量 X 被赋值三次,依次是 10、20、30;之后读取变量 X,如果第一次读到了 20,那下一次只有读到 20 或 30 才是合理的。因为在第一次读到 20 的一刻,意味着 10 已经是过期数据,没有意义了。
实现单调读一致性的方式,可以是将用户与副本建立固定的映射关系,比如使用哈希算法将用户 ID 映射到固定副本上,这样避免了在多个副本中切换,也就不会出现上面的异常了。