Hadoop源码分析-HDFS写数据之创建packet

[TOC]
契约机制深度剖析那里,我们提到过两个类,DFSOutputStreamDataStreamer 这两个类是写数据的核心类。我们先看看注释:

1. DFSOutputStream注释

 * DFSOutputStream creates files from a stream of bytes.
 *
 * The client application writes data that is cached internally by
 * this stream. Data is broken up into packets, each packet is
 * typically 64K in size. A packet comprises of chunks. Each chunk
 * is typically 512 bytes and has an associated checksum with it.
 *
 * When a client application fills up the currentPacket, it is
 * enqueued into dataQueue.  The DataStreamer thread picks up
 * packets from the dataQueue, sends it to the first datanode in
 * the pipeline and moves it from the dataQueue to the ackQueue.
 * The ResponseProcessor receives acks from the datanodes. When an
 * successful ack for a packet is received from all datanodes, the
 * ResponseProcessor removes the corresponding packet from the
 * ackQueue.
 *
 * In case of error, all outstanding packets and moved from
 * ackQueue. A new pipeline is setup by eliminating the bad
 * datanode from the original pipeline. The DataStreamer now
 * starts sending packets from the dataQueue.
  • block 分解成多个 packet (每个64K),packet分解成多个chunk(每个512B),每个chunk都有个校验和。

  • DFSOutputStream负责把数据写入dataQueue,写入单位为packet

  • DataStreamerdataQueue中提取packet,发送到管道中的第一个datanode,同时将该packet写入 ackQueue中(大家都知道block是有副本的,在写block之前就已经确定了,这些副本要写到哪些datanode上,这些datanode形成一个数据管道,DataStreamer只会把数据写入管道的第一个datanode,然后第一个dataNode向第二个datanode写数据,第二个再向第三个写,它们之间使用socket传输数据)

  • ResponseProcessor会从datanodes接收ack(此ackDatanode接收packet成功后的确定),ResponseProcessor接收到所有Datanoteack后,就从ackQueue中移除相应的packet

  • 如果遇到异常,所有的packets都从ackQueue移除,并排除异常的Datanode,再重新申请一个管道 。

  • 然后 DataStreamer又重新从dataQueue中,获得packets并发送。

2. DataStreamer 类注释

  // The DataStreamer class is responsible for sending data packets to the
  // datanodes in the pipeline. It retrieves a new blockid and block locations
  // from the namenode, and starts streaming packets to the pipeline of
  // Datanodes. Every packet has a sequence number associated with
  // it. When all the packets for a block are sent out and acks for each
  // if them are received, the DataStreamer closes the current block.
  • DataStreamer 负责发送packet到管道中的datanode.
  • DataStreamerNamenode中检索新的blockidblock位置,并开始将packet流式传输到datanode的管道。
  • 每个packet都有序列号。
  • 当一个block的所有packet都被发送出去,并且收到每个packetack时,DataStreamer关闭当前block

3. 创建packet

根据DFSOutputStreamDataStream的注释,我们知道这两个类是HDFS写数据的关键。那么他们在哪里被使用呢?我们直接跟进fos.write("abc".getBytes());看看。

  1. 顺着fos.write("abc".getBytes());一直跟进,就跟到了OutputStream.write(int b)方法。并且这个还是个抽象方法。一路跟下来并没有发现调用HDFS的什么,那这样跟肯定是不对的。在最初的地方肯定是返回的并不是实际的对象。我们要去找到真实的对象。

    image

    image

    image

    image

  2. 我们在通过fileSystem.create方法去寻找真实返回的对象类型。当然我们之前讲过fileSystem.create实际上是调用了DistributedFileSystem.create。我们直接看DistributedFileSystem.create就可以了。这里最后就是返回的return dfs.createWrappedOutputStream(dfsos, statistics);,我们接着跟进去看看。

    image

  3. 下面都是一行代码,直接过了。


    image

    image
  4. 可以看到,这里最后返回的其实是HdfsDataOutputStream类。那么我们就直接看HdfsDataOutputStream.write()方法吧。

    image

  5. 结果在 HdfsDataOutputStream里没有找到,那么我们到他的父类里去看看。

    image

  6. HdfsDataOutputStream的父类FSDataOutputStream里,还真找到了。里面调用了out.write(b);,跟进去结果发现又到了OutputStream.write()。那么我们就想下,是不是out.write()out被赋值为其他子类了呢?

    image

  7. 仔细看看代码,发现原来这个out变量是由构造函数赋值的,并且还是调用了父类的构造函数赋值。那我们看看在构建 HdfsDataOutputStream时传入的实际对象是哪个?

    image

  8. 可以看到其实是DFSOutputStream。那么我们看看DFSOutputStream.write()方法吧。

    image

  9. 结果又是没有找到,那么我们再看看他的父类FSOutputStream

    image

  10. 终于找到了,这里调用了flushBuffer();。我们在跟进下。

    image

  11. FSOutputSummer.flushBuffer(),这里除了writeChecksumChunks(buf, 0, lenToFlush);之外,其他都是定义变量,或者判断之类的。

    image

    image

  12. FSOutputSummer.writeChecksumChunks()1:这里是计算校验和;2:按照chunk的大小来遍历字节;3:把每个chunk发送出去;FSOutputSummer.writeChunk()这个方法是个抽象方法,需要看他的实现DFSOutputStream.writeChunk()

    image

  13. DFSOutputStream.writeChunk(),代码writeChunkImpl()就是写Chunk的实现。跟进。

    image

  14. DFSOutputStream.writeChunkImpl(),这里代码比较多,分开看看
    14.1 这块没什么可说的, 都是写检查

    image

    14.2 这里是把 chunk 写入 packet,有校验和,数据,和计数
    image

    14.3 1:这里就是判断是不是写够一个packet了;2:这里就是个debug日志;3:这里这开始写数据了;
    image

  15. DFSOutputStream.waitAndQueueCurrentPacket().
    15.1 这里没什么可看的。就是有个while循环。就是当dataQueue+ackQueue超过配置的大小时,就进行等待。

    image

    15.2 DFSOutputStream.queueCurrentPacket(),这个才是我们要找的代码。
    image

  16. DFSOutputStream.queueCurrentPacket(),这里就是把packet添加到dataQueue队列了,后面还有个notifyAll(),因为前面判断如何dataQueue满了,会wait。

    image

以上就是创建packet并把packet写入 dataQueue 的过程了。这都发生在客户端。以下是个简单的总结

image

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容