漫谈分布式系统(6) -- 跑的快,也别忘了省钱
这是《漫谈分布式系统》系列的第 6 篇,预计会写 30 篇左右。每篇文末有为懒人准备的 TL;DR,还有给勤奋者的关联阅读。扫描文末二维码,关注公众号,听我娓娓道来。也欢迎转发朋友圈分享给更多人。
1
前面两篇分布式存储的文章讲过,存得下不够,还要存得好。存得好,主要是为了节省成本。
因为海量数据随之带来的,就是海量成本。
同样,算得快也不够,还要尽可能压榨机器计算性能,节省成本。
有别于分布式存储引擎在存储方式上做文章,由于计算逻辑优化的空间有限,并且相对属于应用层需要考虑的问题(当然,通用的优化也可以做,以后会讲),分布式计算框架更多尝试对资源的调度做优化。也就促成了一系列所谓 Resource Manager 的诞生,典型的如 Google 的 Borg 和 K8S,Apache 旗下的 YARN、Mesos,都可以归到这个大类。
2
以往,公司不同业务都会有自己专享的各种服务器和集群。这很好理解,每个业务都希望能独立运行,不受其他程序的干扰,也不留下安全隐患。
但业务负载是动态变化的,规律性的波峰波谷,不规律的业务增长和下降,随之而来的就是频繁的扩缩容。为了降低扩缩容带来的工作量和对业务的影响,一般都会留有资源余量。
所谓余量,换一个说法,就是浪费。
怎么灵活又及时地把这些浪费掉的资源利用起来,顺便减轻扩缩容带来的维护成本,就是各种资源管理器要解决的主要问题。
3
最直观的想法,就是混部。机器不再专属于某个业务,而是大家共享。我业务不忙的时候,你就可以多用点,反之亦然。这样整体利用率自然就上来了。
也就是所谓的多租户(muti tenancy)。
多租户怎么共享资源呢,大家都提交任务,资源调度该怎么做呢?
最简单粗暴的是队列式的先进先出,所谓 FIFO。前面任务跑完,释放资源,后面任务才能分到资源。
显然,对多租户的支持,好处自然是整体资源率的提升,于整体有利;坏处就是牺牲了个体,失去独立性就意味着相互影响。
那怎么保证个体资源的需求呢?
4
要想保证个体的需求,只有一个办法,隔离。
于是,各种资源调度系统提出了 pool、queue 一类的概念,用来在逻辑上分配资源。可以给每个 pool 设置计算资源的配额,然后只允许某一个业务使用这个 pool。嵌套和多层的 pool 又可以给业务内的隔离提供便利。
但隔离之后,资源就不能共享了,整体利用率就降下来了。
所以不能硬性隔离,只能软性隔离。
于是给每个 pool 的配额是动态平衡的,支持借用和归还。
但是如果借用的份额长期不归还呢,比如被一个要跑 3 天的程序借用走了,就干等 3 天吗?
于是又支持强杀回收(preemption),抱歉,我等不了那么久,请立刻归还超出你额度的部分。为了让强杀温柔点,不至于引起大面积任务挂掉,又可以支持超出一定比例或(和)一定时间后才强杀。
强杀是后手,还可以先手。
给 pool 设置硬性的资源上限,无论别人怎么空闲,你也最多只能借用这么多。
综合到一起,就有了 Capacity Scheduler、Fair Scheduler 等各种调度器,在相互借鉴改进之后,也逐渐趋同。
比如 Fair Scheduler 也支持设置权重配额,这样相对的公平才是可行的公平。
比如公平策略从优先分给内存占用少的任务,改进成内存和 CPU 都考虑的 DRF(Dominant Resource Fairness) 策略。
比如 Google 的 Borg 为了支持流批混部,明确支持了优先级的概念。
比如工作日和周末使用不一样的分配策略,利用业务错峰来有效利用资源。
不一而足,都是在提高整体利用率和保证个体配额之间做 trade-off。
5
上面说的都是些思路,刻意回避了具体框架的架构和原理。因为那些都是实现,后面文章有需要的时候会再提到,而比实现更重要的是设计思路和解决问题的过程。
说了这么多,都是技术层面的东西。这么多机制和参数,到底要怎么设置呢?
就说配额吧,这么多业务,谁多谁少呢?
这个问题是资源分配的问题,和我们现实生活中的资源分配一样,需要有令人信服的规则,然后由各业务讨论一致(通常很难),或者让老板拍板。
如果你身处数据平台这类的基础设施团队,切记,你只是资源的管理员,手上握的是管理的责任,而不是分配的权利。
你要做的是说明规则,用技术手段保证整体利用率,然后提供各种指标帮助决策。不要越俎代庖,让自己处在风口浪尖。
下面简单列一些值得关注和参考的指标(不完整,只是示例):
平台整体计算资源使用率趋势
平台整体 running、pending task 数趋势
各 业务/队列 计算资源使用总量,包括 CPU 和内存,或者像阿里云那样用计算时整体代替(最好能转成 RMB,这样更有冲击力)
各 业务/队列 计算资源使用率占比分布
各 业务/队列 running、pending task 数趋势
各 业务/队列 抢占/被抢占 资源量和次数
6
我从我们的运营系统里找了两个以前的例子,来说明怎么通过一些指标来指导资源的分配。
下面这个图截取的是一个时间区间内,各个队列整体使用率的分布。
从这个图可以看出,大部分队列在大部分时间使用率都低于 50%,说明当时的配额设置是不合适的,应该把空闲资源多分些给更忙的队列。
下面这个图是部分队列的计算资源使用详情,计算公式是 实际使用资源/资源配额。
可以看到,第一个队列长期出于资源不够用的情况,通过抢占使用了超出配额 1倍多的资源;而最后一个队列平均只用到了配额的一半多点。也正是因为存在像最后一个队列这样用不完的情况,才使得第一个队列有了可以抢占的可能。
而抢占是滞后的,并且会受到硬顶上限的束缚,导致整体利用率偏低。所以应该减小最后一个队列的配额,并加大第一个队列的配额。
总结下,从第一个图,我们知道了资源分配的不合理,存在普遍的吃不完和不够吃的现象。进一步,从第二个图,我们知道了具体哪些队列吃不完,哪些又不够吃,从而知道了该怎么去调整配额。
剩下的,就是让各业务讨论,或者让老板拍板,把这个调整量化下来实施。
TL;DR
分布式计算框架更多尝试对资源的调度做优化,以此节省成本
提升资源整体利用率的方式是混部,错峰使用资源
混部就会相互影响,所以需要资源隔离
隔离又会导致资源借用受限,所以要软性隔离
资源借用需要有时间限制,所以要支持强杀
资源借用需要有容量限制,所以要能设置硬顶
没有绝对的公平,带权重和 DRF 都是折中和改进
平台部门是管理员,不掌握分配资源的权利,而应当提供足够的指标协助决策
小结下,通过最近几篇文章,大家应该对分布式存储引擎和分布式计算框架有了基本的了解。
知道了为什么会有分布式系统,分布式系统是怎么设计的,又应该怎么去更好地使用分布式系统来节省成本。
看起来一片美好,没有烦恼。
但是,世界上没有免费的午餐,伴随着好处,就一定会有问题。分布式系统远不是部署起来,调下 API 就等着出结果了。
后面的文章,我们就一起看下,分布式系统本身引入的一系列问题,以及怎么去解决它们。敬请期待。
关联阅读
原创不易
关注/分享/赞赏
给我坚持的动力
点在看,给大家好看