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

数据中心内的负载均衡

Site Reliability Engineering · Ch 20 · Google · 2016

EN →

这一章讲什么?

你在 App 里点一下,请求飞进某个机房。机房里跑这个服务的可能有上千台机器,程序一模一样——请求该交给哪一台?上一章讲的是「请求进哪个机房」,这一章讲进了机房之后:在一堆长得一样的机器里挑一台,凭什么挑。

先说个怪事

超市结账,你当然找最短的那队。但假如有个收银员的机器坏了——每个顾客一秒钟就被打回来「付款失败,下一位」——他那队永远最短。于是所有人都往他那儿涌,谁也没结上账。

这就是机房里每天发生的真事:按「谁手上活儿最少」挑机器,坏掉那台看起来永远最闲。

那轮流发牌不行吗

一人一个轮着来,听着最公平。两个问题。

一是活儿轻重差很远。有的顾客只买一瓶水,有的推来满满一车。数「个数」不等于数「工作量」。

二是收银员快慢差很远。同一个机房里的机器有新有旧,旁边还有别的程序在抢资源。同样十个顾客,有人十分钟搞定,有人半小时。

结果总有一队排得特别长。而你配人手得按最挤那一队的水位来配——等于白养一批闲人。

三个招

第一招,别跟所有人打招呼。上千个调用方乘上千台机器,光「保持联络」就是几百万条线,两边都得掏内存、还得定时问一句「你还活着吗」。所以每个调用方只认识其中几十台。挑的时候还得讲究:随机乱挑会有的机器被很多人认识、有的没人理;按规则分配才能让每台被认识的次数一样多。

第二招,让机器自己举牌。别在外面猜它忙不忙,让它每次回话时顺便报一句自己有多忙——搭在回复里,不额外跑一趟。谁报得闲就多给谁。这是三种做法里最管用的。

第三招,要下班的人先挂牌子。一台机器要重启、要下线,别直接关灯走人——手上那几个顾客就砸了。正确做法是先挂一块「本通道不再接新客,已在队里的照常结完」的牌子,等队排空再走。书里管这块牌子叫跛脚鸭。没有它,一次例行重启就是一批用户当场看到报错。

带来了什么

粗的事在门口就办完了(进哪个机房);进了门只剩一件事:在同质的一堆机器里挑一台,而依据必须来自机器自己,不能靠外面猜。

诚实的代价:机器自报的忙碌程度,说的是刚刚过去那一小会儿的情况——负载突然抽一下,调用方手里的信息总是慢半拍。

一句话记住

机房内的负载均衡是调用方自己做的决定:先把要联络的机器缩到一小撮,再听机器自己报忙碌程度来分活,最后让要退场的机器先挂「不接新客」的牌子。最反直觉的一条是——「手上活儿最少」不代表最闲,也可能是坏了。

想进到具体机制、算法和示意图? → 切到精读版