深入理解百度在离线混部技术( 二 )


 
在混部调度中,在线和离线使用相同的物理资源,在线看到的资源视图和离线看到的资源视图相互独立 。在线业务看到的可用资源依旧为整机资源进行静态分配,离线看到的可用资源为整机资源减去在线作业已经使用的资源 。

深入理解百度在离线混部技术

文章插图
 
从图中可以看出,在线申请用量和在线usage之间存在很大的差异,主要是由于研发同学部署业务选择容器资源规格时,带有一定的盲目性,申请量高于实际使用资源量或者按照超出峰值用量申请 。混部离线可以复用这部分可回收资源,通过快速填充离线作业,把这部分资源利用起来 。
 
高中优(在线)为静态分配 ∑High request + ∑Medium request <= Host Quota
动态计算低优(离线)可用量 Low Quota = Host Quota - ∑High used - ∑Medium used
注:以上是理想情况下的公式,实际应用中需要对离线使用量设置一个上限,此处排除了上限造成的影响 。下面会有单机资源管理的说明 。
 
由于 K8s 是静态分配,在 K8s 的 QOS 模型中 BestEffort 是不占用 request 的,即使一个 node 上即使资源已经分配完,但是 BestEffort 类型的资源依然可以调度上去,所以我们复用了 BestEffort 模型给离线任务使用,如上文架构图所示,这样有以下的优点:
 
  • 解决了在离线视图冲突问题,离线使用的 BestEffort 模型,对在线不可见
  • 兼容社区组件,比如 cadvisor 可以直接使用
  • 无需修改已有组件,包括 kubelet containerd runc,侵入性小,可以直接安装混部系统,享受混部带来的资源效能提升 。
 
3.2 优先级 
由于在离线业务同时部署在相同节点上可能会产生干扰,我们从调度和单机两个方面对在线离线做了优先级区分 。
 
大的优先级分为(高,中,低)三种,其中高优中优为在线业务,低优为离线业务 。每个优先级优化分若干小优先级 。
 
首先看一下 K8s 的 QOS 模型
  • Guaranteed : 当 Pod 中所有 Container 的 request == limit 时
  • Burstable : 当 Pod 中存在 Container 的 request != limit 时
  • BestEffort : 当 Pod 中所有 Container 均未设置 request, limit 时
     
对比 K8s 模型,百度混部调度器做了如下扩展:
深入理解百度在离线混部技术

文章插图
 
3.3 资源隔离 
由于在离线混部是将在线业务和离线任务混合混部到相同物理资源上,所以在离线业务由于流量激增,出现资源争抢时,如何保证在线的SLA不受影响,并且在保证在线服务的SLA时,也要保证离线任务的整体质量,保证离线作业的成功率和耗时 。
CPU 
cpuset 编排
针对于需要绑核的在线业务,单机上可以感知到 CPU 拓扑,不需要 kubelet 开启绑核机制,可以直接进行绑核,会将在线业务尽量绑在同一 NUMA node 上,避免跨 node 通信延迟 。
 
NUMA 调度
NUMA 是一种内存管理技术,在 NUMA 架构下 CPU 被划分为多个 node,每个 node 都有各自的 CPU core 和 local memory,node core 中的进程访问 local memory 和 remote memory 的代价是不一样的 。节点的所有内存对于本节点所有的 CPU 都是等同的,对于其他节点中的所有 CPU 都不同 。因此每个 CPU 可以访问整个系统内存,但是访问本地节点的内存速度最快(不经过互联模块),访问非本地节点的内存速度较慢(需要经过互联模块),即CPU 访问内存的速度与节点的距离有关 。
 
针对开启了 NUMA 的节点,我们感知 NUMA 架构,将在线业务绑在同一 NUMA 上,提升在线业务的性能,并且感知 NUMA 节点的负载,当 node 之间出现明显的不平衡时,进行重调度 。
 
离线调度器
在线业务要求实时性高,延迟低;为了保证低延迟,CPU 负载不会打的特别高,当 CPU 负载升高时,在线间干扰会导致延时增大 。而离线业务一般 CPU 利用率高,但是重吞吐不重延时 。所以如果能满足在线的延时保障,在线和离线跑在一个核上不会对在线造成干扰,那么可以极大的提升资源利用率 。
 
按照现在通用的 linux 内核调度器调度算法,无法给在线服务做 CPU 的强保障,无法区分在离线业务,会导致在线无法抢占离线 CPU,并且在负载均衡时,因为无法区分在离线业务,可能在线业务会分配到相同的核上,无法打散 。导致性能下降 。


推荐阅读