大数据分布式作业调度系统的一般架构是由 master 将任务分发到一批 worker 上执行
大数据作业有很多种不同的任务类型:
- Shell
- Jar
- Hive/Spark sql
- Python
- 抽取、导出
按运行方式又可分为两大类:
- 在 worker 本地运行的,比如一个 shell 脚本,或者一个算法类的 python 脚本
- 由 worker 提交到资源调度系统 yarn 上运行的任务,比如 spark submit, hive sql 等
每个在 worker 上运行的任务都会消耗一些本地资源,worker 的配置将决定同时可以调度到多少任务上去运行。
对于以上所指的第二类任务,由于任务真正运行的地方是在 Yarn 集群上,所以需要 worker 的资源较少,而对于第一类任务,特别是 python 类的任务,需要消耗较多 CPU 和内存,由于缺乏隔离机制,会导致 worker 的不稳定,从而影响其它任务的运行。
那么如何解决这个问题呢,首先想到的办法是能否让调度系统支持资源隔离机制,即每个任务将被隔离在一个单独的容器中,限制其资源的使用,进而我们会想到 docker 和 Kubernetes,其实已经有这类调度系统出现,叫 Argo, 这种调度系统完全是基于 Kubernetes 开发的云原生作业调度系统,使用 CRD 来封装各种作业类型,任务最终都会以容器化的形式运行在 Kubernetes 上。
本文提供在一个非云原生调度系统上无缝支持容器化的方式。
这种方式就是图中的 k8s_exec, 它是一个使用 kubernetes/python sdk 开发的脚本命令,可以将一个任务脚本包装成一个 on k8s 的任务,提交到 k8s 集群上运行,将管理任务的生命周期。通过这种方式,可以对现在系统较少的倾入方式,实现任务的容器化和资源隔离,更进一步的,特别地,作者将这种方式用在了 Spark on Kubernetes 上,使用调度系统上的 Spark SQL 任务运行在 Kubernetes 上。
k8s_exec 的工作原理如图,详情请查看 github