字节跳动 YARN 云原生化演进实践
本文整理自字节跳动基础架构工程师邵凯阳、林友权在 2022 Hadoop Meetup 上的演讲,文章主要从演进背景、解决方案、上线收益和未来规划四个方面介绍了字节跳动 YARN 云原生化演进实践。
作者|字节跳动基础架构工程师-邵凯阳、字节跳动基础架构工程师-林友权
演进背景
- 离线调度系统基于 YARN 实现,主要包括 Resource Manager(RM) 和 Node Manager(NM) 两个组件,负责资源调度和容器运行时管理。字节内部在 YARN 的基础上进行了很多功能丰富和优化工作,针对不同场景实现了不同的调度器,例如:Batch Scheduler,Gang Scheduler 等。
- 在线调度系统基于 Kubernetes 生态,进行了很多优化,支持字节内部多样化的在线服务。
- 首先,在离线属于两套系统,一些重大活动场景需要通过运维方式进行在离线资源转换,运维负担繁重,转换周期长;
- 其次,现在的混部架构只是在部分节点上同时部署了 NM 和 Kubelet 两个 Agent,资源利用率仍有很大的提高空间;
- 最后,在离线是两套割裂的系统,Quota 平台、机器运维等都不能复用,大数据作业无法享受到云原生的各种好处,例如:资源池化、更好的单机隔离特性等。
- 重大活动场景(春节/双 11 等),在离线资源需要能够 高效、灵活地相互转换;
- 整个数据中心的利用率需要得到更全面、充分的提升,进一步 降本增效;
- 在离线 资源共池,Quota 管控、调度、运行、机器运维统一。
- 对计算引擎侵入较深,计算引擎侧需要做大量改造才能支持原先在 YARN 的各种特性;
- 生产环境的作业(百万级)非常多,如何从 YARN 平滑迁移到 Kubernetes 也是个比较大的问题;
- 特别地,部分比较古老的计算引擎,比如 MapReduce,目前处于 Maintain 状态,已经无法进行大的改造来迁移。
解决方案
Yodel 整体架构
- ZK / ETCD / KV State Store:支持将集群元数据信息持久化到 ZK、 ETCD 和 KV 等持久化存储,可以通过 API Server 方便地进行相关数据查询和更新;
- Remote Godel Scheduler:维护集群所有任务的资源请求,通过该服务将任务的资源请求转化为 Pod 写入 API Server,同时与 API Server 交互获取已调度的 Pod,最终将调度能力下沉到底层的 Godel Scheduler;
- Remote Kubelet Service:实现了原来 YARN 中 NM 的所有接口,例如:启动容器、停止容器、获取容器状态的接口。通过这个服务容器启动从 NM 切换到 Kubelet,最终将容器运行时的管理下沉到底层的 Kubelet;
- 用户从开发机或任务托管平台向集群提交一个任务;
- 当任务经过校验后,Yodel RM 会新建一个 App 对象并持久化至 API Server;
- Yodel RM 创建 AM Pod 并写入 API Server,等待底层调度器调度;
- Yodel RM 收到已经调度完成的 AM Pod 并进行相关转化操作;
- Yodel RM 将相关启动信息丰富至 AM Pod 中并 Patch 至 API Server 由 Kubelet 拉起相关进程;
- AM 启动成功后,随心跳主动向 Yodel RM 申请资源;
- Yodel RM 收到任务的资源请求后,通过 RGS 服务将资源请求转化为 Pod 对象或 PodGroup 对象并写入到 API Server;
- 底层调度器 Watch 到相关对象后,按照一定策略进行调度,同时 Yodel RM 也会及时地 Watch 到已经调度的 Pod;
- Yodel RM 会将已经调度的 Pod 转化为 Container,随心跳返回给对应的 AM;
- AM 收到已经调度的 Container 后,会再跟 Yodel RM 进行交互,来启动对应的容器;
- Yodel RM 收到容器启动请求后,通过 RKS 服务将容器启动所需要的信息丰富到 Pod 对象里并 Patch 到 API Server。Kubelet Watch 到待启动的 Pod 后,会进行这个 Pod 的启动。
- 首先,AM 启动起来后会随心跳申请资源;
- Yodel RM 收到资源请求后,会基于该资源请求的资源量、优先级等创建一个 Pod 对象写入 API Server。创建完成后,该 Pod 对象处于 Pending-Unscheduled 状态,等待底层调度器进行调度;
- 底层调度器 Watch 到新创建的 Pod 后,根据一定策略进行调度,调度完成后会将调度结果写入 API Server。写入完成后,该 Pod 对象的状态会变为 Pending-Scheduled 状态;
- Yodel RM Watch 到已经调度完成的 Pod 后会转化为 Container,该 Pod 对象的状态会变为 Allocated 状态;
- 新分配的 Container 会随心跳返回给 AM,Container 被对应 AM 拿走后,该 Pod 对象的状态会变为 Acquired 状态;
- AM 获取到容器后会与 Yodel RM 交互进行启动操作;
- Yodel RM 收到容器拉起请求后,会把容器启动所需的信息填充到 Pod 对象中并 Patch 到 API Server ;
- Kubelet Watch 到需要启动的 Pod 后,会启动相关进程,容器运行时由 Kubelet 维护。
Remote Godel Scheduler
- 最上层是 Quota Manager 负责进行 Quota 管理:Quota Manager 部分在 YARN 基础上进行了增强。在 YARN 中有队列的概念,但队列只支持一种资源类型。在 Yodel 中对此进行了扩展,一个队列可以同时支持两种类型的资源 —— Guaranteed Resource 和 Best-effort Resource。单队列支持两种资源类型后可以显著简化用户的队列管理成本,对用户使用更友好。
- Guaranteed Resource :稳定资源,使用 Guaranteed Resource 的容器一般情况下不会被抢占也不会被驱逐;
- Best-effort Resource:混部资源, 是在线节点出让的暂时空闲不用的资源,资源会随着节点负载情况动态波动,使用 Best-effort Resource 的容器可能会被抢占或驱逐;
-
- 中间层是 Allocate Service 负责进行请求转换和状态维护:主要包括四个子服务,Convert Reqeust To Pod Service 负责将任务的资源请求转化为 Pod 对象并写入 API Server;Convert Pod To Container Service 负责将已经调度的 Pod 转化为 Container 并返回给 AM;Update Pod Status Service 负责及时更新 Pod 状态并持久化至 API Server ;Delete Pod Service 负责在容器或任务结束时,及时删除 API Server 中的相关对象。
- 最下层 是 Remote Scheduler 负责进行调度和关键信息持久化。
- 100% 兼容 Hadoop 协议,用户无需要做任何改动,可以像原来使用 YARN 一样来使用 Yodel;
- 支持 GT 和 BE 两种资源类型,方便上层用户对平台的使用。
Remote Kubelet Service
- Patch Pod Service :主要负责收到 AM 拉起请求后,将容器启动所需的信息丰富到 Pod 对象中,这些信息包括:容器的 ENV 、 HDFS 自研列表、启动命令等;
- Pod Status Update Service :该服务会及时从 API Server Watch Pod 的最新状态,并将状态返回给对应 AM。
- LocalizationService : 用于下载 Pod 所需的 HDFS 资源;
- Log Serving : 用于方便用户查看 Pod 日志;
- Shuffle Service : 主要有 Spark Shuffle Service 及 MR Shuffle Service,这些 Shuffle Service 是从 NM 的进程解耦出来的,单独部署用于提供计算框架的 Shuffle 服务;
- Metrics Collector : 用于收集离线 Pod 运行时的各维度监控信息;
- Webshell : 方便用户通过 Web 端进入到容器的 Shell,方便排查问题。
- 改造了 NM Client SDK,使 AM 调用 startContainer 时能直连 RKS;
- RKS 收到启动请求后,会把 containerLaunch 上下文等信息写入到 Pod 并 Patch 到 API Server;
- Kubelet Watch 到离线 Pod 后,会通过本机的 LocalizationService 下载 Pod 对应的 HDFS 资源;
- 下载完成后, Kubelet 通过 Containerd 把对应的 HDFS 资源挂载到容器的 Pod 里,之后通过 Containerd 启动 Pod;
- 启动完成后,Kubelet 会把 Pod 的状态更新回 API Server;
- RKS watch 到 Pod 状态变化后,同步更新内存中的 Container 状态,之后等待 AM 心跳时同步 Container 最新状态。
持久化服务
- MetaData:集群元数据信息、集群默认配置等;
- Queue (~300/cluster):队列 Quota、ACL 信息等;
- Application(~2W/cluster):Name、User、State 等;
- AppAttempt(~10W/cluster):Name、User、State 等;
- Pod (~30W/cluster):State、Annotation、ENV、HDFS 自研列表、启动命令等。
平滑迁移
- WorkFlow Hosting:作业托管平台,负责进行作业提交;
- ResLake:是 RM Proxy,可以根据一定策略把作业路由到不同集群;
- Quota Platform:用于同步队列的 Quota 信息;
- AutoMigration:负责从 YARN 集群下线节点,搬迁到 Yodel 集群上。
重要优化
性能优化
- Recover 阶段异步恢复 Pod 状态降低切主时间( 秒级):起初为了确保切主后集群、队列和任务的各维度统计信息准确,采用同步方式恢复 Pod,但上线时发现恢复过程非常耗时。为此通过优化,在确保各维度信息统计准确的前提下异步恢复 Pod 状态,将切主时间缩短到秒级;
- 异步多线程操作 Pod 以提高调度吞吐( ~2K/s):通过异步多线程方式将已经调度 Pod 转化为 Container 后,调度吞吐得到显著提升,目前调度吞吐可以达到每秒 2000 个 Pod;
- PodName 散列优化助力底层存储写延迟 降低为原来的1/100(百分之一) :因 API Server 底层采用基于 range 的 KV 存储,若 PodName 有序会频繁产生分区裂变,导致 API Server 的相关处理延迟显著增加。通过将 PodName 进行散列优化,将 Pod 打散存储在不同的分区中,底层存储写延迟下降 100 倍;
- 与 API Server 交互增强,Java Fabric8 Kubernetes Client 优化:
- 支持指数退让重试,增强 API Server 故障容错;
- List 操作默认添加 ResourceVersion 参数,避免击穿到底层存储;
- 将 Informer Resync 设置为 0,避免频繁内存拷贝造成 OOM。
-
运行优化
- AM 容器运行在单独资源池,独立优先级不可抢占:对于使用 BE 资源的容器有被抢占或驱逐的风险,而 AM 作为任务的 Master 一旦失败就会导致整个任务失败。为了避免此问题,将 AM 容器运行在单独的资源池,确保 AM 可以稳定运行避免任务失败;
- 支持镜像本地化约束,平均拉起速度提升约 1000 倍:一些离线任务的镜像比较大,在容器启动时拉取镜像会花费较多时间,进而导致启动时间变长。为了解决该问题,支持了镜像本地化约束,让容器可以尽量调度到有镜像的节点,该功能上线后容器平均拉起速度提升 1000 倍;
- 支持双栈节点和 v6 only 节点在单集群混跑:通过将双栈节点和 v6 only 节点混跑在同一个集群中显著降低了运维成本,同时也有利于资源利用率提升;
- Shuffle 数据写远程,避免打爆本地磁盘:shuffle 数据通常较大很容易将本地磁盘打满,将 shuffle 数据写远程后,可以避免因本地磁盘打满而导致任务运行异常;
- 大量引入 SSD 和 Nvme 磁盘,加速作业运行。
上线收益
- 高效资源切换:实现了 2022 元旦/春节 约 50 万核离线资源 分钟级出让,显著提高了在离线资源转化效率,为重大活动场景下的资源切换提供了坚实的技术支撑;
- 利用率提升:NM 和周边单机组件下线,降低 Overhead,带来单机 2% 利用率提升;
- 在离线统一: 在离线资源 全量共池,Quota 管控、调度、运行、机器运维统一。
未来规划
- RGS & RKS 部署云原生化
- 接入服务发现
- 支持容器化部署
- 可弹性扩展
-
- 开源 Yodel 回馈社区

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
张文歆:思维需碰撞,才有更大的“火花”|对话 Doris
「 对话 Doris」是 SelectDB 推出的系列专访栏目,本栏目将对 Apache Doris 社区优秀开发者进行访谈,希望通过他们在社区的成长经历,传递出对开源的态度、参与开源方法论以及实践经验,让开发者更加了解开源、了解 Doris,并呼吁大家参与到社区建设中来。 第 1 期我们邀请了 Apache Doris Committer、SelectDB 查询优化器研发 Leader 张文歆,一起来看看他在参与社区建设中都有哪些经验和大家分享吧。 推荐语: 从 15 年参加工作开始,也接触了许多开源项目,Apache Doris 是我遇到的最活跃的开源社区之一,“事事有回应,件件有着落”这句话用来形容 Apache Doris 社区再合适不过了。 —— Apache Doris Committer 张文歆 Q 1:你好,很开心可以与你交流,简单介绍下自己吧 我叫张文歆,2022 年初加入 SelectDB,主要负责 Apache Doris 新查询优化器 Nereids 的开发工作。我从 15 年研究生毕业后进入百度,17 年初转入离线计算引擎组,自此之后一直从事大数据相关的工作,...
- 下一篇
Sa-Token v1.33.0 更新,新增全局 Log 模块
Sa-Token v1.33.0 更新,新增全局 Log 模块 Sa-Token 是一个轻量级 Java 权限认证框架,主要解决:登录认证、权限认证、分布式 Session 会话、单点登录、OAuth2.0 等一系列权限相关问题。 框架针对踢人下线、自动续签、前后台分离、分布式会话…… 等常见业务进行 N 多适配,通过 Sa-Token,你可以以一种极简的方式实现系统的权限认证部分 Sa-Token v1.33.0 版本更新包括以下内容: 重构:重构异常状态码机制。 [重要] 重构:重构 sa-token-sso 模块异常码改为 300 开头,sa-token-jwt 异常码改为 302 开头。 [不向下兼容] 新增:新增全局 Log 模块。 [重要] 重构:SaTokenListenerForConsolePrint 改名 SaTokenListenerForLog。 [不向下兼容] 修复:修复多线程下 SaFoxUtil.getRandomString() 随机数重复问题。 修复:修复 sa-token-demo-sso3-client-nosdk 项目中单点注销 url 配置错误...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- CentOS关闭SELinux安全模块
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2配置默认Tomcat设置,开启更多高级功能
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- SpringBoot2更换Tomcat为Jetty,小型站点的福音
- CentOS7,8上快速安装Gitea,搭建Git服务器
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- Windows10,CentOS7,CentOS8安装MongoDB4.0.16
- Eclipse初始化配置,告别卡顿、闪退、编译时间过长