从Spark Shuffle RDD到Shuffle Service on Yarn 源码阅读 二
涉及内容从Task执行,到RDD的读取,以及Shuffle数据的获取。本章主要从第二部分入手
Task体系
一 ShuffleMapTask的读和写
二 Shuffle Block的读和写
三 External Shuffle Service的设计
引子
上一章完成了从ShuffledRDD到ShuffleBlock的读取,这一章节侧重于作为ExternalShuffleService的CLient端,Spark Executor如何完成shuffle 数据的读取。
基础知识
Netty
因为Spark使用了Netty作为底层的数据传输框架,所以阅读这一部分需要掌握基础的Netty知识,否则看起来的时候很难以理解。
建议通过官方文档进行入门的基础学习。
https://netty.io/3.7/guide/#architecture
Spark
ExternalShuffleService RPC消息设计
Spark中为Shuffle数据的读取设计了如下的消息类型
Message.java
enum Type implements Encodable {
ChunkFetchRequest(0), ChunkFetchSuccess(1), ChunkFetchFailure(2),
RpcRequest(3), RpcResponse(4), RpcFailure(5),
StreamRequest(6), StreamResponse(7), StreamFailure(8),
OneWayMessage(9), UploadStream(10), User(-1);
下面摘抄一段TransportClient.java中的注释
1. For example, a typical workflow might be:
2. client.sendRPC(new OpenFile("/foo")) --> returns StreamId = 100
3. client.fetchChunk(streamId = 100, chunkIndex = 0, callback)
4. client.fetchChunk(streamId = 100, chunkIndex = 1, callback)
5. client.sendRPC(new CloseStream(100))
这里只说明其中几个比较关键的消息类型
- RpcRequest,这是一个generic类型的消息,意味着其中可以封装多种类型的MSG。如下的Encodable的子类对象都可以进行发送。为什么这里有一个generic类型的rpc request定义呢,是因为这这消息只是control plane的消息,并不涉及真实文件数据的传送,对比其他几个消息就可以发现,其他的消息都涉及到大量数据的发送和接收过程,所以这里进行了区分。
这里拿出OpenBlock为例子进行一下分析。
在OneForOneBLockFetcher.java中可以分析出如下的关系, openblock请求会得到streamhandle作为响应。
ShuffleClient ExternalShuffleService
|------->–openblock-------->|
| |
|<--------streamHandle–<-- |
| |
public OpenBlocks(String appId, String execId, String[] blockIds) {
this.appId = appId;
this.ex