对于分布式系统设计,数据的一致性 (consistency, 后文均用 consistency 指代) 是一个非常重要的考虑方面。我们来用几篇文章由浅入深的讨论这个问题。
朋友圈的点赞 Bug ?
如果你是朋友圈的重度用者,不知道是否发现过这样一个现象:当你为朋友的 moment 点赞时,点赞名单中会瞬间蹦出很多其他朋友的点赞记录。你可能会疑惑,”难道大家都这么心有灵犀同时点赞么?” 但是这种现象一直在发生,看起来并非偶然。卖个关子,读完本文你应该就懂得背后的道理。
NoSQL 的一点历史
最近几年时间,No-relational (NoSQL) 型的数据存储方案,作为大规模分布式系统中的重要一环,越来越收到关注。几乎每个 Cloud provider (AWS, GCE etc) 都会把 NoSQL service 作为旗舰型的服务提供,甚至这某种程度上是整体分布式系统研发实力的象征。相比传统的关系型数据库,NoSQL 的存储方案有着更好的 scalability and availbility, 具体在此不多展开,今天我们讨论 consistency.
Strong Consistency
Strong Consistency,也就是强一致性。传统的关系型数据库是天然的强一致性:当一条数据发生添加、更新操作时,强一致性保证,在操作完成之后,所有之后查询该条记录的请求都会拿到最新的数据。由于大部分程序员都是从关系型数据库的时代成长起来,因此大家下意识中会把 Strong Consistency 作为理所应当的事情,但是关系型数据库的 Strong Consistency 是依赖数据加锁实现的,牺牲了系统的整体性能。
如上图所示,如果该数据库中有三个节点 (node), 如果 update 操作发生在 node A, 当操作完毕时,node A 需要把最新信息 replicate 到 node B/C, 这时为了保证 strong consistency, 所有在 node B/C 读取该条记录的请求都会被 block, 直到该条数据完整的从 node A replicate 完毕。
Eventual Consistency
Strong Consistency 设计中 blocking request 是一个非常常见的情况,当系统承受大规模 update/insert 时,整体 throughput 性能会收到很大影响。那有没有更合适的其它方案呢?
Eventual Consistency 来了:它保证当一个 update/insert 发生后,所有的 read request 会最终 (eventual) 读取到操作发生后的值。换句话说,假设一条 node A 中一条记录 x = 10, 下一个 update request set x = 20. 如果使用 Eventual Consistency 的架构,那么之后发生的 read request 仍有可能拿到 x = 10. 只不过最终在未来某个时间点,所有 read request 都会拿到 x = 20. 但这个时间点是不能保证的。
有朋友会说,”你耍我呢?更新数据之后还能返回旧值,这种方案有啥用?“
DNS
是真有用的。比如 Internet 离不开的 DNS 服务就是一个典型的 Eventual Consistency 模型。简单说,DNS 是一个域名解析服务,当你输入 google.com 的时候他会帮你转化成 google.com 后的具体 IP 地址。如果你有一定的网站部署经验,一定会遇到类似的情况:当你把自己的域名 (XXX.com) 绑定的 IP 从 IP 1 改到 IP 2 时,很长一段时间内,域名的访问还是会 hit IP 1, 过了几十分钟,甚至几天,所有的 traffic 才被导到 IP 2.
为什么这么设计?
DNS 是一个非常非常大规模的分布式服务。你每打开一个网页,都要经过 DNS 的域名解析。想象一下,如果 DNS 是一个 Strong Consistency 的架构,那么假设 google.com 改变了对应的 IP 地址时,世界上所有的 DNS node 都开始 block request to google.com, 然后等更新完毕之后再 unblock, 这个过程中大家只能对着浏览器发呆,不骂娘才怪。
但是使用 Eventual Consistency, 也许让 developer 的日子难过一些:迁移过程中需要保证 both old and new IPs 都用能使用,但对于用户的体验来说,这是无脑选择。
尾声
本文简单的介绍了 Strong Consistency 和 Eventual Consistency 的概念,下面几篇文章会具体分析 AWS / GCE 的具体实现,敬请期待。
最后说一句文章开头的朋友圈问题,你想明白了么?有两个选择:每次朋友圈开始时有个几秒钟的卡顿 VS 朋友圈的点赞可能不太准确,如果你是张小龙手下的产品经理,这是个无脑选择么?:) 另外,如果想看小编的朋友圈,欢迎加微信好友 “bao-zi-jun”.