专业书籍精读 · SRE · 第 23 章

管理关键状态:用分布式共识做可靠的状态复制

Site Reliability Engineering · Ch 23 · Google(Laura Nolan 等)· 2016

EN →

这一章讲什么?

在群里指定一个值班负责人,只要有人认领,事就有人管;但如果两个人同时以为自己是负责人,各改各的,那才是灾难。一堆机器天天要干这件事:谁是主库?这把锁在谁手上?SRE 第 23 章讲的就是——一群机器怎么才能可靠地「说好同一件事」

先说个怪事

2018 年 10 月,GitHub 东岸机房和网络枢纽之间断了 43 秒。就 43 秒,网站却降级了整整一天。那 43 秒里,东岸和西岸的数据库各自收下一批写入;等网通了,两边都有对方没有的数据,谁也不能简单覆盖谁——只能人工对账。43 秒的「说不上话」,换来 24 小时手工善后。

旧世界为什么难

土办法是:主机每秒喊一声「我还活着」,备机几秒没听见就自己上位。听着合理,但有个死结——听不见对方,你分不清是他死了,还是电话线断了。若只是线断了,你一上位,世上就有了两个「负责人」,这叫脑裂。更阴险的是,它平时看着完全正常,只在你最不希望出问题的那天露馅

靠谱的办法:凡事要过半数点头

假设有 5 台机器,任何决定必须凑够 3 票才算数。妙就妙在——世上不可能同时存在两拨各自凑够 3 票的人:3 加 3 是 6,比 5 还多,两拨人里必定有人被重复算了,而这个人不会替两件互相矛盾的事各投一票。于是「同时冒出两个负责人」从根上被堵死。断网时人少的那侧凑不够票,就老实停下来——停一会儿能恢复,数据分叉不能。

第二个诀窍是记同一本流水账:所有机器不各记各的账,而是把每一笔改动按完全相同的顺序抄进同一本账。账本和顺序一致,各台机器照着重放,结果就必然一样。

那该怎么办

这套东西早有人写好并被折磨了二十年——Google 的 Chubby、开源的 ZooKeeper 和 etcd(你用的 Kubernetes 就把集群状态全存在 etcd 里)。本章最实在的一句是:别自己造。你以为在写「简单的主从切换」,其实在写一个共识算法,而且大概率写错了。

代价也说清楚:每个决定都要等过半数机器点头,所以它天生比单机慢,机器摆得越远越慢——跨大洲问一趟,光速也要来回一百多毫秒。

一句话记住

一群机器要就「谁是老大、现在是什么状态」达成一致,唯一靠谱的办法是过半数投票 + 记同一本流水账;心跳加超时那套土办法迟早脑裂。而这种东西,请用现成的,别自己写

想进到具体机制、时序图和选型表? → 切到精读版