一、写在前面
EC的写流程有一部分流程跟普通副本写流程是复用的。例如:DataStreamer线程的run方法。StripedDataStreamer继承自DataStreamer,run方法也是直接继承过来的。
因此读本文之前,如果读者还不了解HDFS的普通写副本块的流程,强烈建议可以翻看一下我之前的系列文章:
【精】彻底吃透HDFS写流程(8)-- 数据真正落盘
二、从write方法开始
这里注意一点:在调用输出流的write相关方法之前,相应的DataStreamer线程就已经启动了。
@Override
protected synchronized void start() {
for (StripedDataStreamer streamer : streamers) {
streamer.start();
}
}
在EC这里是private final List<StripedDataStreamer> streamers;
,为什么list呢?因为EC是条带式的,会把一个block的数据写到一个条带里的多个datanode上,因此要有一个StripedDataStreamer的列表,每一个StripedDataStreamer对应一个datanode。遍历启动这个列表里面的StripedDataStreamer,这个StripedDataStreamer继承自DataStreamer,run方法是直接继承下来的。因此逻辑通用。
好,接下来我们从FSOutputSummer#write1
方法出发,此方法中调用System.arraycopy方法将用户数据拷贝到local buffer中。如果拷贝完之后发现buf的size满了,则进行一次flushBuffer操作。
flushBuffer这个方法是我们重点需要关注的,这个方法的功能时强制把buffer中的输出数据计算checksum并且写入到底层的output stream里。
flushBuffer里会调用一个核心方法writeChecksumChunks
,这个writeChecksumChunks
方法主要是写块校验、数据chunks到底层流。
看下这个writeChecksumChunks
方法:
网友评论