喜大普奔:Spark on kubernetes

标签: spark tech | 发表时间:2017-08-31 00:11 | 作者:
分享到:
出处:http://ieevee.com/

1 Spark on Kubernetes

两个星期前(08/15/2017),spark社区提了一个新的SPIP(Spark Project Improvement Proposals): Spark on Kubernetes: Kubernetes as A Native Cluster Manager,即用k8s管理spark集群。经过社区2个星期的投票,看上去很快要能合入了。

喜大普奔啊!

我场的spark为了支持多租户也是跑在k8s上的,但其实是一个太监的方案:在k8s上跑的只是spark driver,而spark excutor是跑在yarn上的。但这个方案有2个局限:

  1. 由于yarn会将driver的listen socket信息带给excutor,让excutor反过来访问该listen socket,所以k8s集群和yarn集群必须跑在同一套服务器上,否则yarn上的container将无法访问k8s集群内部的容器。
  2. 由于k8s和yarn在同一套服务器上,即存在2个集群管理者,因此也必然存在资源竞争:究竟k8s是大房,还是yarn做小妾?在我们的集群上就出现过,yarn上跑的excutor负载过重,导致k8s上的容器出现故障的现象。当然可以在k8s和yarn之外再加一个管理者(齐人有一妻一妾),由它来统筹k8s和yarn,但终究是复杂了一点。

该SPIP合入Spark后,Spark将支持k8s作为集群管理器,可以解决上述问题:集群只有1个管理者,Spark与其他跑在k8s上的app并无二致,都是普通app而已,都要接受k8s的管理。

2 Goals

  • Make Kubernetes a first-class cluster manager for Spark, alongside Spark Standalone, Yarn, and Mesos.
  • Support both client and cluster deployment mode.
  • Support dynamic resource allocation.
  • Support Spark Java/Scala, PySpark, and Spark R applications.
  • Support secure HDFS access.
  • Allow running applications of different Spark versions in the same cluster through the ability to specify the driver and executor Docker images on a per-application basis.
  • Support specification and enforcement of limits on both CPU cores and memory.

基本上能够替换yarn了,而且能得到若干额外的好处,例如多版本Spark同时运行。特别是支持secure HDFS,好评。

3 设计思路

Spark的driver和excutor都运行在Pod中。driver会调用k8s的api来创建和销毁Excutor pod,而k8s则负责将Pod调度到合适的Node上执行。

3.1 cluster & client

spark on k8s支持cluster和client两种模式。

  • 在cluster模式下,driver运行在pod中,spark-submit脚本会启动一个k8s client,该client负责调用k8s api。由于driver也运行在pod中,所以集群中的excutor容器可以直接访问。
  • 在客户端模式下,driver在集群外部运行,并调用Kubernetes API来创建和销毁执行器Pods。driver必须可以从集群中路由,以便excutor容器与之进行通信。

driver中运行的主要组件是KubernetesClusterSchedulerBackend ,它是CoarseGrainedSchedulerBackend的一个实现,它通过调用方法doRequestTotalExecutors 和doKillExecutors 分别管理通过Kubernetes API分配和销毁执行程序。

3.2 反压

在KubernetesClusterSchedulerBackend内,单独的kubernetes-pod-allocator线程通过适当的调节和监视来处理新的Excutor Pods的创建。该线程会根据先前的excutor Pod创建请求是否已完成,决定是否k8s提交新的请求。

这种反压是必要的,因为Kubernetes API server乐观地接受对新Pods的请求,期望能够最终安排它们运行。

然而,k8s集群内有大量暂时无资源调度的Pods并不是个好事情。反压机制使我们能够控制应用程序扩展速度(可配置),并有助于防止Spark应用程序使用太多Pod创建请求,对Kubernetes API server造成DOS攻击

3.3 依赖文件存储

spark on k8s有辅助和可选组件:ResourceStagingServer 和KubernetesExternalShuffleService ,它们具体描述如下。

ResourceStagingServer 用作文件存储(如果没有Kubernetes持久化存储)。client会将application依赖上传到ResourceStagingServer,而driver和excutor pod中的 init-containers 会从ResourceStagingServer下载依赖。

ResourceStagingServer是一个JAX-RS的jetty server,分别具有用于上传和下载文件的两个端点。上传响应中返回安全令牌,并且必须在下载文件的请求中携带该令牌。

该ResourceStagingServer 部署为Kubernetes的service+deployment,并且可以在同一集群中部署多个实例。Spark应用程序通过配置属性指定要使用哪个ResourceStagingServer 实例。

3.4 动态资源分配

KubernetesExternalShuffleService 用于支持动态资源分配:Spark应用程序的Excutor的数量可以在运行时根据资源需求动态改变。

它为驱动程序提供了一个额外的端点,允许shuffle service删除driver程序,终止并清理与相应application相关联的随机文件。

有两种部署KubernetesExternalShuffleService的方法:或者使用DaemonSet在每个节点(或者一部分节点)中运行shuffle service,或者在每个执行器Pods中运行shuffle service。

在第一个选项中,每个 shuffle service 容器都装载一个hostPath卷。每个Excutor容器也安装相同的hostPath卷,该容器也必须将环境变量SPARK_LOCAL_DIRS 指向hostPath。

在第二个选项中, shuffle service 与每个Excutor Pod中的Excutor容器位于同一位置。两个容器共享一个emptyDir卷,用以写入shuffle数据。在集群中部署的 shuffle service 可能有多个,可能用于不同版本的Spark,或者用于资源配额不同的优先级别。

3.5 k8s配置项

Spark on k8s还引入了新的Kubernetes配置选项,以便于指定driver和excutor Pods的Kubernetes资源。例如,driver和excutor Pods可以在特定的Kubernetes命名空间中以及集群中特定的一组节点上创建。允许用户将label和注释应用于driver和excutor Pods。

下面例子里我指定了 spark.kubernetes.driver.limit.coresspark.kubernetes.executor.limit.cores

另外,HDFS的安全性正在积极地进行设计。利用内置的Kubernetes Secrets,可以支持短期运行作业和长期运行作业。

4 跑下试试

试试就试试。

要运行Spark on k8s,需要先满足如下条件。

  • k8s集群。a piece of cake
  • 具备创建pods, configmaps, secrets的权限。a piece of cake
  • 支持k8s的spark distribution。可以从 这里下载,也可以自己编译。当然你要是下载不了(aws s3你懂的),可以给我mail,一块钱一份。
  • 相关spark on k8s镜像:spark-driver/spark-excutor/spark-init
Component Image
Spark Driver Image kubespark/spark-driver:v2.2.0-kubernetes-0.3.0
Spark Executor Image kubespark/spark-executor:v2.2.0-kubernetes-0.3.0
Spark Initialization Image kubespark/spark-init:v2.2.0-kubernetes-0.3.0

向k8s提交一个Pi作业。 --master指定了k8s的api server,可以通过kubectl clusterinfo查看Kubernetes master。jar文件是在容器里的,路径不要改。不过官方文档里写的是spark_examples_2.11-2.2.0.jar,这个名字是错的,按下面的命令即可。

   bin/spark-submit \
  --deploy-mode cluster \
  --class org.apache.spark.examples.SparkPi  \
  --master k8s://http://127.0.0.1:8080  \
  --kubernetes-namespace default    \
  --conf spark.executor.instances=3    \
  --conf spark.app.name=spark-pi    \
  --conf spark.kubernetes.driver.limit.cores=1   \
  --conf spark.kubernetes.executor.limit.cores=1  \
  --conf spark.kubernetes.driver.docker.image=kubespark/spark-driver:v2.2.0-kubernetes-0.3.0  \
  --conf spark.kubernetes.executor.docker.image=kubespark/spark-executor:v2.2.0-kubernetes-0.3.0  \
  --conf spark.kubernetes.initcontainer.docker.image=kubespark/spark-init:v2.2.0-kubernetes-0.3.0  \
  local:///opt/spark/examples/jars/spark-examples_2.11-2.2.0-k8s-0.3.0.jar

不过这种离线作业,在执行完了以后只是删除了Excutor Pod,但并没有删除driver Pod,仍然还在running,并不友好。如果确实想设计为干完不走,driver pod可以用Job类型,但这个行为跟Yarn又不一致了(Spark on Yarn执行完了所有进程都退出),所以还是删除的好,只是这执行日志,哎呀,还是得找个好地方存起来呀。


相关 [spark kubernetes] 推荐:

喜大普奔:Spark on kubernetes

- - Zlatan Eevee
两个星期前(08/15/2017),spark社区提了一个新的SPIP(Spark Project Improvement Proposals): Spark on Kubernetes: Kubernetes as A Native Cluster Manager,即用k8s管理spark集群. 经过社区2个星期的投票,看上去很快要能合入了.

Spark概览

- - 简单文本
Spark具有先进的DAG执行引擎,支持cyclic data flow和内存计算. 因此,它的运行速度,在内存中是Hadoop MapReduce的100倍,在磁盘中是10倍. 这样的性能指标,真的让人心动啊. Spark的API更为简单,提供了80个High Level的操作,可以很好地支持并行应用.

Spark与Mapreduce?

- - 崔永键的博客
我本人是类似Hive平台的系统工程师,我对MapReduce的熟悉程度是一般,它是我的底层框架. 我隔壁组在实验Spark,想将一部分计算迁移到Spark上. 年初的时候,看Spark的评价,几乎一致表示,Spark是小数据集上处理复杂迭代的交互系统,并不擅长大数据集,也没有稳定性. 但是最近的风评已经变化,尤其是14年10月他们完成了Peta sort的实验,这标志着Spark越来越接近替代Hadoop MapReduce了.

Spark迷思

- - ITeye博客
目前在媒体上有很大的关于Apache Spark框架的声音,渐渐的它成为了大数据领域的下一个大的东西. 证明这件事的最简单的方式就是看google的趋势图:. 上图展示的过去两年Hadoop和Spark的趋势. Spark在终端用户之间变得越来越受欢迎,而且这些用户经常在网上找Spark相关资料. 这给了Spark起了很大的宣传作用;同时围绕着它的也有误区和思维错误,而且很多人还把这些误区作为银弹,认为它可以解决他们的问题并提供比Hadoop好100倍的性能.

Spark 优化

- - CSDN博客推荐文章
提到Spark与Hadoop的区别,基本最常说的就是Spark采用基于内存的计算方式,尽管这种方式对数据处理的效率很高,但也会往往引发各种各样的问题,Spark中常见的OOM等等. 效率高的特点,注定了Spark对性能的严苛要求,那Spark不同程序的性能会碰到不同的资源瓶颈,比如:CPU,带宽、内存.

一篇文章带你了解Kubernetes安装

- - Tony Bai
由于之前在阿里云上部署的 Docker 1.12.2的Swarm集群没能正常展示出其所宣称的Routing mesh和VIP等功能,为了满足项目需要,我们只能转向另外一种容器集群管理和服务编排工具 Kubernetes. 注:之前Docker1.12集群的Routing mesh和VIP功能失效的问题,经过在github上.

Kubernetes中的服务发现与负载均衡

- - Feisky's Blog
Kubernetes在设计之初就充分考虑了针对容器的服务发现与负载均衡机制,提供了Service资源,并通过kube-proxy配合cloud provider来适应不同的应用场景. 随着kubernetes用户的激增,用户场景的不断丰富,又产生了一些新的负载均衡机制. 目前,kubernetes中的负载均衡大致可以分为以下几种机制,每种机制都有其特定的应用场景:.

beeline 连接SPARK /Hive

- - 开源软件 - ITeye博客
hiveclient所在主机的jdk 1.7_51,hive 0.12和hadoop 2.3.0是从服务器端拷贝过来的,环境变量一切OK. 执行连接报了Invalid URL的错误:. 开始的一段时间都在纠结这个jdbc的URL格式问题,后来在cloudra论坛上找到了一个方法,. 直接调用的jdbc:hive2的驱动测试是正常的,证明CLASSPATH等环境变量没有问题.

Spark容错机制

- - zzm
一般来说,分布式数据集的容错性有两种方式: 数据检查点和记录数据的更新. 面向大规模数据分析,数据检查点操作成本很高,需要通过数据中心的网络连接在机器之间复制庞大的数据集,而网络带宽往往比内存带宽低得多,同时还需要消耗更多的存储资源. 因此,Spark选择记录更新的方式. 但是,如果更新粒度太细太多,那么记录更新成本也不低.

Mesos上部署spark

- - 开源小站
还是回到之前一直持续的 Mesos话题. 在之前的环节里,我们已经尝试了Mesos的安装,Marathon守护服务以及相对比较主流的Mesos作为Hadoop的资源管理器的实际操作. 这次就说说同属于伯克利出品的Spark. 其实spark最初0.7以前的版本还没有自己的资源管理系统,资源的调度都是通过Mesos来执行的.