Hadoop学习--第五篇:HDFS文件系统架构和操作

一、HDFS概述

1.1 HDFS概念

HDFS ( Hadoop Distributed File System ) ,Hadoop分布式文件系统,通过目录树(/)来定位文件。是根据google发表的论文翻版的。论文为GFS(Google File System)Google 文件系统(中文:http://www.open-open.com/lib/view/open1328763454608.html,英文:https://pdos.csail.mit.edu/6.824/papers/gfs.pdf)。

1.2 HDFS优缺点

1.2.1 优点

① 高容错性:保存多个副本,提高容错性,副本丢失或宕机自动恢复。默认存3份。
② 简单的一致性模型:一次写入,多次读取,不能修改。
③ 适合大数据的处理:数据规模上,能够处理数据规模达到 GB、TB、甚至PB级别的数据。文件规模上,能够处理百万规模以上的文件数量,数量相当之大。
④运行在廉价的机器上。

1.2.2 缺点

① 不适合低延时数据访问,比如毫秒级的存储数据,是做不到的。
② 无法高效的对大量小文件进行存储。
③ 一个文件只能有一个写,不允许多个线程同时写。也不支持文件修改。

1.3 HDFS架构

在这里插入图片描述
① Client:客户端。负责文件切分;与NameNode交互,获取文件的位置信息;与DataNode交互,读取或者写入数据;
② NameNode:管理数据块映射;处理客户端的读写请求;配置副本策略;管理HDFS的名称空间;
③ SecondaryNameNode:有两个作用,一是镜像备份,二是日志与镜像的定期合并。它会保存合并后的命名空间镜像的副本,并在namenode发生故障时启用。
④ DataNode:负责存储client发来的数据块block;执行数据块的读写操作。

1.4 HDFS块大小

块的大小可以通过配置参数(hdfs-site.xml 文件中dfs.blocksize)来规定。
默认大小在hadoop2.x版本中是128M,老版本中是64M。

二、HDFS命令行操作

动作命令例子
输出命令参数hadoop fs -helphadoop fs -help ls
显示根目录信息hadoop fs -lshadoop fs -ls /
创建目录hadoop fs -mkdirhadoop fs -mkdir /foodir
删除文件或文件夹hadoop fs -rmhadoop fs -rm -r -f /foodir
拷贝hadoop fs -cphadoop fs -cp /test/1.txt /2.txt
移动hadoop fs -mvhadoop fs -mv /2.txt /test/
显示文件内容hadoop fs -cathadoop fs -cat /test/1.txt
本地剪切粘贴到HDFShadoop fs -moveFromLocalhadoop fs -moveFromLocal ./3.txt /test
追加文件hadoop fs -appendToFilehadoop fs -appendToFile 2.txt /test /1.txt
本地拷贝到HDFShadoop fs -copyFromLocal
或者
hadoop fs -put
hadoop fs -copyFromLocal 4.txt /test
HDFS拷贝到本地hadoop fs -copyToLocal
或者
hadoop fs -get
hadoop fs -copyToLocal /test/1.txt ./5.txt
合并下载多个文件hadoop fs -getmergehadoop fs -getmerge /test/* ./result.txt
统计可用空间信息hadoop fs -dfhadoop fs -df -h /
统计文件夹的大小信息hadoop fs -duhadoop fs -du -h /
设置HDFS中文件的副本数量hadoop fs -setrephadoop fs -setrep 2 /test/6.txt

三、通过API操作HDFS

3.1 获取文件系统

@Test
public void initHDFS() throws Exception {
    // 1 创建配置信息对象
    Configuration configuration = new Configuration();

    // 2 获取文件系统
    FileSystem fs = FileSystem.get(configuration);

    // 3 打印文件系统
    System.out.println(fs.toString());
}

3.2 HDFS文件上传

参数优先级:① 客户端代码中设置的值 > ② classpath下的用户自定义配置文件 > ③ 服务器的默认配置。

@Test
public void testCopyFromLocalFile() throws IOException, InterruptedException, URISyntaxException {
    // 1 获取文件系统
    Configuration configuration = new Configuration();
   //  configuration.set("dfs.replication", "2");  设置副本数量
    FileSystem fs = FileSystem.get(new URI("hdfs://Master:9000"), configuration, "root");
    // 2 上传文件
    fs.copyFromLocalFile(new Path("e:/hello.txt"), new Path("/hello.txt"));
    // 3 关闭资源
    fs.close();
}

3.3 HDFS文件下载

@Test
public void testCopyToLocalFile() throws IOException, InterruptedException, URISyntaxException{
    // 1 获取文件系统
    Configuration configuration = new Configuration();
    FileSystem fs = FileSystem.get(new URI("hdfs://Master:9000"), configuration, "root");
    // 2 执行下载操作
    // boolean delSrc 指是否将原文件删除
    // Path src 指要下载的文件路径
    // Path dst 指将文件下载到的路径
    // boolean useRawLocalFileSystem 是否开启文件效验
    fs.copyToLocalFile(false, new Path("/hello1.txt"), new Path("e:/hello1.txt"), true);
    // 3 关闭资源
    fs.close();
}

3.4 HDFS文件详情查看

@Test
public void testListFiles() throws IOException, InterruptedException, URISyntaxException {
    // 1获取文件系统
    Configuration configuration = new Configuration();
    FileSystem fs = FileSystem.get(new URI("hdfs://Master:9000"), configuration, "root");

    // 2 获取文件详情
    RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/"), true);

    while (listFiles.hasNext()) {
      LocatedFileStatus status = listFiles.next();

      // 输出详情
      // 文件名称
      System.out.println(status.getPath().getName());
      // 长度
      System.out.println(status.getLen());
      // 权限
      System.out.println(status.getPermission());
      // z组
      System.out.println(status.getGroup());

      // 获取存储的块信息
      BlockLocation[] blockLocations = status.getBlockLocations();

      for (BlockLocation blockLocation : blockLocations) {
        // 获取块存储的主机节点
        String[] hosts = blockLocation.getHosts();
        for (String host : hosts) {
          System.out.println(host);
        }
      }
    }
}

3.5 HDFS文件和文件夹判断

@Test
public void testListStatus() throws IOException, InterruptedException, URISyntaxException {
    // 1获取文件系统
    Configuration configuration = new Configuration();
    FileSystem fs = FileSystem.get(new URI("hdfs://Master:9000"), configuration, "root");

    // 2 判断是否是文件还是文件夹
    FileStatus[] listStatus = fs.listStatus(new Path("/"));

    for (FileStatus fileStatus : listStatus) {

      // 如果是文件
      if (fileStatus.isFile()) {
        System.out.println(fileStatus.getPath().getName() + " is a file!");
      } else {
        System.out.println(fileStatus.getPath().getName() + " is not a file!");
      }
    }
}

四、通过IO流操作HDFS

4.1 HDFS文件上传

@Test
public void putFileToHDFS() throws IOException, InterruptedException, URISyntaxException {

    // 1 获取文件系统
    Configuration configuration = new Configuration();
    FileSystem fs = FileSystem.get(new URI("hdfs://Master:9000"), configuration, "root");

    // 2 创建输入流
    FileInputStream fis = new FileInputStream(new File("e:/hello.txt"));

    // 3 获取输出流
    FSDataOutputStream fos = fs.create(new Path("/hello4.txt"));

    // 4 流对接
    IOUtils.copyBytes(fis, fos, configuration);

    // 5 关闭资源
    IOUtils.closeStream(fis);
    IOUtils.closeStream(fos);
}

4.2 HDFS文件下载

@Test
public void getFileFromHDFS() throws IOException, InterruptedException, URISyntaxException{
    // 1 获取文件系统
    Configuration configuration = new Configuration();
    FileSystem fs = FileSystem.get(new URI("hdfs://Master:9000"), configuration, "root");

    // 2 获取输入流
    FSDataInputStream fis = fs.open(new Path("/hello4.txt"));

    // 3 获取输出流
    //FileInputStream fos = new FileInputStream(new File("e:/hello.txt"));

    // 4 流对接 输出到控制台
    IOUtils.copyBytes(fis, System.out, configuration);

    // 5 关闭资源
    IOUtils.closeStream(fis);
}

4.3 定位读取文件

4.3.1 下载第一块
@Test
public void readFileSeek1() throws IOException, InterruptedException, URISyntaxException{
    // 1 获取文件系统
    Configuration configuration = new Configuration();
    FileSystem fs = FileSystem.get(new URI("hdfs://Master:9000"), configuration, "root");

    // 2 获取输入流
    FSDataInputStream fis = fs.open(new Path("/hadoop-2.7.2.tar.gz"));

    // 3 创建输出流
    FileOutputStream fos = new FileOutputStream(new File("e:/hadoop-2.7.2.tar.gz.part1"));

    // 4 流的拷贝
    byte[] buf = new byte[1024];

    for(int i =0 ; i < 1024 * 128; i++){
      fis.read(buf);
      fos.write(buf);
    }

    // 5 关闭资源
    IOUtils.closeStream(fis);
    IOUtils.closeStream(fos);
}
4.3.2 下载第二块
@Test
public void readFileSeek2() throws IOException, InterruptedException, URISyntaxException{

    // 1 获取文件系统
    Configuration configuration = new Configuration();
    FileSystem fs = FileSystem.get(new URI("hdfs://Master:9000"), configuration, "root");

    // 2 打开输入流
    FSDataInputStream fis = fs.open(new Path("/hadoop-2.7.2.tar.gz"));

    // 3 定位输入数据位置
    fis.seek(1024*1024*128);

    // 4 创建输出流
    FileOutputStream fos = new FileOutputStream(new File("e:/hadoop-2.7.2.tar.gz.part2"));

    // 5 流的对拷
    IOUtils.copyBytes(fis, fos, configuration);

    // 6 关闭资源
    IOUtils.closeStream(fis);
    IOUtils.closeStream(fos);
}
4.3.3 合并文件

找到文件所在位置,搜索栏搜索cmd
在 window 命令窗口中执行:type hadoop-2.7.2.tar.gz.part2 >> hadoop-2.7.2.tar.gz.part1
重命名文件名:hadoop-2.7.2.tar.gz.part1为hadoop-2.7.2.tar.gz

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值