谷歌拼音盗用搜狗拼音词库事件,前段时间可谓闹得沸沸扬扬。搜狗拼音开发工程师那一篇
《搜狗拼音输入法词库是怎样炼成的》写得深入浅出、荡气回肠,令我等搜狗拼音粉丝们深感搜狗词库来之不易,谷歌窃桃之举可鄙之极。为了表示对搜狗拼音的一贯支持,本文还是照例用搜狗拼音撰写。
言归正传。最近某个应用产品团队突然提出要增加数十台服务器,让兄弟我大出了一身冷汗。现在机架空间紧张的很,我们预算也有限,怎么能你说加几十台服务器就给加几十台?为什么?凭什么?给个理由先?对方回答,说是根据最近一段时间对其应用集群平均负载的观察结果,以及运营方面预估的访问量增长趋势数据,得出要加几十台服务器的结论。那么问题来了,且不论运营方面怎么预估访问量增长,用当前的平均负载作为基数来估算服务器增长,靠谱么?
我们首先来看看平均负载(Load Average)到底是什么?这个问题似乎从未有人清楚地阐释过,我也只知道所谓平均负载,就是指当前Running和Runnable队列里的任务总数摊到每个逻辑CPU的平均数。貌似多数UNIX/Linux教材、书籍里谈到平均负载这个概念时,都是这么忽悠人的,甚至讲的比前面这句更为含糊。幸好Linux Kernel开放源码,我们既然碰到了问题,就不妨做个愣头青,直接去源码里找找答案。
仔细一找,果然发现 kernel/timer.c 里这段疑似代码:
/*
* calc_load - given tick count, update the avenrun load estimates.
* This is called while holding a write_lock on xtime_lock.
*/
static inline void calc_load(unsigned long ticks)
{
unsigned long active_tasks; /* fixed-point */
static int count = LOAD_FREQ;
count -= ticks;
if (unlikely(count < 0)) {
active_tasks = count_active_tasks();
do {
CALC_LOAD(avenrun[0], EXP_1, active_tasks);
CALC_LOAD(avenrun[1], EXP_5, active_tasks);
CALC_LOAD(avenrun[2], EXP_15, active_tasks);
count += LOAD_FREQ;
} while (count < 0);
}
}
|
又在 include/linux/sched.h 里找到了 CALC_LOAD 宏定义:
#define FSHIFT 11 /* nr of bits of precision */
#define FIXED_1 (1<<FSHIFT) /* 1.0 as fixed-point */
#define LOAD_FREQ (5*HZ) /* 5 sec intervals */
#define EXP_1 1884 /* 1/exp(5sec/1min) as fixed-point */
#define EXP_5 2014 /* 1/exp(5sec/5min) */
#define EXP_15 2037 /* 1/exp(5sec/15min) */
#define CALC_LOAD(load,exp,n) \
load *= exp; \
load += n*(FIXED_1-exp); \
load >>= FSHIFT;
|
看不懂了。本着“内事不决问老婆,外事不决问Google”的原则,还是Google一下。果然有位大仙,法号
Dr. Gunther ,曾专门撰写了一系列文章来研究这个 Load Average 的算法,及其背后的险恶用心:
1.
The "LA Triplets" Quiz
2.
UNIX® Load Average Part 1: How It Works
3.
UNIX® Load Average: An Addendum
4.
UNIX® Load Average Part 2: Not Your Average Average
5.
UNIX® Load Average Reweighed
略过各篇文章前面深深浅浅的描述和数学公式,只看最后的Summary或者Conclusion,我们就可以发现:
所谓负载(load),并非如我们想像的那样,表示系统的利用率,而只是反映CPU run_queue 的长度。这三个数字(1/5/15-min LA)只是三个不同时间序列的时点抽样,还是经指数阻尼平滑的平均数,而且它们是在以错误的顺序反映趋势信息。
既然平均负载(Load Average)的算法都不靠谱,那么以此为基数的估算又怎么可能不是扯淡呢?