专栏首页大道七哥Hadoop(八)Java程序访问HDFS集群中数据块与查看文件系统

Hadoop(八)Java程序访问HDFS集群中数据块与查看文件系统

阅读目录(Content)

  • 一、HDFS中数据块概述
    • 1.1、HDFS集群中数据块存放位置
    • 1.2、数据块(data block)简介
    • 1.3、对分布式文件系统中的块进行抽象会带来很多好处
  • 二、Java访问HDFS中的数据块
    • 2.1、相关类和方法介绍
    • 2.2、编写程序访问
  • 二、Java查看HDFS集群文件系统
    • 1.1、相关类和方法
    • 2.2、编写程序访问

前言

  我们知道HDFS集群中,所有的文件都是存放在DN的数据块中的。那我们该怎么去查看数据块的相关属性的呢?这就是我今天分享的内容了

一、HDFS中数据块概述

1.1、HDFS集群中数据块存放位置

  我们知道hadoop集群遵循的是主/从的架构,namenode很多时候都不作为文件的读写操作,只负责任务的调度和掌握数据块在哪些datanode的分布,

  保存的是一些数据结构,是namespace或者类似索引之类的东西,真正的数据存储和对数据的读写是发生在datanode里的。

  找到${HADOOP_HOME}/ect/hadoop/hdfs-site.xml文件,里面有你自己定义的dfs.datanode.data.dir一项就是你数据存放的位置。

  此外我们还可以通过Web控制页面(http://master:50070)的hdfs查看你所存放的所有数据文件,而且更加的清晰简洁,包括文件的名称,用了多少个数据块存储,数据块的id,每个数据块写入数据的大小。

1.2、数据块(data block)简介

  每个磁盘都有默认的数据块大小,这是磁盘进行数据读/写的最小单位,构建于单个磁盘之上的文件系统通过磁盘块来管理该文件系统中的块,该文件系统块的大小可以是磁盘块的整数倍。

  HDFS同样也有块的概念,但是大得多,默认为128MB(2.0以前是64MB)。与单一磁盘上的文件系统相似,HDFS上的文件也被划分为多个分块,作为独立的存储单元。

  与其他文件系统不同的是,HDFS中小于一个块大小的文件不会占据整个块的空间。

1.3、对分布式文件系统中的块进行抽象会带来很多好处

  1)第一个明显的好处是,一个文件的大小可以大于网络中任意一个磁盘的容量。文件的所有块并不需要存储在同一个磁盘上,因此他们可以利用集群上的任意一个磁盘进行存储。   2)第二个好处是,使用块抽象而非整个文件做为存储单元,大大简化了存储子系统的设计。简化是所有系统的目标,但是这对于故障种类繁多的分布式系统来说尤为重要。

    将存储子系统控制单元设置为块,可简化存储管理(由于块的大小是固定的,因此计算单个磁盘能够存储多少个块相对容易)。同时也消除了对元数据的顾虑(块只是存储数据的一部分---而文件的元数据,

    如权限信息,并不需要与块一同存储,这样一来,其他的系统就可以单独管理这些元数据)。   3)块非常适合用于数据备份进而提供数据容错能力和可用性。将每个块复制到少数几个独立的机器上(默认为3个),可以确保在发生块、磁盘或机器故障后数据不会丢失。

    如果发现一个块不可用,系统会从其他地方读取另一个复本,而这个过程对用户是透明的。

  注意:HDFS中的文件都是一次性写入的,并且严格要求在任何时候只能有一个写入者。

二、Java访问HDFS中的数据块

2.1、相关类和方法介绍

  Hadoop关于HDFS中的数据块相关类 org.apache.hadoop.hdfs.protocol包下。(不知道为什么在2.8的api中查询不到,所以我只能通过IDEA去看源码)

  1)ExtendedBlock类(通过LocatedBlock的getBlock()方法获取)

public String getBlockName() {}

    这里主要是得到数据块的名字和id。

  2)DatanodeInfo类

    这里列举部分属性

  public String getIpAddr() {}
  public String getHostName() {}  

  3)LocatedBlock

public ExtendedBlock getBlock(){}
public long getBlockSize() {}

2.2、编写程序访问

  1)使用方法

    在 HdfsDataInputStream中:获取所有数据块信息

  2)ListBlocks_0010

import java.net.URI;
import java.util.List;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.hdfs.client.HdfsDataInputStream;
import org.apache.hadoop.hdfs.protocol.DatanodeInfo;
import org.apache.hadoop.hdfs.protocol.ExtendedBlock;
import org.apache.hadoop.hdfs.protocol.LocatedBlock;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class ListBlocks_0010
    extends Configured
    implements Tool{
    @Override
    public int run(String[] args) throws Exception{
        Configuration conf=getConf();
        String input=conf.get("input");
        FileSystem fs=
            FileSystem.get(
                URI.create(input),conf);
        HdfsDataInputStream hdis=
            (HdfsDataInputStream)
                fs.open(new Path(input));
        List<LocatedBlock> allBlocks=
            hdis.getAllBlocks();
        for(LocatedBlock block:allBlocks){
            ExtendedBlock eBlock=
                block.getBlock();
            System.out.println("------------------------");
            System.out.println(
                eBlock.getBlockId());
            System.out.println(
                eBlock.getBlockName());
            System.out.println(
                block.getBlockSize());
            System.out.println(
                block.getStartOffset());
            // 获取当前的数据块所在的DataNode的信息
            DatanodeInfo[] locations=
                block.getLocations();
            for(DatanodeInfo info:locations){
                System.out.println(
                    info.getIpAddr());
                System.out.println(
                    info.getHostName());
            }
        }
        return 0;
    }

    public static void main(String[] args) throws Exception{
        System.exit(
            ToolRunner.run(
                new ListBlocks_0010(),args));
    }
}

  3)测试

    在安装了Hadoop客户端的服务器中执行:

    结果:

    这里解释一下偏移量:

      数据块的偏移量是指一个数据块距离一个文件开始的偏移位置(从上图中可以分析出来)

二、Java查看HDFS集群文件系统

  我们怎么去查看HDFS文件系统呢?我们可以通过FileSystem类中

1.1、相关类和方法

  1)FileStatus类

    FileStatus类封装文件和目录的文件系统元数据,包括文件长度,块大小,复制,修改时间,所有权和许可信息。     FileSystem上的getFileStatus()方法提供了一种获取FileStatus的方法对象为单个文件或目录。

getAccessTime()  //上次访问的时间
getOwner()   //文件的所有者
getGroup()   //文件的所属者
getPath()  //得到文件的路径
getPermission()  //文件的权限
getReplication()  //文件的备份数

  2)FileSystem中的类  

public FileStatus[] listStatus(Path f)throws IOException;
public FileStatus[] listStatus(Path f, PathFilter filter)throws IOException;
public FileStatus[] listStatus(Path[] files)throws IOException;
public FileStatus[] listStatus(Path[] files, PathFilter filter)throws IOException;

2.2、编写程序访问

  1)核心代码

import java.io.IOException;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.conf.Configured;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.util.Tool;
import org.apache.hadoop.util.ToolRunner;

public class ListFileStatus_0010
    extends Configured
    implements Tool{
    FileSystem fs;
    @Override
    public int run(String[] args) throws Exception{
        Configuration conf=getConf();
        String input=conf.get("input");

        fs=FileSystem.get(
                URI.create(input),conf);
        FileStatus[] fileStatuses=
            fs.listStatus(new Path(input));
        for(FileStatus status:fileStatuses){
            process(status);
        }
        return 0;
    }

    public void process(
        FileStatus fileStatus) throws IOException{
        if(fileStatus.isFile()){
            System.out.println("--------------");
            System.out.println(
                fileStatus.getAccessTime());  //上次访问的时间
            System.out.println(
                fileStatus.getOwner());  //文件的所有者
            System.out.println(
                fileStatus.getGroup());  //文件的所属者
            System.out.println(
                fileStatus.getPath());  //得到文件的路径
            System.out.println(
                fileStatus.getPermission());  //文件的权限
            System.out.println(
                fileStatus.getReplication());  //文件的备份数
        }else if(fileStatus.isDirectory()){

            // 和Java的File不一样的地方:
            // 当File对象所代表的是目录的时候,
            // 可以通过listFiles方法来获取该目录下的所有文件(有可能还包含目录)

            // 在HDFS中,当FileStatus对象代表一个目录的时候
            // 没有相应的方法来获取该目录下的所有文件
            // 要通过FileSystem类来获取该目录下的文件
            //      path=fileStatus.getPath();
            //      FileStatus[] fileStstuses=
            //          fs.listStatus(path);
            FileStatus[] fileStatuses=
                fs.listStatus(fileStatus.getPath());
            for(FileStatus status:fileStatuses){
                process(status);
            }
        }
    }

    public static void main(String[] args) throws Exception{
        System.exit(ToolRunner.run(new ListFileStatus_0010(),args));
    }
}

  2)测试

    我们先运行一个文件:

    我们运行一个目录:有n多的文件,并且做了递归调用


-END-

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Hadoop(九)Hadoop IO之Compression和Codecs

      前面一篇介绍了Java怎么去查看数据块的相关信息和怎么去查看文件系统。我们只要知道怎么去查看就行了!接下来我分享的是Hadoop的I/O操作。

    大道七哥
  • Hadoop(十)Hadoop IO之数据完整性

      上一篇我分享了Hadoop的压缩和编解码器,在我们开发的过程中其实是经常会用到的,所以一定要去掌握。这一篇给大家介绍的是Hadoop的数据完整性!

    大道七哥
  • Hadoop(十六)之使用Combiner优化MapReduce

      前面的一篇给大家写了一些MapReduce的一些程序,像去重、词频统计、统计分数、共现次数等。这一篇给大家介绍的是关于Combiner优化操作。

    大道七哥
  • HBase Java API 03:HBase与MapReduce整合

    编写MapReduce程序,把"student"表中"info"列族下的"name"那一列抽取出来,存入新HBase表"student_extract"中,要求...

    CoderJed
  • HBase新的客户端接口

    最近学习接触HBase的东西,看了《Habase in Action》,但里面关于HBase接口都是过时的接口,以下为HBase新的客户端接口:

    chaplinthink
  • HBase 2.0 协处理器实现 ES 数据同步

    在正式进行讲述实现之前,我觉得有必要说一下出发点。团队期初数据都是基于 HBase+Phoenix 这样架构进行持久化。随着业务的复杂性增加,对部分表的查询效率...

    迹_Jason
  • 大数据应用之HBase数据插入性能优化实测教程

    大家在使用HBase的过程中,总是面临性能优化的问题,本文从HBase客户端参数设置的角度,研究HBase客户端数据批量插入性能优化的问题。事实胜于雄辩,数据比...

    数据饕餮
  • Mapreduce和HBase新版本整合之WordCount计数案例

    先计数单词数量存到hdfs文件上,这个是以前的就做过的 package com.my.myhnase.mapreduce; import java.io.IO...

    汤高
  • HBase整合MapReduce之建立HBase索引

    HBase索引主要用于提高Hbase中表数据的访问速度,有效的避免了全表扫描,HBase中的表根据行健被分成了多个Regions,通常一个region的一行都会...

    汤高
  • Hadoop Mapper 阶段将数据直接从 HDFS 导入 Hbase

    数据源格式如下: 20130512 1 -1 -1 13802 1 2013-05-12 07:26:22 20130512 1 -1 -1 13802 ...

    用户1177713

扫码关注云+社区

领取腾讯云代金券