zoukankan      html  css  js  c++  java
  • HDFS读写数据流

    一, 读文件剖析

    Configuration conf = new Configuration();

    FileSystem fs = FileSystem.get(conf);

    FSDataInputStream in = fs.open(new Path(uri));

    客户端调用FileSystem的get()方法得到一个实例fs(即分布式文件系统DistributedFileSystem),然后fs调用open()打开希望读取的文件(步骤1)

    DistributedFileSystem(fs)通过使用RPC调用NameNode以确定文件起始block的位置(步骤2)。(Block位置信息存储在namenode的内存中)。对于每一个bolck,NameNode返回block所有复本的DataNode地址(并根据与client的距离排序)。

    DistributedFileSystem(fs).open()返回一个FSDataInputStream对象给client用来读数据。FSDataInputStream封装了分布式文件输入流(DFSInputStream)用于管理NameNode和DataNode的I/O. client对这个输入流调用read()方法(步骤3)。

    此输入流DFSInputStream has stored the datanode addresses for the first few blocks in the file, then connects to the first(closest) datanode for the first block in the file.通过对数据流反复的调用read()可以将数据从datanode传输到client(步骤4).

    对一个block读完时DFSInputStream会关闭与datanode的连接,然后寻找下一个block的最佳datanode(步骤5).当一批blocks读完时,DFSInputStream会询问namenode下一批所需blocks的datanode地址。读取blocks的切换对于client是透明的。

    当client完成读取,调用FSDataInputStream的close()方法(步骤6)。

    在读的过程中,如果DFSInputStream和datanode通信时出错,它会尝试连接下一个最近的datanode。DFSInputStream也会通过校验和确认从datanode读取的数据是否完整,如果发现某个block有损坏,就回报告给namenode,然后从其它复本读取此block。

    二, 写文件剖析

    Configuration conf = new Configuration();

    FileSystem fs = FileSystem.get(conf);

    FSDataOutputStream out = fs.create(new Path(uri));

    客户端调用FileSystem的get()方法得到一个实例fs(即分布式文件系统DistributedFileSystem),然后fs调用create()创建文件(步骤1),

    DistributedFileSystem(fs)通过RPC调用NameNode在命名空间中创建一个新文件,此时该文件还没有相应的数据块(步骤2)。namenode会检查此文件是否已存在及client是否有权限新建文件,如果检查不通过,则创建失败并向client抛出IOException异常,否则namenode就会创建一条记录。

    然后DistributedFileSystem(fs)向client返回一个FSDataOutputStream(封装了DFSOutputStream)对象来写数据。在client写数据时(步骤3),DFSOutputStream将它分成一个个的数据包并写入内部队列,称作数据队列(data queue).

    DFSOutputStream会请求namenode在合适的datanodes(默认3个)上分配blocks来存储数据队列。3个datanodes形成一个管线DataStreamer将数据包流式的传输到管线中第一个datanode,第一个datanode存储数据包并发送到第二个datanode, 第二个datanode存储数据包并发送到第三个datanode(步骤4).

    DFSOutputStream也维护了一个确认队列(ack queue),当收到管道中所有datanodes的确认信息后对应数据包才会从确认队列中删除(步骤5)。

    Client完成数据的写入后便对FSDataOutputStream调用close()方法(步骤6)。

    该操作将所有剩余的数据包写入管线,并等待确认,最后向namenode报告写完成(步骤7)。

    注:DistributedFileSystem, DFSInputStream, DFSOutputStream这几个是逻辑概念,并没用实际的类

  • 相关阅读:
    教大家如何在word 2007中同时打出对齐上下标以及字母头上有波浪线(非编辑器)
    C#返回多个参数 ref及out
    回溯法解决0-1背包问题
    USB peripherals can turn against their users
    50元制作PS2键盘无线监控装置
    物联网安全拔“牙”实战——低功耗蓝牙(BLE)初探
    Bluetooth Low Energy 嗅探
    MagSpoof:能预测并窃取你下一张信用卡号码的廉价设备
    Python 安全类目推荐 (持续更新)
    树莓派安装kali后的简单配置
  • 原文地址:https://www.cnblogs.com/liangzh/p/2541785.html
Copyright © 2011-2022 走看看