大家好,我是 K&D,一名 10 年以上大数据架构 &研发经验从业者,目前主要从事云原生大数据方向设计,擅长云原生技术、数据架构、数据平台构建、大数据组件性能调优
前言概述
在上一篇离在线混部架构模型文章中,我们讲到了大数据离在线混部的架构模式,同时也整体回顾了一下大数据架构的演变历程,概括性的来看,从数据处理范式中更多的是做批流一体、存算分离等方向演进,这种能力可以视为整个平台或者业务支撑的底层架构支撑,然后,在架构之上,还有关于组件选型、资源调度、监控运维等等相关的设计工作,然后在上层作为和业务开发关联最密切的平台,会涉及到数据处理、元数据管理、数据集成等平台架构,这三种能力基本是组成云原生数据平台的几个核心要素。这种架构模式也是逐步演变的过程,也是先有上篇中讲到的底层架构,才有了根据不同业务沉降的不同模式,才有了为了更好的支撑业务和提升开发效率而延伸出来的数据平台架构。
好了,关于架构方面我们就暂时说这么多,在本文中我会更多的介绍关于资源调度方面的内容,以及,在云原生大数据背景下如何选择调度引擎,会从以下几个方面进行阐述:
-
为什么 Hadoop Yarn 慢慢脱离了作为大数据资源调度的支撑位置?
-
云原生调度相比 Hadoop Yarn 调度有哪些优势以及不足之处
-
离在线混部调度下,我们应该关注哪些技术?
-
本文总结
一、为什么 Hadoop Yarn 慢慢"脱离"了大数据的支撑位置?
其实,了解 Hadoop 生态发展历程的朋友们知道,Hadoop 最早期的版本中是有没有 Hadoop Yarn 这个组件的,只有分布式文件系统(GFS)也就是现在的 HDFS、分布式计算框架 MapReduce,到了 Hadoop2.x 的时候,将 MapReduce 里面的调度功能拆分了出来,单独创建了一个项目叫 Hadoop Yarn 用于做资源调度引擎,自此,大数据的三架马车才正式成立,以 Hadoop 为代表的大数据生态开始了迅猛发展,逐步的 Spark 和 Flink、Storm、Tez 等这种分布式计算引擎替代了 MapReduce,但是 HDFS 和 Yarn 的地位始终没有动摇(截止到当下也是稳稳的主导地位),基本上下面是双足鼎立,上面是有多种不同的数据库、计算引擎框架,来支撑不通场景下的分析 &查询需求。
这时我们要多加思考一点,为什么文件存储 HDFS 和资源调度 Yarn 基本上没有主流的替代品呢?(中间其实有一些厂家做了,但是没有普及起来,比如 Mesos),这里我罗列一下我个人的一些思考结果,仅供参考:
-
Hadoop 生态是根基,是作为行业标准式进行发展,并且后面很多引擎都是向 Hadoop 体系兼容
-
社区发展健全,由 Apache 基金会进行开源运营,大批量开源爱好者加入,正如当下 Kubernetes 之于 CNCF
-
迁移难度和复杂度高,大数据集群不像应用服务,可以随时迁移切换,底层服务保存着数据会涉及到数据迁移,大批量组件迁移
-
学习成本高,当时大家学习技术入门门槛相对较低,Hadoop 在当时算是比较复杂的应用了,毕竟分布式系统在那个时期还并不是很普及(2008 年-2012 年)
但是,随着虚拟化技术的不断迭代和更新,同时期随着 Docker 技术的诞生,Kubernetes 编排框架的开源之后,一切貌似又在悄悄的发生着变化,这里面解决最核心的问题在于:虚拟化隔离技术的增强,一是更加轻量化;二是隔离性更强。
首先我们来看一下 Yarn 整体架构设计:
当我们要提交一个任务到 Yarn 上面时,请求会先到 Resource Manager(后面简称为 RM)中,RM 会选择在相应的 NodeManager 中启动若干个 Container 进程,并从中选择一个作为 Application Master(下面简称为 AMaster)来负责 Container 的管理以及和 RM 之间通信,当 AMaster 连接之后,会从 RM 中申请资源,拿到资源信息之后,再去对应的 Container 中启动一些 Task 来执行具体的计算任务。
那么,从 Hadoop Yarn 的使用上来讲,能够满足大部分的计算引擎的场景,但是从当下以及长远角度来看,它其实无法友好的支撑下去,主要原因在于:
-
配置复杂度高 (Yarn 配置方面,yarn label、hostname、)
-
调度器性能存在不足
-
资源争抢问题
二、云原生调度相比 Hadoop Yarn 有哪些优势和不足?
上面内容提到了 Hadoop Yarn 和容器化技术相关的技术实现特点,那么现在都说要做云原生大数据,相比于 Hadoop Yarn 来说云原生调度方面有哪些优势和不足呢?
下面,我们从以下几个方面来剖析一下:
-
资源隔离性
-
调度算法支持
-
弹性能力
-
成本与性能
01:多租户隔离技术
从资源隔离角度来看,我选择站在 Kubernetes 一方,如果读者朋友们有大规模使用 Yarn 的场景的话,请回想一下是否遇到如下类似问题:
-
任务执行快完成的时候被 Killed 掉了
-
命名区分了队列,但是队列隔离效果不明显
-
Hadoop Yarn 代码越来难以维护了(实在受不了了,所以吐槽一下!)
以上看起来都是很平常的问题,但是长而久之暴露了不少底层的不稳定性,虽然 Hadoop Yarn 支持了 LCE(Liunx Container Executor)隔离机制,但是这种隔离机制在现有调度算法情况下依旧无法解决资源争抢问题,而且必须要指定为 Capacity Scheduler,这种队列在某种情况下为了提升集群的吞吐性能,会允许队列之间的资源抢占,而导致某些任务被强制 KILL 掉。
在 Kubernetes 中,隔离是基于 Namespace 来实现的,Namespace 是 Kubernetes 系统中的一个重要对象资源,它的主要作用就是实现多个租户的资源隔离,而且是从操作系统内核层面进行了强隔离。
默认情况下,kubernetes 集群中的所有的 Pod 都是可以相互访问的 ,但是如果将两个 Pod 划分到不同的 namespace 下,这两个 pod 就无法进行直接访问。kubernetes 通过将集群内部的资源分配到不同的 Namespace 中,可以形成逻辑上的”组"的概念,以方便不同的组的资源进行隔离使用和管理。
同时我们也可以通过 kubernetes 的权限管控,将不同的 namespace 交给不同租户进行管理,这样就实现了多租户的资源隔离,并且还可以通过 kubernetes 的资源配额机制,限定不同租户能占用的资源,例如 CPU 使用量、内存使用量等等,来实现租户可用资源的强隔离。
02:资源调度算法能力
这个怎么说呢?Hadoop Yarn 本身是支持三种调度策略,分别为:FIFO 调度(先进先出)、Capacity 调度(容量调度)、Fair 调度(公平调度),当时也支持自定义调度,但是我从来没有使用过,所以这个就不太好评判,单说这三个调度来讲,对于大部分场景来说是完全够用的,但是,对于高性能计算场景来说,这些能力是远远不够的,比如 AI 的场景、机器学习场景,这时候就凸显出来 Kubernetes 提供了设计范式,Kubernetes 整个框架的厉害之处就在于它将所有能力都提供了可以灵活插拔的插件机制,它自身只提供基础能力和维护各个插件之间的协议(ps.感兴趣的读者可以了解一下 Kubernetes 的 CRD 机制,也许后面可以单独一篇文章来讲解),正是因为这种设计范式,给了大众很大的设计和开发自由度。
再说到调度算法机制,Kubernetes 本身提供的调度策略是比较欠缺的, 但是其生态内有非常不错的调度插件。在下面的调度系统选型中我会给出比较有代表性的开源项目。
03:弹性能力
这一点毋庸置疑,云原生的天然优势就在于快速弹性伸缩,相对于 Hadoop 的技术架构,基于 Kubernetes 的云原生架构展现出了灵活、弹性、轻量等特点。
下面从弹性角度来简单聊聊(更多弹性 &存算的内容,后面在单独一篇来输出)
从本人近些年使用 Hadoop 的经验来讲,Hadoop 在 3.x 版本之前可以说是完全存算耦合的架构,但是在 Hadoop 3.x 的版本中,做了一系列的特性支持,比如:生态兼容性(对象存储、Docker)、内核隔离、多个 NameNode 服务等等,可以说解决了一部分的弹性问题,但是长远来看,依旧无法使得大象快乐的奔跑,源于 Hadoop 这头大象的起初的设计构思就是分布式存算一体、数据就近计算、亲和性调度、廉价机器,因为在当时 Hadoop 设计的年代(2008 年左右),机器性能还没有达到现在这么高,网卡的带宽往往是百兆网卡,磁盘吞吐率只有 50M/s 左右,硬件的限制条件决定了它只能做本地化的计算,所以,我至今记得刚接触大数据的时候,当时的代名词“可以运行在任意廉价的机器上”。这十多年的更新迭代,代码量级已经超级大,如果要完全兼容新老功能, 这件事情可能不如重新一套系统实现来得快。
那从现实角度来看,Kubernetes 系统的出现,某种意义上来讲就是重新实现的一套系统,这套系统是面向未来至少十年的,反观 Kubernetes 以及容器化技术的设计定位:松耦合、存储编排能力、弹性、资源隔离等等。
弹性最大的好处就是资源按需,混部资源的本质也是弹性,只不过支持了更多不同资源介质的弹性条件
04:成本与性能
在上篇文章中,有给出三种大数据离在线混部的架构模型,其实稍微思考一下就会发现,其本质就是降低成本,而不同的架构模型在不同的场景下都可以带来一定程度的成本优化 ,这个是显而易见的,但是在抛开性能只考虑成本就属于“耍流氓”行为。
还是从上文中的架构模型来看,无论是哪种其实都会有性能的损耗,性能损耗主要来自两个方面,一个是网卡,一个是存储,从网络层来看,混部的架构是存储与计算分离的典型架构,那么在计算的时候就会涉及到多节点之间的数据拉取,还有中间过程的 shuffle 传输,这是一种损耗。另外一个是存储层,一般作为离在线混部架构中,在线的集群磁盘存储空间往往都不会太多,这就导致当离线作业调度到在线集群中的时候,计算过程所产生的临时数据(如 shuffle),都会瞬间打满磁盘空间,那这时候极有可能会对在线集群的稳定性造成影响。
所以,在离在线混部架构中(其他架构同理),我们不能只考虑成本而抛开性能与稳定性问题,那针对上面的性能与稳定性问题有什么处理方式吗?当然是有的,这里一般的处理方案如下:
-
任务调度策略
-
RemoteShuffleService 方案替换本地磁盘
-
监控运维保障
第一:其实可以作为混部任务调度里面的标准策略玩法,将计算任务区分优先级,部分可以调度到混部,部分不可以,这个要根据具体业务场景来区分,另外就是根据实际业务区分不同队列或者标签玩法,Hadoop Yarn 中支持标签配置,可以将混部的节点默认打上独立标签,这样避免所有任务都跑在混部集群中,最后就是针对在线集群的改动,在某些离线分析场景下,我们可能需要每天零点到八点之间占用在线集群的资源,那么在这个时间点可以将在线集群的服务调度同某几个节点组的标签中,这样可以最大的化保障在线服务的稳定性(在线服务最好是无状态的)
第二:就是通过 RemoteShuffleService,RSS 可以解决本地盘 shuffle 问题,由一个统一的 shuffle 服务来提供支持,在同一个网络内解决本地盘吞吐的同时,对性能也有小幅度的提升(具体要看算子类型),通常,在存算分离和混部场景下,离线任务计算性能只要不低于或者稍微低于一点本地集群的计算性能是在成熟范围之内的。
第三:从运维监控保障机制来看,是所有设计架构之初都要考虑的核心因素之一,为了实现功能而忽略了监控也是“耍流氓”行为,我认为一名合格的架构师和开发人员,都应该为所开发的系统负责,这个负责不仅仅是开发完成,更重要的是功能可维护性、可运维性、易用性,出现问题是否能及时感知,而不是上线之后不闻不问。我经常给团队研发强调一个事情,所有人从需求评审到方案设计到上线再到后续保障,我们所开发的需求不能以单一的上线为目的,上线只是功能实现之后的最低标准,稳定性、性能,出现问题排查手段和处理能力都要考虑到,基于此,基本上我们所负责的线上系统很少出现问题,即便是出现了问题,我们能很短时间内处理完成,也许可能业务还没有感知到,我们已经恢复了,然后我们会通知客户某某时间点,出现了短暂了 xx 问题,目前已恢复。进而得到了客户的信任,我一直认为这是合格程序员的标准之一,并且远远大于你的技术水平。关于这一块,也有很多做事准则,后续可以考虑单独一篇来聊一下
综上所述,那从架构设计上可以参考如下:
三、离在线混部架构下,应该关注哪些资源调度技术?
在混部系统使用中,我们尤其要关注就是资源的使用情况,不能让离线任务影响到在线服务的稳定性,不能因为让离线作业资源分配比例过小,在发生资源不足时,要优先保障在线服务,而要对离线作业进行驱逐,那么这里就对资源调度系统有了极大的要求,这里推荐两款基于云原生的高性能调度引擎,比如:
华为开源的 Volcano:
华为开源的 Volcano 是 CNCF 下首个基于 Kubernetes 的容器批量计算平台,Volcano 主要解决的就是目前各种新兴高性能计算需求的持续增长,Job 的调度和管理能力的支撑能力不足而出现的,它从调度算法的多样性、调度性能的高效性、主流计算框架的无缝对接、异构设备的支持等等这些需求场景而出发,而这些场景和需求在 Hadoop Yarn 中是远远无法满足的。
在大数据场景、机器学习、科学计算、特效渲染等高性能计算场景,提供了更多的调度算法支持,例如:
-
Gang-scheduling
-
Fair-share scheduling
-
Queue scheduling
-
Preemption scheduling
-
Topology-based scheduling
-
Reclaims
-
Backfill
-
Resource Reservation
同时得益于 Kubernetes 的设计思想,在可扩展性的架构设计方面,Volcano 支持用户自定义 plugin 和 action 以支持更多调度算法,关于 Volcano 的更新信息可以参考 Volcano 的社区网站
阿里开源的 Koordinator
Koordinator 是一个基于 QoS 的 Kubernetes 混合工作负载调度系统。它旨在提高对延迟敏感的工作负载和批处理作业的运行时效率和可靠性,简化与资源相关的配置调整的复杂性,并增加 Pod 部署密度以提高资源利用率。
Koordinator 简单理解就是为了大数据云原生而生的调度引擎,同时也是阿里内部在整个混部调度场景下所诞生的技术。
摘自阿里公开演讲内容:
作为云原生混部的践行者,阿里巴巴是真刀真枪的在生产环境中推进混部技术理念,并在去年双 11 完成了超过千万核的混部规模,通过混部技术帮助阿里巴巴双 11 节约超过 50% 的大促资源成本,在大促快上快下链路上提速 100%,助力大促实现丝滑的用户体验。
正是在双 11 这样的峰值场景驱动之下,阿里的混部调度技术持续演进,积累了大量的生产实践经验,到今天已经是第三代即云原生全业务混部系统。Koordinator 的架构基于阿里巴巴内部的超大规模生产实践,结合阿里云看到的企业容器客户的真实诉求,在标准化、通用化上做出了更多的突破,实现首个基于标准 Kubernetes 的生产可用的开源混部系统。
Koordinator 核心特性在于:
-
精心设计的优先级和 QoS 机制,可将不同类型的工作负载混跑在集群中,并在单个节点上运行不同类型的 Pod 。
-
允许资源超卖以实现高资源利用率,但仍通过利用应用程序分析机制来满足 QoS 保证。
-
细粒度的资源协调和隔离机制,以提高延迟敏感的工作负载和批处理作业的效率。
-
灵活的作业调度机制,支持特定领域的工作负载,例如大数据、人工智能、音频和视频。
-
一整套用于监控、故障排除和操作的工具
综上所得,Koordinator 是当前对于大数据资源调度和混部场景支持比较好的系统,目前也是作为我们混部系统调度中的核心系统,感兴趣的读者可以去 Koordinator 官网进行查看(附录社区地址:koordinator.sh/zh-Hans/doc…),相关细节因为篇幅原因就不多赘述了,后面在大数据混部实战中会详细的演示 Koordinator 的功能(根据目前线上运行结果,还是符合预期的)
当然也有其他用于混部场景开源的系统,类似腾讯开源的 Caelus,但是 Caelus 自开源之后,社区基本没什么动态(截止本文发布),所以整体来看 Caelus 一方面是没有成熟社区生态,另一方面对于资源调度层面支持的力度都不够,所以就不多介绍了,感兴趣的朋友可以自行 google 查询
四、本文总结
从上面的几个维度拆解之后,我们发现 Kubernetes 并不是一定就比 Hadoop Yarn 的调度能力要好,甚至在兼容性、数据本地存储、权限限制等方面也存在诸多不足,OK,回归到技术架构设计的根本问题就是:适合 OR 不适合?怎么来判断是否适合做云原生化建设?可以建议你从以下几个方面来综合考虑:
- 集群规模是否足够大
集群规模足够大之后,从数据跨区域存储、集群容错性、计算作业跨区域调度、数据存储成本的压力等等,这些都是要考虑的核心要素,在当下企业发展前景不明确的情况下,不可能一昧的扩充资源来承接不断膨胀的数据量,那么这时候你可以考虑做云原生化的升级改造,将数据存储在对象存储中,不用担心多副本、跨区域、容错性问题,成本相比本地存储要至少有 7-10 倍的降低。
其次,是计算层可以做混部云架构,一部分计算作业跑在本地环境(已有的节点资源不能浪费),一部分跑在云端(如果有计算型扩容的话)这种架构对于具备一定规模的集群来说,是效能最大化的一种解决方案。
最后,其实就是上文讲到的参考第三种混部的架构模式,提供一套资源池来提供给不同的业务部门来使用,算力上可以灵活调度,存储侧也不必完全存储在本地磁盘中,可以使用 JuiceFS 或者 Alluxio 来进行缓存加速,这部分在后面云原生存算分离技术中会单独来讲到,如果借助 JuiceFS 或者 Alluxio 来提升计算引擎的性能
- 业务足够新
今年的 AI 热潮,对于整个大数据技术也是有一定的依赖性的,包括数据采集、数据清洗等等都会使用大数据相关技术来实现,并且当下很多大数据组件也都开始支持了 AI 相关的场景,例如:Spark、Flink、Alluxio、JuiceFS 等等,那么这时候很多公司也就会成立相关数据团队,这时候可以选择使用基于云原生 &大数据结合的方式来进行开发, 这里主要解决的是存储压力问题,算力就不是核心问题了,因为 AI 场景下数据规模是超大规模海量级别的,如果用本地存储那可是太耗费资源了。
- 有降本需求的企业 &团队
这个是当下我所接触到的公司里面最核心的需求,就是降本,在上篇离在线混部内容中我们也讲到,混部解决的也是降本问题,云原生调度能力可以先在混部场景下跑通,然后逐步迁移到完全云原生状态,这部分具体可以参考上篇内容,这里就不多赘述了。
我们宗旨:分享创造价值、交流促进成长,欢迎关注:KubeData