概述
网易轻舟基于K8s的业务混部署实践
- 前言
- 资源利用率现状和原因分析
- 在/离线业务混部
- Kubernetes Native Feature
- 混部系统设计
- Resource Reclaim
- 动态调度
- 动态资源分配和动态资源隔离
- 离线业务重调度
- 落地成果
- Redis+视频转码
- 广告推荐+视频转码
- 总结和展望
- 参考文献
导读: 服务器资源利用率较低,IT基础设施的总拥有成本(TCO)逐年上涨,一直是困扰很多企业的难题。随着云原生技术的发展,Kubernetes逐渐成为数据中心的一项基础设施,将在/离线业务统一使用Kubernetes调度编排日渐成熟。本议题结合网易轻舟在这一领域的工作实践,介绍如何基于Kubernetes通过混合部署,在不影响在线业务的前提下将CPU利用率提高到50%以上,大幅降低企业数据中心成本。
作者:张晓龙、李岚清、陈林亮
前言
数据分析显示,数据中心成本中,服务器采购成本占比超过50% 1, 2 ,而全球服务器平均资源利用率不到20%,并且服务器一般3~5年就会淘汰,需要购置新服务器,造成了巨大的成本浪费。
如果数据中心或者机房规模较小,服务器数量有限,很少有人会去关注资源利用率这个问题。因为在小规模场景下,耗费人力、物力想办法提高服务器资源利用率并不会获得太高的收益。如果数据中心规模比较大,提升数据中心资源利用率则能够显著降低成本、带来巨大收益,所以国内外的大型互联网公司,很早就开始投入大量的人力物力进行较多的探索实践。
近几年,随着网易云音乐、严选、传媒、有道等互联网业务的快速发展,网易内部的服务器数量不断攀升,而实际资源利用率又比较低,IT基础设施成本问题日益严峻。面对日益增长的业务,我们希望用最小的基础设施资源成本来支撑更大的业务需求。提升服务器资源利用率成为一个比较重要的解决手段。
网易轻舟团队提出了一套基于kubernetes的业务混部方案,目前已经在网易内部得到广泛应用,在不影响业务SLO(service-level objective)的前提下,资源利用率得到显著提升。
本文将从以下几个方面逐步展开:
- 资源利用率现状和原因分析
- 如何通过混部提高资源利用率
- 落地成果
- 未来展望
资源利用率现状和原因分析
麦肯锡数据统计显示,整个业界的服务器平均利用率大约为6%,而Gartner的估计要乐观一些,大概在12%。国内一些银行的数据中心的利用率大概在5%左右 3 。
而造成利用率比较低的原因主要有以下三个方面:
- 不同类型的业务划分了独立的服务器资源池
绝大多数企业在构建数据中心或者机房的时候,对于在线服务(latency-sensitive service)和离线服务(batch job)是单独采购机器并且分开管理部署的,各自采用独立的资源调度管理系统(比如离线业务使用Yarn调度,在线业务Mesos调度),从服务器采购、规划到业务调度层面都是完全隔离的。
图1(b) 是Google 专门运行在线应用的2万台服务器CPU利用率分布图,大部分处于30%左右。图1© 是Google专门运行批处理作业的2万台服务器CPU利用率分布图,大部分在75%左右 3。
在线业务SLO要求较高,为了保证服务的性能和可靠性,通常会申请大量的冗余资源,因此,会导致资源利用率很低、浪费比较严重。而离线业务,通常关注吞吐量,SLO要求不高,容忍一定的失败,资源利用率很高。
假如将离线业务跑在在线业务的机器上,充分利用在线业务的空闲资源,那是不是就能节省下离线业务的服务器成本了呢?
- 服务的reserved资源和实际used资源存在较大Gap,通常overprovision
业务通常是有波峰和波谷的,用户在部署服务时,为了保证服务的性能和稳定性通常都会按照波峰申请资源,即 provision resource for the peek load,但是波峰的时间可能很短。另外,也有相当一部分用户对于自己服务的资源使用情况不是很了解,在申请资源时具有较大盲目性,但是通常也是申请过量资源而不是申请的过少。
图2 是推特数据中心资源使用情况,可以看到cpu利用率大约在20%左右,但是用户申请了60%左右的cpu资源;内存利用率在40%左右,但是用户申请了80%左右的内存资源 4。
服务A已申请的但是实际没有使用的资源,即使是空闲的,其他服务也是不能够使用的。Reserved - Used
差值越大,资源浪费越多。所以我们应该如何去缩小Reserved - Used
的差值,从而提高业务部署密度和资源利用率呢?
- 业务负载具有明显的时间上的波峰波谷,处于波谷时,空闲资源其他服务无法使用
很多面向用户的在线服务具有明显的波峰波谷,比如白天用户使用量较多,资源利用率相应较高,但是夜间用户使用量较少,资源利用率相应较低。夜间空闲出来的资源,其实都是浪费的。那夜间空闲出来的这部分资源是不是也可以用来跑离线业务呢?
在/离线业务混部
在线业务(latency-sensitive service):和用户存在交互的、并且对交互延时敏感的应用称为在线业务。例如:网络搜索服务、即时通讯服务、支付服务、游戏服务等,延迟对于这些服务的服务质量至关重要,故称为“延时敏感”,在线业务通常有着严格的SLO(service-level objective)5。
离线业务(batch job):和用户不存在交互,对延时不敏感的应用称为离线业务。例如:Hadoop生态下的MapReduce作业、Spark作业、机器学习的训练作业、视频转码服务等。这些作业对于其完成时间的容忍度较高,故称为“延时不敏感”。离线业务通常没有严格的SLO 5。
混合部署(co-location):是指将在线业务和离线业务混合部署在同一集群和服务器上。
传统的数据中心中,之所以将在/离线服务分开部署管理,实属无奈之举:
- 混部会带来底层共享资源(CPU、内存、网络、磁盘等)的竞争,会导致在线业务性能下降,并且这种下降是不可预测的
- 在/离线服务分属不同的研发、产品团队,成本管理是分开的
- 在/离线服务使用不同的资源调度管理系统,无法统一调度
如果能够将离线服务跑在在线服务的机器上,充分利用在线服务的空闲资源,则能够显著提升资源利用率降低服务器成本。
随着云原生理念、容器和微服务的普及,Kubernetes 逐步统治了容器编排领域,成为数据中心的基础设施。将在/离线业务统一使用 Kubernetes 调度管理,日渐成熟。
接下来,本章节会详细讲解如何基于 Kubernetes 实现在/离线业务的混部,在复杂的基础设施架构下,面对众多的共享资源,如何实现多维度的资源隔离,最小化在/离线业务之间的性能干扰,保证在线业务的运行性能、提升离线业务运行效率。
Kubernetes native feature
因为要基于Kubernetes 实现在/离线业务的混部,所以需要先了解 Kubernetes 有哪些功能能够帮助实现混部,以及 Kubernetes 本身存在哪些问题。
Pod Priority
pod是有优先级(pod priority)的,相应字段是pod.spec.priority
,它表示了pod的重要程度,值越大优先级越高。调度器调度的时候会优先调度高优先级的pod,Kubelet在驱逐过载节点的pod时,会优先驱逐低优先级的pod。
所以,可以将离线任务设置较小的pod priority。
Pod QoS
Pod有三种QoS class:
Best Effort
: 如果pod的cpu/memory资源的request和limit都没有设置,则该pod属于Best Effort
类型Guaranteed
:如果pod的cpu/memory资源的request和limit都设置了,并且每个资源的request值等于limit值,则该pod属于Guaranteed
类型Burstable
: 剩下的则是Burstable
类型
其中,Guaranteed
pod对于 SLO 要求最高,有最高的资源保证;Burstable
pod对于 SLO 要求次之,仅保证 request 部分的资源;Best Effort
pod 对于 SLO 要求最低,资源无法保证。
QoS class | oom_score_adj |
---|---|
Guaranteed | -998 |
Best Effort | 1000 |
Burstable | min(max(2,1000-(1000*memoryRequestBytes)/machineMemoryCapacityBytes),999) |
Best Effort
类型pod的 OOM Score 是最大的,也就是说在发生系统OOM的时候,首先kill的就是Best Effort
类型的pod。
当节点上内存、磁盘等非可压缩资源负载过高时,kubelet会驱逐上面的pod,保证节点稳定性,驱逐的顺序是: Best Effort
、Burstable
、Guaranteed
。
所以,是不是可以将离线任务归为Best Effort
class 呢?
Kubelet CGroup Manager
Kubernetes 是使用 cgroups 来实现pod的资源限制的。
图4 是Kubernetes cpu cgroups的层级,三种不同的颜色表示三种不同的QoS class:
- kubepods 的cpu.share 只在kubelet启动的时候设置一次
- besteffort和burstable的cpu.share,每隔1分钟更新一次. 有pod创建删除也会触发更新
- pod的cpu.share和cfs quota只在创建时设置,后面不再更新
图5 是Kubernetes memory cgroups的层级,三种不同的颜色表示三种不同的QoS class:
- kubepods 的memory.limit_in_bytes 只在kubelet启动时设置一次
- besteffort和burstable的memory.limit_in_bytes,后面不会更新
- pod的memory.limit_in_bytes只在创建时设置,后面不会更新
之所以在这讲一下Kubernetes pod cgroups的层级组织结构和动态更新策略,是因为我们开发的资源隔离组件也是通过更改cgroups配置来实现资源隔离的。如果不知道Kubernetes原生的cgroups管理策略,很容易发生更新失效或者冲突,引发故障。
K8S 本身存在的问题
- 静态调度
Kubernetes是使用的静态调度。静态调度是指根据容器的资源请求(resource request)进行调度,而不考虑节点的实际负载。所以,经常会发生节点负载很低,但是调度不了新的pod上去的情况。
Kubernetes为什么会使用静态调度呢?因为要实现一个基于节点负载进行动态调度的通用框架是很困难的。而静态调度实现简单、管理方便,但是对于用户的要求要高一些,如果 resource request 配置的不合理,可能会导致节点之间负载不均衡以及利用率较低。
- 隔离性较弱
Kubernetes 是没有区分在线业务和离线业务的,当前的cgroups层级组织结构也很难将在/离线业务区分开,很难实现动态的资源分配和动态的资源隔离。所以,也无从谈起在/离线业务的性能隔离,顶多就是不同pod之间的隔离。
而 Kubernetes 对于pod之间的资源隔离也是很弱的,仅仅通过cgroups在cpu维度使用cpu.shares
控制发生cpu争用时的时间片分配比例,使用cfs quota
限制cpu使用上限;内存维度使用memory limit in bytes
限制使用上限。
如果贸然将在/离线业务混部在同一台机器上,是无法保证在线业务的SLO的。
混部系统设计
我们基于 Kubernetes 实现了在/离线业务混部系统,遵循以下设计原则:
- 动态调度:根据节点的真实负载实现离线业务的动态调度
- 动态资源分配和隔离:根据在线业务的负载,动态调整分配给离线业务的资源量,动态执行资源隔离策略,降低甚至消除彼此之间的性能干扰
- 插件化:不对k8s做任何in-tree的侵入式改动,所有组件要基于k8s的扩展机制开发,并且混部系统本身扩展性强
- 及时响应:当混部节点资源利用率过高,或者对在线业务产生影响时,能够及时发现,并驱逐离线业务,以保证在线业务的SLA
- 可运维、可观测:对用户和运维人员友好,接入成本低,使用成本低
Resource Reclaim
Resource Reclaim是指回收在线业务已申请的,但是目前还空闲的资源,然后给离线业务使用。这部分资源是low-quality
的,没有太高的可用性保证.
我们自定义了扩展资源colocation/cpu
和colocation/memory
(分别对应原生的cpu和memory),来表征上述 reclaimed resource
,实现离线任务的动态调度。
节点上在线业务CPU Usage高,则我们分配给离线业务的资源就会减少;在线业务CPU Usage低,则我们就可以将更多的资源分配给离线业务。
动态调度
基于扩展资源colocation/cpu
和colocation/memory
实现离线任务的动态调度,优先将离线任务调度到节点负载较低、离线任务较少的混部节点上,均衡不同节点之间的负载、减少业务之间的资源竞争。
动态资源分配和动态资源隔离
Google 在数据中心资源管理领域,很多年以前就开始投入大量人力、物力。由于硬件在性能隔离上的局限性,Google在软件层面做了大量的改造,率先提出了多项资源隔离技术,包括cgroups、Container等(内核的很多功能特性都是业务需求触发的,而不是凭空想象出来的)。我们对于在/离线业务的性能隔离也是主要通过cgroup来实现的。
kubelet cgroup manager 没有可扩展点,直接修改kubelet代码又会给后续的运维升级带来比较大的成本,因此我们单独开发了一个zeus-isolation-agent
运行在每个混部节点上,通过定时动态更新cgroup来实现在/离线业务资源隔离。
从CPU、内存、缓存、磁盘到网络,我们实现了多维度的隔离策略,显著降低在/离线业务之间的互相干扰。以缓存为例,我们对内核进行了定制化改造,给在/离线业务设置不同的缓存回收优先级,优先回收离线业务使用的缓存。
离线业务的重调度
存在这样一种场景,刚开始时混部节点上的在线业务较少、负载较低,能够分配给离线业务的资源较多,因此用户能够调度较多的离线业务上去。但是,后来用户调度了更多的在线业务上来或者在线业务的流量飙升,导致节点上能够给离线业务的资源非常有限,离线任务执行效率会很低。假如此时,其他混部节点比较空闲,为了避免离线任务的饥饿、减小业务之间的资源竞争,我们会重调度离线任务到其他node上。
离线任务的重调度,主要有如下优点:
- 均衡各个混部节点的负载情况,避免有的节点负载较高而有的节点又过于空闲
- 避免某个节点负载过高,以至于影响到在线业务性能和稳定性
- 提高离线业务的执行效率
但是,重调度也有缺点,如果没有远程checkpoint机制,会导致重调度之前的算力被浪费。影响程度有多大,是跟单个任务的处理时长有关系的。如果处理一个任务的时长是秒级,那么重调度的影响是微乎其微的。如果处理一个任务的时长是天级别的,那么重调度的影响还是比较大的。因此,是否使用重调度功能、重调度的触发阈值等用户都是可以实现workload级别的配置的。
落地成果
上述在/离线业务混部方案已经集成到网易轻舟容器平台NCS中,在网易内部得到广泛应用,大幅提高了服务器资源利用率,取得显著成果。
以网易传媒为例,传媒将视频转码业务作为离线业务混部到了在线业务的机器上,混部后CPU利用率从 6%-15% 提高到 55% 左右。
先了解一下视频转码服务的特点:
- CPU密集型,大量读写磁盘保存临时数据,有一定量网络IO
- Long-running pod,而不是一个
run-to-complete
类型的pod,它会从队列中不断取视频任务进行转码处理,没有任务的话就空闲且保持运行 - 转码单个视频的时长在秒级,因此重调度对其影响是微乎其微的
Redis+视频转码
Redis业务是对于时延比较敏感的在线业务,SLO要求较高,但是其CPU利用率较低,因此我们尝试将视频转码业务混部到了Redis专属节点上,下面我们看一下这两个在/离业务混部的效果。
从图9 可以看到,Redis节点混部前CPU利用率在8%左右,混部后达到30~35%,利用率大幅提升。
然后我们再看一下混部前后redis的SET/GET操作的RT对比。
_ | 调用次数 | 平均RT(ms) | ms0_3 | ms3_10 | ms10_n |
---|---|---|---|---|---|
混部前 | 7.0E | 0.45 | 99.49% | 0.3% | 0.21% |
混部后 | 6.5E | 0.45 | 99.53% | 0.27% | 0.2% |
从图10 和 表3 可以看出,混部前后GET操作的RT 基本没有变化。
_ | 调用次数 | 平均RT(ms) | ms0_3 | ms3_10 | ms10_n |
---|---|---|---|---|---|
混部前 | 285W | 0.62 | 99.35% | 0.4% | 0.25% |
混部后 | 284W | 0.63 | 99.39% | 0.37% | 0.24% |
从图11 和 表4 可以看出,混部前后SET操作的RT 基本没有变化。
广告推荐+视频转码
广告推荐服务也是一个对稳定性和性能要求很高的时延敏感的在线类型业务,下面我们看一下转码服务和广告推荐服务混部取得的效果(节点上还有其他类型的在线服务,这里我们以时延敏感的广告推荐服务为例)。
从图12 可以看到,混部之前cpu利用率在10-20%之间,混部之后cpu利用率长时间维持在55%左右,利用率提升幅度较大。
混部的目的是提高资源利用率、降低成本,但是前提是不能对在线业务产生明显的性能影响。因此,我们再看一下该广告推荐服务的某个核心性能指标在混部前后的变化:
从图13 发现,混部前后该核心性能指标是没有任何衰减和恶化的,混部前的平均RT是6.59ms,混部后的平均RT是6.65ms:
_ | 调用次数 | 平均rt(ms) | 失败次数 | ms0_10 | ms10_20 | ms20_n |
---|---|---|---|---|---|---|
混部前 | 10.3E | 6.59 | 0 | 81.99% | 5.62% | 12.39% |
混部后 | 10.2E | 6.65 | 0 | 81.82% | 5.61% | 12.57% |
总结和展望
目前,混部已经在网易得到广泛落地,取得显著成果。接下来,我们会继续探索和实践云原生技术,基于网易轻舟将混部方案落地到更多企业,让更多企业享受到云原生的红利。
参考文献
- [1] The Datacenter as a Computer
- [2] Overall Data Center Costs
- [3] 数据中心成本与利用率现状分析
- [4] Quasar: resource-efficient and QoS-aware cluster management
- [5] 浅谈混部系统研究
- [6] PerfIso: Performance Isolation for Commercial Latency-Sensitive Services
- [7] Borg: the Next Generation
- [8] Autopilot: workload auto scaling at Google
- [9] Improving Resource Efficiency in Cloud Computing
作者简介:
张晓龙,网易技术委员会委员,网易数帆轻舟事业部技术总监,2012年浙江大学博士毕业后加入网易杭州研究院,负责基础设施研发/运维至今。在虚拟化、网络、容器、大规模基础设施管理以及分布式系统等技术架构有多年经验,当前主要兴趣点在云原生技术方向。
李岚清,网易数帆轻舟事业部资深系统开发工程师,具有多年Kubernetes开发运维经验,负责在/离线业务混部、容器网络编排等多个项目,推动和协助网易内部多个业务实现容器化。目前专注于云原生、分布式系统架构等技术领域。
陈林亮,网易杭州研究院资深云计算开发工程师,具有多年云计算开发,运维及优化经验,参与开发网易云计算平台研发及迭代。目前专注于在/离线业务混部、容器编排资源优化等方向。
最后
以上就是哭泣钢笔为你收集整理的网易轻舟基于K8s的业务混部署实践网易轻舟基于K8s的业务混部署实践前言资源利用率现状和原因分析在/离线业务混部落地成果总结和展望参考文献的全部内容,希望文章能够帮你解决网易轻舟基于K8s的业务混部署实践网易轻舟基于K8s的业务混部署实践前言资源利用率现状和原因分析在/离线业务混部落地成果总结和展望参考文献所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复