大数据 | 《Riffle:Optimized Shuffle Service for Large-Scale》论文阅读

news2024/11/26 16:24:01

1. 简介

1.1. 近期工作

  1. 研究工作鼓励运行大量小任务
    小任务能提高并行性,减少端到端耗时
  2. 工程经验反对运行过多的任务
    过多的task在shuffle阶段会引入大量IO开销,根本原因在于map和reduce阶段之间的shuffle IO请求数量随着任务数量的增长呈现指数级的增长,每个request的平均大小在线性下降;又因为shuffle期间的数据需要保存在HDD磁盘上(为了容错),因此在shuffle期间存在大量小的随机IO导致耗时变长。执行task数量多的job时会拆分IO请求,进一步加剧问题。

1.2. Riffle解决方案

显著提高IO效率,扩展到pb级别数据处理,Riffle通过大量随机小IO转换为更少的连续的大IO提高shuffle性能和资源效率;核心是由一个集中的调度程序 scheduler 和一个shuffle merge service组成,前者跟踪中间shuffle文件并动态协调合并操作,后者运行在每个物理集群节点上,以很少的资源开销将小文件合并为大文件

1.3. 挑战和解决方案

  1. Riffle节省计算和存储资源
  2. 易于配置,适用不同的存储系统和硬件设备
  3. 容错性强:Riffle跟踪合并和未合并格式的中间文件,一旦出现故障,返回未合并格式的文件(放弃本次合并操作)
  4. 开销小

2. 背景和动机

2.1. shuffle简介

宽依赖:子task会接受来自多个父task的输出
窄依赖:只依赖于一个父task

shuffle是资源密集型操作,从map任务传输到reduce任务的每个数据块都是需要经过数据序列化、磁盘和网络IO以及数据反序列化。

2.2. 中间数据的高效存储

  1. 磁盘溢写IO
  2. shuffle IO

2.3. 当前实践与现有解决方案(现有服务的缺陷)

  1. 减少每个stage的task数量

  2. 为reducer聚合服务器

3. 系统概述

在这里插入图片描述

3.1 Shuffle Merge scheduler

spark框架中的task由driver分配,driver将一个job转换成DAG有向无环图,被shuffle分割成几个stage;来自同一个stage的task可以并行执行,而下一个stage的task需要在shuffle完成后才能执行,中间的shuffle文件需要持久化在本地或HDFS(GFS)等

Riffle跟踪任务执行进度,根据配置策略调度合并操作。Riffle手机所有task生成的中间文件状态和块大小,并在shuffle文件满足合并标准时发出和并请求。

3.2 Shuffle service with merging

在这里插入图片描述

大数据计算框架会提供外部shuffle服务管理shuffle输出文件(例如Spark中的ESS)

上图展示了Riffle对于文件合并的优化:每个mapper输出数据以便将数据分配到所需的reducer中,原有请求下每个reducer都需要到每个mapper处请求数据,通过Riffle合并后,reducer秩序从合并后的中间文件中读取数据即可。显著提高shuffle IO的效率

4. 系统设计

4.1. 合并shuffle中间文件

当map操作和merge完成后,driver会启动reducer任务,将全部map输出的元数据(位置,执行器id,task id)广播给executors节点。通过Riffle,driver可以发送已合并文件的metadata,而不是原始的map输出文件,因此reducer可以更高效的从合并后的文件中提取相应的部分。

4.1.1. 合并调度策略

  1. Merge with fixed number of files. 见下图a
  2. Merge with fixed block size. 见下图b
  3. 配置合并策略
    在这里插入图片描述

4.1.2. 高效Worker-Side合并(重点 参照原文)

在这里插入图片描述

4.2. Best-Effort合并(最小化合并开销)

导致部分任务超时的原因:

  1. 最后几个mapper生成的shuffle需要等待mapper任务完成后在开始合并
  2. worker节点crush重启

best-effort merge实现思想:
driver会将mapper阶段标记为已完成,在worker完成大多数merge操作时就开始启动reducer,剩余未完成的merge操作都由driver取消,直接进入reduce阶段。

Riffle的driver对于合并成功的文件直接发送已合并文件的metadata,对于合并失败的文件发送源文件的metadata。

4.3. 异常处理

为保证计算结果的正确性并加快发生异常时的恢复速度,Riffle将原始的未合并文件、合并后的文件都保存在磁盘上。若出现上述异常,Riffle会返回到原始未合并的文件,从而避免map阶段的延迟。

Spark和Hadoop在处理shuffle数据丢失和损坏时,只会重新计算丢失部分的mapper任务。Riffle遵循这种设计,若未合并的文件丢失,只计算这部分对应的mapper任务,若合并后的文件丢失则进行降级。

*sailfish对于数据丢失会导致大量任务的重计算,相对Riffle造成更高的耗时

4.4. 分布式系统中的负载均衡

“power of two choices”可以有效平衡动态合并负载,driver随机挑选两个merger,选择其中pending数量更少的一个。既可以减少探测开销,又可以平衡负载。
在这里插入图片描述

4.5 讨论

4.5.1. IO操作节省分析

原生的shuffleIO request数量:MR
对于N路合并,生成M/N个合并文件,最终的shuffle request数量为M/N
R;
对于合并操作可能会引起额外的IO,完整的合并需要对全部数据(T)增加一次读写操作,由于Riffle合并只产生连续的磁盘IO,因此总IO请求数为2* T/s,其中s为缓冲区大小。

总IO请求数为 M/N * R + 2 * T/s

举个栗子,总数据量为100G其中使用了1000个mappper,1000个reducer,则shuffle期间的IO请求为10001000,若使用Riffle合并,配置10MB的缓冲区,使用40路合并,IO请求的总数为: 1000/401000 + 2*100GB/10MB = 45000,请求量减少了22倍。

上述计算没有考虑磁盘溢出的影响,Riffle的高效merge缓解了shuffle IO的二次增长,进一步降低了由于磁盘的溢出导致对磁盘IOPS的要求;

*与sailfish对比IO相同,但容错性更强,更适合大规模集群的部署。

4.5.2. 部署在不同集群上

每台物理机上有多个executor时,Riffle最适合;
Riffle更适合存算分离的行业趋势;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/177825.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

emoji 符号大全,给各位程序员增加一些奇怪的知识点

这篇博客非常有意思,我将为大家整理和罗列一些好用的 emoji 表情站点。 文章目录EmojiXDcarpedm20emoji-cheat-sheetemojiterrafsymbols符号大全unicode.orgemojiallemojiguideemojipediaemoji696 编辑器emoji.inkEmoji Artemojifinderemoji 可以在许多社交媒体平台…

Redis 持久化-AOF

Redis 持久化-AOF 1.官方资料 在线文档 : https://redis.io/topics/persistence 2.AOF 是什么? 1、AOF(Append Only File) 2、以日志的形式来记录每个写操作(增量保存),将 Redis 执行过的所有写指令记录下来(比 如 set/del 操作会记录, 读操作 get 不记录) 3、…

【大数据趋势】1月24日 美元关键位置上,应该不会一次破,纳指有概率反弹,人民币结汇行情结束在即。

确定市场形态 - 美元指数 关键位置大概率不会一次就破,有较强反弹 作为长期的关键位置101-103这个区域,没有可能一次性涨破,或者一次性跌破,所以大概率有一次反弹出现。作为趋势线(红色)来看&#xff0c…

十大经典排序算法(动态演示+代码)-冒泡算法

时间、空间复杂度比较 排序算法平均时间复杂度最差时间复杂度空间复杂度数据对象稳定性冒泡排序O(n2)O(n2)O(1)稳定选择排序O(n2)O(n2)O(1)数组不稳定、链表稳定插入排序O(n2)O(n2)O(1)稳定快速排序O(n*log2n)O(n2)O(log2n)不稳定堆排序O(n*log2n)O(n*log2n)O(1)不稳定归并排序…

万能四码(0126版本)之分析

万能四码(0126版本)之分析一、万能四码的重新排列原版是这样的:0126,0134,0159,0178,0239,0247,0258,0357,0368,0456,0489…

【进阶C语言】程序环境与预处理

文章目录一.程序环境1.翻译环境编译器1.预处理2.编译3.汇编链接器2.运行环境总图解二.预处理1.预定义符号2.define1.define的定义2.替换规则3.定义的建议和使用的缺点1.加括号2.避免使用带有副作用的符号3.命名约定4.#和##1.#2.##5.宏和函数的对比6.undef3.条件编译1.常量表达式…

趣味三角——第3章——6个三角函数的成熟过程

目录 3.1 6个三角函数的演化进程简述 3.2 Johann Muller(别名Regiomontanus)的贡献 第3章 6个三角函数的成熟过程 It is quite difficult to describe with certainty the beginning of trigonometry . . . . In general, one may say that the emphasis was placed first …

ThinkPHP5 Request类method任意方法调用RCE

ThinkPHP v5.0.x 影响版本&#xff1a;5.0.0 < version < 5.0.23 漏洞点&#xff1a;\think\Request::method 修复&#xff1a;版本更新 top-think/framework4a4b5e6 改进Request类 环境 thinkphp5.0.23核心版&#xff08;需开启debug&#xff09;thinkphp5.0.22完…

设计模式 - 六大设计原则之LoD(迪米特法则原则)

文章目录概述Case学生类老师类Bad ImplBetter Impl老师类改造调用方&#xff1a;校长类改造概述 迪米特法&#xff08;Law Of Demeter &#xff0c; LoD&#xff09;则又叫最少知道原则&#xff08;Least Knowledge Principle&#xff09;&#xff0c;最早是在1987年由美国Nor…

【游戏客户端】如何实现环形进度条

【游戏客户端】如何实现环形进度条 Hello大家好&#xff0c;我是Lampard。好久没写博客了&#xff0c;之前在忙着制作项目的一个大的副本&#xff0c;趁着过年得闲&#xff0c;和大家分享一下制作过程中遇到的一些有趣的问题。今天主要是分享如何在cocos制作一个环形的进度条 (…

重写 equals 时为什么一定要重写 hashCode

equals 方法和 hashCode 方法是 Object 类中的两个基础方法&#xff0c;它们共同协作来判断两个对象是否相等。为什么要这样设计嘞&#xff1f;原因就出在“性能” 2 字上。 使用过 HashMap 我们就知道&#xff0c;通过 hash 计算之后&#xff0c;我们就可以直接定位出某个值存…

移动web 空间转换 3D

移动web 空间转换 3D空间转换 3D3D位移透视3D旋rotateXrotateY左手法则立体呈现空间转换 3D 3D坐标系 3D 坐标系比2D 多了一个Z轴。 一定要记住3个坐标轴取值的正反&#xff1a; X 轴 往右越大&#xff0c;是正值&#xff0c; 否则反之Y 轴 往下越大&#xff0c;是正值&…

React错误边界

首先 我们先构建出问题的场景 我们创建一个react项目 然后在src下创建 components 文件夹目录 在下面创建一个 error.jsx 组件 参开代码如下 import React from "react";export default class App extends React.Component{constructor(props){super(props);this.…

CUDA编程笔记(5)

文章目录前言CUDA的内存组织全局内存常量内存纹理内存和表面内存寄存器局部内存共享内存L1和L2缓存SM的构成API函数查询设备总结前言 cuda的内存组织&#xff0c;在使用GPU时尽可能提高性能&#xff0c;合理的使用设备的内存也是十分重要的。 CUDA的内存组织 如表所示&#…

Docker基本操作

Docker基本操作一、镜像操作1.镜像名称2.镜像命令&#xff08;1&#xff09;拉取、查看镜像&#xff08;2&#xff09;保存、导入镜像二、容器操作1.容器相关命令2.创建并运行一个容器3.进入容器&#xff0c;修改文件4.小结三、数据卷&#xff08;容器数据管理&#xff09;1.什…

Java:枚举类型

Java&#xff1a;枚举类型 每博一文案 师父说&#xff1a;人活一世&#xff0c;每个人都有他的特别&#xff0c;每个人都值得被温柔相待。红尘一遭&#xff0c;每段经历都有它的必然&#xff0c; 每段经历都造就了现在的你&#xff0c;最快乐的事情&#xff0c;就是做自己&…

Java多线程案例之定时器

一. 定时器概述 1. 什么是定时器 定时器是一种实际开发中非常常用的组件, 类似于一个 “闹钟”, 达到一个设定的时间之后, 就执行某个指定好的代码. 比如网络通信中, 如果对方 500ms 内没有返回数据, 则断开连接尝试重连.比如一个 Map, 希望里面的某个 key 在 3s 之后过期(自…

排序算法: 数据的离散化(排序+去重 C++例题实现)

文章目录数据的离散化例题&#xff1a;电影完整代码数据的离散化 离散化是指将一个无穷大的集合中的若干个元素映射到一个有限的集合中&#xff0c;以便于对那个无穷大的集合进行操作。 在很多情况下&#xff1a;对于一个规定在Z范围内的整数范围&#xff0c;他有可能包含非常…

maven创建自定义web工程模板

一&#xff0c;先搭建好一个项目模板。 注意每个文件夹下都放一个文件占位&#xff0c;否则创建模板时会认为是空目录不进行创建。 注意项目文件夹名字 和 pom.xml 中<artifactId 和 <name 的名字都使用相同的名字&#xff0c;写一个好记的名字&#xff0c;因为后面生…

QT UI布局设置整理-边框设置

一、设置边距的方法 1、设置容器内部的内容控件的边距 //设置容器leftBar&#xff08;QWidget&#xff09;内部marginui->leftBar->setContentsMargins(10,10,0,0); 2、 设置内部控件之间的间距 //editWidget是一个QWidget ui->editWidget->layout()->setSpac…