【摘要】 external-shuffle-service是Spark里面一个重要的特性,有了它后,executor可以在不同的stage阶段动态改变数量,大大提升集群资源利用率。但是这个特性当前在k8s上并不能很好的运行。让我们来看看,在k8s上要实现这个external-shuffle-service特性的最新进展吧。

如果你想在kubernetes集群中运行Spark任务,那么你可能会对:如何在k8s上运行external-shuffle-service感兴趣。把Driver和Executor都当做容器,丢到k8s上(k8s集群则把他们当做一般的容器,和其他业务类app一样对待),这种模式,可以使得集群资源池归一,避免Spark一个资源池,业务类(K8S)集群一个资源池。提升整体资源利用率,统一维护也降低运维成本。这也是Spark官方在2.3版本后为什么要支持Spark-on-k8s的主要驱动力。

1      external-shuffle-service作用

如果想要executor数量可以动态变化,就需要依赖external-shuffle-service功能(注意这句话,因为在k8s集群中,容器启动关闭很方便。所以非常希望executor数量可以动态调整,提升资源利用率)。

原因是在shuffle过程中,一个executor会到另一个executor那里取数据。如果一个executor节点挂掉了,那么它也就无法处理其他executor发过来的 shuffle 的数据读取请求了,它之前生成的数据都没有意义了。为了解决“取shuffle数据”,和“目标executor是否运行”分开。Spark引入了external-shuffle-service服务。相当于先把shuffle数据暂存到external-shuffle-service那里,然后大家去external-shuffle-service那里取就行了(有点像个中介)。

好文参考:https://zhmin.github.io/2019/08/05/spark-external-shuffle-service/

2      原来怎么部署

在原Spark框架中,external-shuffle-service是部署在每个节点上的。

(1)executor 告诉 external-shuffle-service 数据存放在哪里,然后(2) external-shuffle-service 记下来,供别人查询。所以问题的关键是,数据放“哪里”支持哪些格式呢。我们看(1)里面通知是结构是长这样:

public class RegisterExecutor extends BlockTransferMessage {
public final String appId; // spark application id
public final String execId; // executor id
public final ExecutorShuffleInfo executorInfo; // 《==文件路径
}

可以看出来,关键在 “在哪里” 要看(2)长什么样:

public class ExecutorShuffleInfo implements Encodable {

     public final String[] localDirs;         // 《== 第一级目录列表
public final int subDirsPerLocalDir; // 第二级目录列表
public final String shuffleManager; // shuffleManager的类型,目前只有一种类型 SortShuffleManager
}

可以看到,这个shuffle数据 “在哪里” 只能支持HostPath(本地路径)。

问题的关键就来了:executor容器跑在k8s节点上面,external-shuffle-service跑在另一个容器里面。要想共享相同Path文件,那就必须使用节点路径(k8s-hostpath)。要用这个Hostpath 还得拥有节点的所有权,这个对于多用户共享的K8s集群来说,权限不安全,数据未隔离。

3      在k8s上要怎么解决(一)

Spark的external-shuffle-service要怎么在k8s上运行,这是个问题。Spark社区关于这个有个讨论:https://docs.google.com/document/d/1uCkzGGVG17oGC6BJ75TpzLAZNorvrAU3FRd2X-rVHSM/edit#heading=h.btqugnmt2h40

这个文档主要是说:

当前external-shuffle-service的实现有缺点:(1)多个Spark应用共用一个external-shuffle-service,如果external-shuffle-service出问题,多个Spark应用都受影响,即隔离性差。(2)一个节点一个external-shuffle-service,导致不同节点间压力不均衡。同时如果节点挂了,external-shuffle-service也就没了,这个节点上面的所有executor都受影响,可靠性差。(3)在当前较火热的Docker容器环境下,executor写入的shuffle数据(在一个容器内)。不一定就能被external-shuffle-service读取到(在另一个容器内)。因为有些k8s集群中,管理员出于安全考虑,会强制隔离不同用户的容器,禁止任何共享。

所以提出了改进方向:即executor保存shuffle数据时,不限定非得是保存在本地Path中。

具体实现方案可以有多种。

(1)       保存shuffle数据时,通过external-shuffle-service上传的方式。

(2)       external-shuffle-service支持shuffle数据为远端uri地址,而不仅仅是主机路径。

(3)       由Driver来维护所有的shuffle数据信息,取消external-shuffle-service组件。

(4)       将shuffle数据保存到分布式存储中。

(5)       将shuffle数据上传到external-shuffle-service,然后由Driver跟踪文件路径。

总体思路就是:以前external-shuffle-service是本地写,远程读。调整为:远程写,远程读。

4      在k8s上要怎么解决(二)

其实要在k8s上实现executor数量动态调整(dynamic resource allocation),还有另一条小路(即不通过external-shuffle-service的方式)。并且这条路已经实现了,在这个PR里面。https://github.com/apache/spark/pull/24817

Ø  实现原理:

当发现executor里面是shuffle数据没有用了,则可以删除该executor。如果这个executor里面的shuffle数据,还会被其他Jop读取,那么就保持这个executor存活着不被删除。从而实现executor数量可以动态调整。

Ø  缺点:

可以看出来,这种方式其实是一种缓兵之计。(1)删除部分暂时不被使用executor,但是必须保留那些还会被使用的executor。所以动态效果并不是最优的。另外,(2)一个executor也许最近不被使用,被删除了。但是后续其他Stage又有可能去访问那个shuffle数据。结果发现找不到(被动态删除嘛),这个时候又得重新计算,浪费性能。

PR里面的讨论也说了,这个是无法用来完整替代external-shuffle-service的。

5      路标计划

通过上面的分析,基本了解了在k8s上面跑external-shuffle-service的困难和思路。

所以要达到目的的路径为:(1)external-shuffle-service支持远端保存shuffle数据。(2)executor和external-shuffle-service共享云端shuffle数据。(3)executor数量可以动态调整,不影响功能。(4)在k8s上支持了executor数量动态调整(dynamic resource allocation)。

看Spark的规划是在 3.0.0 版本提供完整能力,嗯,让我们期待Spark on K8s越来越溜吧。

https://issues.apache.org/jira/browse/SPARK-24432

作者:tsjsdbd

快速理解spark-on-k8s中的external-shuffle-service的更多相关文章

  1. 降本增效利器!趣头条Spark Remote Shuffle Service最佳实践

    王振华,趣头条大数据总监,趣头条大数据负责人 曹佳清,趣头条大数据离线团队高级研发工程师,曾就职于饿了么大数据INF团队负责存储层和计算层组件研发,目前负责趣头条大数据计算层组件Spark的建设 范振 ...

  2. Spark机器学习 Day2 快速理解机器学习

    Spark机器学习 Day2 快速理解机器学习 有两个问题: 机器学习到底是什么. 大数据机器学习到底是什么. 机器学习到底是什么 人正常思维的过程是根据历史经验得出一定的规律,然后在当前情况下根据这 ...

  3. 理解Spark RDD中的aggregate函数(转)

    针对Spark的RDD,API中有一个aggregate函数,本人理解起来费了很大劲,明白之后,mark一下,供以后参考. 首先,Spark文档中aggregate函数定义如下 def aggrega ...

  4. 快速理解Python中使用百分号占位符的字符串格式化方法中%s和%r的输出内容的区别

    <Python中使用百分号占位符的字符串格式化方法中%s和%r的输出内容有何不同?>老猿介绍了二者的区别,为了快速理解,老猿在此使用另外一种方式补充说明一下: 1.使用%r是调用objec ...

  5. 在 K8S 中快速部署 Redis Cluster & Redisinsight

    Redis Cluster 部署 使用 Bitnami helm chart 在 K8S redis 命名空间中一键部署 Redis cluster . helm repo add bitnami h ...

  6. k8s中几个基本概念的理解,pod,service,deployment,ingress的使用场景

    k8s 总体概览 前言 Pod 副本控制器(Replication Controller,RC) 副本集(Replica Set,RS) 部署(Deployment) 服务(Service) ingr ...

  7. 深入理解k8s中的访问控制(认证、鉴权、审计)流程

    Kubernetes自身并没有用户管理能力,无法像操作Pod一样,通过API的方式创建/删除一个用户实例,也无法在etcd中找到用户对应的存储对象. 在Kubernetes的访问控制流程中,用户模型是 ...

  8. 《深入理解Spark:核心思想与源码分析》(前言及第1章)

    自己牺牲了7个月的周末和下班空闲时间,通过研究Spark源码和原理,总结整理的<深入理解Spark:核心思想与源码分析>一书现在已经正式出版上市,目前亚马逊.京东.当当.天猫等网站均有销售 ...

  9. 《深入理解Spark:核心思想与源码分析》(第2章)

    <深入理解Spark:核心思想与源码分析>一书前言的内容请看链接<深入理解SPARK:核心思想与源码分析>一书正式出版上市 <深入理解Spark:核心思想与源码分析> ...

随机推荐

  1. 【IOS开发学习—OC篇】

    一.instancetype和id关键字的区别 1)instancetype表示方法的返回类型和调用方法的对象类型相同. 2)在Object-C引入instancetype之前,初始化方法的返回类型都 ...

  2. 原生JS实现队结构及利用队列模拟‘击鼓传花’游戏

    1. 前言 队列,是一种遵从先进先出(FIFO,First-In-First-Out)原则的有序集合.队列在尾部添加新元素,并从顶部移除元素,最新添加的元素必须排在队列的末尾. 2.功能说明 enqu ...

  3. 『题解』Coderforces352A Jeff and Digits

    更好的阅读体验 Portal Portal1: Codeforces Portal2: Luogu Description Jeff's got n cards, each card contains ...

  4. web应用安全框架选型:Spring Security与Apache Shiro

    一. SpringSecurity 框架简介 官网:https://projects.spring.io/spring-security/ 源代码: https://github.com/spring ...

  5. Scrapy进阶知识点总结(六)——中间件详解

    概述 查看scrapy官网的框架图,可以看出中间件处于几大主要组件之间,类似于生产流水线上的加工过程,将原料按照不同需求与功能加工成成品 其中4,5处于下载器与引擎之间的就是下载中间件,而spider ...

  6. SpringBoot 源码解析 (五)----- Spring Boot的核心能力 - 自动配置源码解析

    在上一篇博客中分析了springBoot启动流程,大体的轮廓只是冰山一角.今天就来看一下springBoot的亮点功能:自动化装配功能. 先从@SpringBootApplication开始.在启动流 ...

  7. nyoj 24-素数距离问题 (素数算法)

    24-素数距离问题 内存限制:64MB 时间限制:3000ms Special Judge: No accepted:21 submit:71 题目描述: 现在给出你一些数,要求你写出一个程序,输出这 ...

  8. 领扣(LeetCode)两个列表的最小索引总和 个人题解

    假设Andy和Doris想在晚餐时选择一家餐厅,并且他们都有一个表示最喜爱餐厅的列表,每个餐厅的名字用字符串表示. 你需要帮助他们用最少的索引和找出他们共同喜爱的餐厅. 如果答案不止一个,则输出所有答 ...

  9. shell脚本0——”一切皆文件“, 认识Shell

    一.”一切皆文件“与“管道” 1)管道:grep foo /path/to/file | grep -n -k 3 | more 实际过程与我们直观认为的相反,最好通过实际过程理解.首先运行的是mor ...

  10. 区块链共识机制之工作量证明(POW)

    像比特币.以太坊.NXT.Bitshares等这些区块链系统,其本质上是一种加密经济组织,它建立在点对点网络上,是去中心化.无管辖的,由密码学.经济学和社会共识来共同维护.这些加密网络因各种原因有着多 ...