Spark 的shuffle 服务是spark的核心,本文介绍了非ExternalShuffleClient的方式,看BlockService的整个架构。ShuffleClient是整个框架的基础,有init方法和fetchBlock两个方法。

/** Provides an interface for reading shuffle files, either from an Executor or external service. */
public abstract class ShuffleClient implements Closeable { /**
* Initializes the ShuffleClient, specifying this Executor's appId.
* Must be called before any other method on the ShuffleClient.
* 初始化ShuffleClient, 传入本执行器的程序ID,本方法必须在访问ShuffleClient的其它方法前调用。
*/
public void init(String appId) { } /**
* Fetch a sequence of blocks from a remote node asynchronously,
*
* Note that this API takes a sequence so the implementation can batch requests, and does not
* return a future so the underlying implementation can invoke onBlockFetchSuccess as soon as
* the data of a block is fetched, rather than waiting for all blocks to be fetched.
* 异步的从远程结点取一系列的数据块,并且不返回future对象,所以当取到一个数据块的数据时,底层的实现可以调用onBlockFetchSuccess方法,
* 并不用等所有的数据块都取完。
*/
public abstract void fetchBlocks(
String host,
int port,
String execId,
String[] blockIds,
BlockFetchingListener listener);
}

BlockFetchingListener接口,onBlockFetchSuccess方法:每次成功取得一个数据块时调用。当本方法返回时,数据必须被自动释放。 如果数据被传递给另一个线程,接收者必须自己调用retain()和release(),或者拷贝数据到一个新的缓冲区。onBlockFetchFailure方法,数据块获取失败时,至少被调用一次。

public interface BlockFetchingListener extends EventListener {
/**
* Called once per successfully fetched block. After this call returns, data will be released
* automatically. If the data will be passed to another thread, the receiver should retain()
* and release() the buffer on their own, or copy the data to a new buffer.
*/
void onBlockFetchSuccess(String blockId, ManagedBuffer data); /**
* Called at least once per block upon failures.
*/
void onBlockFetchFailure(String blockId, Throwable exception);
}

BlockTransferService扩展了ShuffleClient,有一些方法的公共的实现。

private[spark]
abstract class BlockTransferService extends ShuffleClient with Closeable with Logging { /**
* Initialize the transfer service by giving it the BlockDataManager that can be used to fetch
* local blocks or put local blocks.
* 通过传递给他BlockDataManager对象来初始化传输服务,BlockDataManager可以用来存取本地数据块。
*/
def init(blockDataManager: BlockDataManager): Unit /**
* Tear down the transfer service.
* 关闭传输服务。
*/
def close(): Unit /**
* Port number the service is listening on, available only after [[init]] is invoked.
* 传输服务所在的端口号,在调用init方法后可用。
*/
def port: Int /**
* Host name the service is listening on, available only after [[init]] is invoked.
* 传输服务所在的主机名,在调用init方法后可用。
*/
def hostName: String /**
* Fetch a sequence of blocks from a remote node asynchronously,
* available only after [[init]] is invoked.
*
* Note that this API takes a sequence so the implementation can batch requests, and does not
* return a future so the underlying implementation can invoke onBlockFetchSuccess as soon as
* the data of a block is fetched, rather than waiting for all blocks to be fetched.
*
* 异步的从远程结点取一系列的数据块,,仅在调用init方法后可用。
* 注意本API用一个序列,所以实现可以使用批量请求,并且不返回future对象,所以当取到一个数据块的数据时,底层的实现可以调用onBlockFetchSuccess方法,
* 并不用等所有的数据块都取完。
*/ override def fetchBlocks( host: String, port: Int, execId: String, blockIds: Array[String], listener: BlockFetchingListener): Unit /**
  * Upload a single block to a remote node, available only after [[init]] is invoked.
* 上传一个数据块到远程结点,仅在调用init方法后可用。
*/
def uploadBlock(
hostname: String,
port: Int,
execId: String,
blockId: BlockId,
blockData: ManagedBuffer,
level: StorageLevel,
classTag: ClassTag[_]): Future[Unit] /**
* A special case of [[fetchBlocks]], as it fetches only one block and is blocking.
*
* It is also only available after [[init]] is invoked.
* fetchBlocks的一个特别方法,他只取一个数据块并且阻塞,仅在调用init方法后可用。

*/
def fetchBlockSync(host: String, port: Int, execId: String, blockId: String): ManagedBuffer = {
// A monitor for the thread to wait on.
val result = Promise[ManagedBuffer]()
fetchBlocks(host, port, execId, Array(blockId),
new BlockFetchingListener {
override def onBlockFetchFailure(blockId: String, exception: Throwable): Unit = {
result.failure(exception)
}
override def onBlockFetchSuccess(blockId: String, data: ManagedBuffer): Unit = {
val ret = ByteBuffer.allocate(data.size.toInt)
ret.put(data.nioByteBuffer())
ret.flip()
result.success(new NioManagedBuffer(ret))
}
})
ThreadUtils.awaitResult(result.future, Duration.Inf)
} /**
* Upload a single block to a remote node, available only after [[init]] is invoked.
*
* This method is similar to [[uploadBlock]], except this one blocks the thread
* until the upload finishes.
* 上传一个数据块到远程结点,仅在调用init方法后可用。
* 这个方法和uploadBlock方法类似,除了直到上传结点,本方法会一直阻塞。
*/
def uploadBlockSync(
hostname: String,
port: Int,
execId: String,
blockId: BlockId,
blockData: ManagedBuffer,
level: StorageLevel,
classTag: ClassTag[_]): Unit = {
val future = uploadBlock(hostname, port, execId, blockId, blockData, level, classTag)
ThreadUtils.awaitResult(future, Duration.Inf)
}
}

NettyBlockTransferService扩展了BlockTransferServie

Spark2.0 shuffle service的更多相关文章

  1. hadoop-2.7.3.tar.gz + spark-2.0.2-bin-hadoop2.7.tgz + zeppelin-0.6.2-incubating-bin-all.tgz(master、slave1和slave2)(博主推荐)(图文详解)

    不多说,直接上干货! 我这里,采取的是ubuntu 16.04系统,当然大家也可以在CentOS6.5里,这些都是小事 CentOS 6.5的安装详解 hadoop-2.6.0.tar.gz + sp ...

  2. Ubuntu14.04或16.04下安装JDK1.8+Scala+Hadoop2.7.3+Spark2.0.2

    为了将Hadoop和Spark的安装简单化,今日写下此帖. 首先,要看手头有多少机器,要安装伪分布式的Hadoop+Spark还是完全分布式的,这里分别记录. 1. 伪分布式安装 伪分布式的Hadoo ...

  3. 图文解析Spark2.0核心技术(转载)

    导语 Spark2.0于2016-07-27正式发布,伴随着更简单.更快速.更智慧的新特性,spark 已经逐步替代 hadoop 在大数据中的地位,成为大数据处理的主流标准.本文主要以代码和绘图的方 ...

  4. Spark2.0机器学习系列之1: 聚类算法(LDA)

    在Spark2.0版本中(不是基于RDD API的MLlib),共有四种聚类方法:      (1)K-means      (2)Latent Dirichlet allocation (LDA)  ...

  5. 在centos7上安装部署hadoop2.7.3和spark2.0.0

    一.安装装备 下载安装包: vmware workstations pro 12 三台centos7.1 mini 虚拟机 网络配置NAT网络如下: 二.创建hadoop用户和hadoop用户组 1. ...

  6. hive on spark (spark2.0.0 hive2.3.3)

    hive on spark真的很折腾人啊!!!!!!! 一.软件准备阶段 maven3.3.9 spark2.0.0 hive2.3.3 hadoop2.7.6 二.下载源码spark2.0.0,编译 ...

  7. Spark2.0集成Hive操作的相关配置与注意事项

    前言 已完成安装Apache Hive,具体安装步骤请参照,Linux基于Hadoop2.8.0集群安装配置Hive2.1.1及基础操作 补充说明 Hive中metastore(元数据存储)的三种方式 ...

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

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

  9. Magnet: Push-based Shuffle Service for Large-scale Data Processing

    本文是阅读 LinkedIn 公司2020年发表的论文 Magnet: Push-based Shuffle Service for Large-scale Data Processing 一点笔记. ...

随机推荐

  1. 关于java之socket输入流输出流可否放在不同的线程里进行处理

    2014年2月20日到叫(黑土)(人士)的公司去面试,一家新成立的公司.刚去公司是他们新聘请的猎头A来面试我的,A面试完之后是一个号称X总的年轻人来面试我,初一见此人有点邋遢,穿着西装. X:&quo ...

  2. NHibernate连接oracle报错

    NHibernate.Exceptions.GenericADOException:“could not execute query [ select sys_user0_.USERID as USE ...

  3. POJ 1243 One Person

    题意: 猜数字, 给定 G, L, G 表示可以猜的次数, 每猜一次, G减一, 假如猜的 number 大于 target, L 还需减一, 当 L == -1 或者 G==0 时, 若还没猜中, ...

  4. NodeJS-003-自动刷新

    修改index.js之后,发现刷新浏览器,没有任何更改,需要关闭应用重新启动. 为了避免每次修改代码后要自动重启.通过安装supervisor来监控代码修改. 安装:npm install -g su ...

  5. linux安装oracle11g步骤

    1. 修改用户限制 root用户:修改 /etc/security/limits.conf 文件,加上下面的参数 oracle soft nproc 2047 oracle hard nproc 16 ...

  6. RF常用快捷键

    转自:http://www.robotframework.net/article/47 重命名——>F2 搜索关键字——>F5 执行用例——>F8 创建新工程——>ctrl+n ...

  7. Linux mii-tool 命令

    mii-tool 用来查看或设置网卡的相关参数,该命令已经过时了,推荐使用 ethtool 命令 [root@localhost ~]$ mii-tool -v eth1 # 查看网卡的相关信息,包括 ...

  8. poj_1743 后缀数组

    题目大意 给定一串数字,长度为N.定义数字中的某个连续的子串为一个"theme",只要子串满足: (1)长度 >= 5 (2)和该子串相同或者该子串的“变种串”在整串数字中出 ...

  9. java基础---->java中国际化的实现

    应用程序的功能和代码设计考虑在不同地区运行的需要,其代码简化了不同本地版本的生产.开发这样的程序的过程,就称为国际化.今天,我们就开始学习java中国际化的代码实现. Java国际化主要通过如下3个类 ...

  10. jQuery性能优化整理

    1.总是从ID选择器开始继承 2.class选择器之前使用tag 3.将jQuery对象缓存起来 4.使用链式操作 5.使用子查询 6.对直接的DOM操作进行限制 7.当需要对dom进行多次操作时,使 ...