Hadoop内核分析之Hadoop文件存储细节

2019-03-28 13:16|来源: 网络

众所周知,我们需要Hadoop来分布式存储我们的数据,提高并发和吞吐量,造就了Mapreduce框架的易用性。那对于整个这个过程来说,最开始需要我们认识到的是文件是如何存储在hadoop系统上的。

Hadoop可以分为三个部分,Client端,namenode端和datanode端。他们之间的协作做成了这个庞大的分布式文件系统。文件从客户端这个接口,进入系统,由客户端和namenode通信,使用反射机制,告知Client文件所需要存储的datanode列表,然后就可以进行传输了,当然,我们在这里屏蔽了所有hadoop错误处理的过程,即便这是hadoop的最大的优势之一。

大体的过程知道了,那么下面我们可以深入源码,来看看具体的实现。

首先在Client端,假设你写了一个mapreduce程序就是用来存储一个文件的,代码如下:

String localSrc = "/root/Desktop/examp.c";
  String dst = "/fangpei/examp.c";
  InputStream in = new BufferedInputStream(new FileInputStream(localSrc));
  Configuration conf = new Configuration();
  URI uri = URI.create(dst);
  FileSystem fs = FileSystem.get(uri, conf);
  OutputStream out = fs.create(new Path(dst),new Progressable(){
   public void progress(){
    System.out.print(".");
   
   }
  });
IOUtils.copyBytes(in, out, 4096,true); 

 FileSystem.get(uri, conf);

用来获取文件系统。其中FileSystem类是抽象类,会进入内存的cache寻找已创建的文件系统(FileSystem.cache.get(uri,conf)),如果没有则最终会调用newInstance去创建DistrubutedFileSystem这个类的对象,放入cache中并返回这个文件系统实例。

OutputStream out = fs.create(new Path(dst),new Progressable(){
   public void progress(){
    System.out.print(".");
   
   }
  });

这个create会调用DistributedFileSystem的create。这个create创建了一个DFSOutputStream输出流,在这个输出流的构造函数中会映射调用namenode方法用于在分布式系统上创建一个文件。

namenode.create(src, masked, clientName, overwrite, createParent, replication, blockSize);

然后启动streamer

streamer.start();

DataStreamer这个线程类用于真正的数据传输。里面保持了一个dataqueue,会不停的监听这个队列是否为空。

启动完数据监听守护进程后,对数据IO通道的读写操作如下:

IOUtils.copyBytes(in, out, 4096,true);

其中,copyBytes最终会调用到writechunk函数,该函数如下:

currentPacket.writeChecksum(checksum, 0, cklen);
        currentPacket.writeData(b, offset, len);
        currentPacket.numChunks++;
        bytesCurBlock += len;
............................
        enqueueCurrentPacket();

这里就是将数据包组装并且压进队列,然后DataStreamer就会执行发送队列。

相关问答

更多
  • hadoop和hbase问题[2022-03-08]

    Hadoop 是一个能够对大量数据进行分布式处理的软件框架。 HBase是一个分布式的、面向列的开源数据库。 HBase在Hadoop之上提供了类似于Bigtable的能力。 HBase是Apache的Hadoop项目的子项目。 HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。 另一个不同的是HBase基于列的而不是基于行的模式。
  • hadoop的数据存储[2023-05-06]

    存放到HDFS 一般都是要分析的数据。分析完成的数据直接存储到MYSQL 或者ORACLE 中。这种处理方式是离线处理。如日志文件存储到hdfs 分析出网站的流量 UV PV 等等。一般都是用pig hive 和mr 等进行分析的。 存放到HBASE 一般都是数据拿过来直接用的。而且他是实时的。也就是说数据就是成型的而且不需要进行分析就能得到结果的数据。 大致就是这么个意思。有点啰嗦了。
  • hadoop fs -put /source /target source :源文件位置 target:put到的位置
  • 1、存储文件的时候需要指定存储的路径,这个路径是HDFS的路径。而不是哪个节点的某个目录。比如./hadoop fs -put localfile hdfspat 一般操作的当前路径是/user/hadoop比如执行./hadoop fs -ls .实际上就相当于./hadoop fs -ls /user/hadoop 2、HDFS本身就是一个文件系统,在使用的时候其实不用关心具体的文件是存储在哪个节点上的。如果需要查询可以通过页面来查看,也可以通过API来实现查询。
  • hdfs存储文件是按照块来的,hdfs的块大小默认是256M,可以自己设置,一个大文件会被切分成很多块存储到不同的地方,同时每个块也会备份多份。
  • 你的假设是错误的。 Hadoop计算没有复制的块数。 你可以在broose hadoop文件系统时检查这一点。 如果选择文件,则可以看到如下输出: Total number of blocks: 1 471365007463424017: IP1:Port IP2:Port IP3:Port 这是一个位于3台不同机器上的块(复制因子为3)。 Your assumption is wrong. Hadoop counts the number of blocks with ...
  • HDFS文件系统是分布式存储系统,其中存储位置是虚拟的并且使用来自所有DataNode的磁盘空间来创建。 安装hadoop时,必须为dfs.namenode.name.dir和dfs.datanode.data.dir指定路径。 这些是所有HDFS相关文件存储在各个节点上的位置。 将数据存储到HDFS时,它存储为指定大小的块(Hadoop 2.X中默认为128MB)。 使用hdfs dfs命令时,您将看到完整的文件,但内部HDFS将这些文件存储为块。 如果在本地文件系统上检查上述路径,您将看到一堆与HDFS ...
  • 视频和图像文件可以存储在HDFS中。 如果要处理视频和图像文件,则需要弄清楚如何拆分这些文件并编写自己的InputFormat和OutputFormat以及RecordReader。 您可以在网上搜索如何创建这些类。 Video and Image files can be stored in HDFS. If you want to process video and image files, you need to figure out how to split this files and write ...
  • 检查hdfs-site.xml和core-site.xml。 相关属性是: dfs.name.dir /var/lib/hadoop/dfs/name Determines where on the local filesystem the DFS name node should store the name table(fsimage). If t ...
  • Hadoop有asm 3.2而我使用的是ASM 5.在ASM5中,ClassVisitor是一个超类,而在3.2中它是一个接口。 出于某种原因,错误是Throwable(信任Shevek),catch块只捕获异常。 任何hadoop日志都没有捕获throwable错误。 因此,调试非常困难。 使用jar jar链接修复asm版本问题,现在一切正常。 如果你正在使用Hadoop并且某些东西不起作用并且没有日志显示任何错误,那么请尝试抓住Throwable。 阿伦 Hadoop had asm 3.2 and ...