正文
nginx,http/https 请求到 processes / application 间的映射。
Memory manager,virtual memory 到 physical memory 间的映射。
hypervisor,VM 到物理机器间的映射。
AWS EC2 service,VM 到 hypervisor 间的映射。
Spark,map/reduce job 到计算节点间的映射。
通过这些映射,我们得到很多好处:
仔细观察上面的例子,我们不难发现,待处理任务的数量往往远大于资源的数量,甚至,二者相差好几个数量级。这种用少量的资源打肿脸充胖子完成大量的任务的无耻行为,在计算机领域有一个漂亮的名字,叫 over subscription。你仔细琢磨,其实很多商业领域尤其是互联网,其秘密就在于 over subscription 这个小小的词语中。比如运营商给你的 50M 包月网络;早期 gmail 提供的不断增长的 1G 邮箱容量;aws 拍着胸脯对每个客户宣传:老表,来我们这场子,S3 管够,EC2 想要多少就有多少。
反过来,我们要想支持 over subscription,那么,通过添加一个 scheduler 把资源的两端解耦,就可以解决。
到目前为止,大家对 scheduling 已有一个粗浅的认知 —— 这时我们的脑海里便会浮现出很多很多的疑问。这其中,最重要的问题是:这世上没有无缘无故的便宜给你占。享受到 scheduler 的马杀鸡,代价是什么?
scheduling 究竟有多快(多慢)?
还是拿 linux scheduler 说事。scheduler 本身的运行会消耗资源,这边是其最主要的代价。自然,我们希望这代价越小越好。于是,下一个问题是:当 linux 做一次 reschedule 的动作时,究竟耗费多少资源(CPU 时间)?
要想回答这个问题,我们先得回答另一个问题:怎么测量?
要测量上图中桔色的部分,有两个直观的方法。一种方法是在入口和出口记录时间,然后计算 diff,最后求平均值 —— 然而 scheduling 的动作并不受你我掌控,用户态下很难找到其入口和出口。另一种方法是我们让青色的区域无限接近零,让整个时间片都被桔色的区域占满,这样,任务运行的时长便是 scheudling 花费的总时长。按照这个思路,用户态的代码需要被简化到只做一件事情:一旦被执行就立刻阻塞自己,让 scheduler 毫不犹疑地把 CPU 让给小伙伴们。
这个思路 linux 下面的 perf 工具已经给你实现好,直接调用即可:
staging