5 月 30 日,字节跳动技术沙龙 | 基础架构专场 进行了在线直播。我们邀请到了字节跳动基础架构团队资深研发工程师邵伟、江帆和大家进行分享交流。
本次沙龙给大家分享的主题是《大规模混合部署项目在字节跳动的落地实践》,希望这次的分享能够带给大家一些我们对混部的思考。
沙龙分享的内容将会围绕以下问题来进行:
首先是字节跳动为什么想要开启混部,它产生的背景是什么样的,字节内部的业务形态有什么样的特征使我们能够开启大规模的混部?
我们具体做了哪些事情来支持混部的顺利开启和落地,在其中遇到哪些问题和挑战?
以及,在字节内部,混部有哪些典型的应用场景,分别是为了解决什么问题,带来了哪些收益等等。
为了更好地回答这些问题,本次沙龙将分为两个议题,分别围绕上层控制逻辑和底层隔离技术进行展开。
以下是字节跳动基础架构团队资深研发工程师邵伟的分享主题沉淀,《自动化弹性伸缩如何支持百万级核心错峰混部》。
演讲内容大纲:
背景介绍
弹性伸缩
混部实践
下面我会首先着重介绍第一个议题,也就是《自动化弹性伸缩如何支持百万级核心错峰混部》,而关于底层隔离技术的分享将在稍后给大家带来。
首先了解下今天分享的大纲,在第一部分中,会对字节私有云平台的整体现状,和上面所托管的服务做一个简单的介绍,在这部分中将重点回答为什么需要对服务开启弹性伸缩,它跟混部间的关系是什么。第二部分的内容主要涉及到在控制层上如何实现大规模服务弹性伸缩,以及相关的基础组件如何才能支撑弹性伸缩的稳定性。最后,会介绍一下,我们在弹性伸缩的基础上逐步推动大规模混部上量的过程,以及具体落地的一些场景,还有对应的演进思路。
背景介绍
字节内部的私有云平台叫做 TCE,它底层使用 K8S 作为编排调度的系统,目前字节内部几乎所有无状态服务都是以容器的形式部署和运行在 TCE 之上,这些无状态服务主要包括典型的微服务,还有像推荐和广告等在类的偏算法型的服务。其中,微服务对于资源的申请比较简单,只涉及到 CPU 和 内存等,而算法类服务对稳定性要求更为严格,所以对资源有很更多定制化的需求,例如内存带宽、numa 节点的绑定等。这些无状态服务都是以 K8S Deployment 的形式进行多实例部署和管理的,每个实例通常会以 RPC 或 HTTP 的形式对外提供访问接口,并在上层通过 consul 或 lb 提供统一的外部访问入口和负载均衡的能力。这些特征使得这些无状态服务的实例天然是可以在集群的不同节点上进行动态迁移的,并且服务实例的资源利用情况跟流量的变化呈现正向的关系,这就为服务副本数的动态控制和调整提供了基础。
由于 TCE 上接管的服务数量非常众多,所以集群的规模也相应变得非常庞大,截止到目前为止,TCE 已经部署在中国、新加坡、美东等三个区域,底层搭建和托管的 K8S 集群数量超过了 40 个,总计包括约几十万台服务器资源;从应用规模上来说,TCE 上部署的服务数量也超过了 4w 个,对应的 Deployment 和 Pod 总量则分别超过了 30 万和 300 万个。随着业务的不断发展,集群规模还在处于不断增长的过程中。如此庞大的集群规模带来的问题就是资源成本的不断攀升,所以对于管理资源的架构团队而言,需要回答的一个核心问题就是如何才能尽可能的提高集群整体资源利用率。
为这个目标,我们对业务的流量特性进行了分析。首先我们观察到在线业务的一个非常重要特性就是天级利用率具有很强的稳定性,在没有特殊变更的情况下,在线业务每天的流量几乎不会发生变化。从这张图中可以看到,服务天级利用率在一周的时间维度上具有相同的波动曲线。而且通常来说,业务会倾向于申请比自己实际需要更多的资源,这样对服务本身的好处是可以在最大程度上保证流量服务的稳定性,但是造成的问题就是,始终有部分资源是业务即使在高峰期也永远用不上的,即图中红线和绿线之间的 Gap 就是一定程度上的资源浪费。

基于这一特性,我们可以采取的方式就是在合理范围内尽可能地把图中的绿线往下拉,具体的做法就是根据服务在过去一周中峰值利用率的最大值,动态调整服务的资源申请量,从而回收和再利用一定的冗余资源。当然我们会在峰值利用率的基础增加一定的 buffer 以适应服务 burst 的行为。这个策略就是服务级别的动态超售,超售对于微服务的资源回收具有非常明显的效果。
除此之外,我们发现在另外一些场景下仍然存在非常多资源的浪费,这就涉及到在线业务的另外一个特点,即在线业务的流量具有明显波峰波谷的潮汐变化。举个例子来说,几乎所有的用户都会在晚高峰的时段刷抖音,这样就会导致抖音相关服务的整体流量都上涨到一个比较高的水平。而到了凌晨,因为大家刷抖音的次数和频率又会下降,所以此时业务访问的流量会出现比较明显的波谷。这种潮汐现象对头部服务而言会非常明显,尤其是像抖音和推荐这类服务,它们波峰波谷间利用率的差距可能达到