大数据从入门到实战 - 大数据系统及应用-HDFS实训


叮嘟!这里是小啊呜的学习课程资料整理。好记性不如烂笔头,今天也是努力进步的一天。一起加油进阶吧!
在这里插入图片描述

一、关于此次实践

1、实战简介

Hadoop是一个由Apache基金会所开发的分布式系统基础架构,可以在不了解分布式底层细节的情况下,开发分布式程序,以满足在低性能的集群上实现对高容错,高并发的大数据集的高速运算和存储的需要。Hadoop支持超大文件(可达PB级),能够检测和快速应对硬件故障、支持流式数据访问、同时在简化的一致性模型的基础上保证了高容错性。因而被大规模部署在分布式系统中,应用十分广泛。
实验目的

理解HDFS在Hadoop体系结构中的角色;
熟悉HDFS操作常用的Java API。

2、全部任务

在这里插入图片描述
在这里插入图片描述

二、实践详解

1、第1关:HDFS Java API编程 ——文件读写

在这里插入图片描述
在这里插入图片描述

import java.io.*;
import java.sql.Date;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;


public class hdfs {

    public static void main(String[] args) throws IOException {
        Configuration conf = new Configuration();//configuration类实现hadoop各模块之间值的传递
        FileSystem fs = FileSystem.get(conf);  //获取文件系统
        Path file = new Path("/user/hadoop/myfile");        //创建文件
        FSDataOutputStream outStream = fs.create(file); //获取输出流
        outStream.writeUTF("https://www.educoder.net");//可以写入任意字符
        outStream.close();//记得关闭输出流
        FSDataInputStream inStream = fs.open(file);  //获取输入流
        String data = inStream.readUTF();  //读取文件
    }
  }

评测
在这里插入图片描述

2、第2关:HDFS Java API编程——文件上传

在这里插入图片描述

import java.io.*;
import java.sql.Date;
import java.util.Scanner;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

public class hdfs {

      /**
     * 判断路径是否存在
     */
    public static boolean test(Configuration conf, String path) throws IOException {
        /*****start*****/
        //请在此处编写判断文件是否存在的代码
        try(FileSystem fs = FileSystem.get(conf)){
            return fs.exists(new Path(path));
        } catch (IOException e){
            e.printStackTrace();
            return false;
        }   
        /*****end*****/
    }

    /**
     * 复制文件到指定路径
     * 若路径已存在,则进行覆盖
     */
    public static void copyFromLocalFile(Configuration conf, String localFilePath, String remoteFilePath) throws IOException {
        /*****start*****/
        //请在此处编写复制文件到指定路径的代码

        Path localPath = new Path(localFilePath);  
        Path remotePath = new Path(remoteFilePath);  
        try (FileSystem fs = FileSystem.get(conf)) { 
        fs.copyFromLocalFile(false, true, localPath, remotePath);  
         } catch (IOException e) {  
            e.printStackTrace();  
         }  

        /*****end*****/
    }

    /**
     * 追加文件内容
     */
    public static void appendToFile(Configuration conf, String localFilePath, String remoteFilePath) throws IOException {
       /*****start*****/
         //请在此处编写追加文件内容的代码

        Path remotePath = new Path(remoteFilePath);  
    try (FileSystem fs = FileSystem.get(conf);  
            FileInputStream in = new FileInputStream(localFilePath);) {  
        FSDataOutputStream out = fs.append(remotePath);  
        byte[] data = new byte[1024];  
        int read = -1;  
        while ((read = in.read(data)) > 0) {  
            out.write(data, 0, read);  
        }  
        out.close();  
    } catch (IOException e) {  
        e.printStackTrace();  
    }  

        /*****end*****/
    }

    /**
     * 主函数
     */
    public static void main(String[] args)throws IOException  {
        Configuration conf = new Configuration();

        createHDFSFile(conf);

        String localFilePath = "./file/text.txt";           // 本地路径
        String remoteFilePath = "/user/hadoop/text.txt";    // HDFS路径
        String choice = "";    

        try {
            /* 判断文件是否存在 */
            Boolean fileExists = false;
            if (hdfs.test(conf, remoteFilePath)) {
                fileExists = true;
                System.out.println(remoteFilePath + " 已存在.");
                choice = "append";      //若文件存在则追加到文件末尾
            } else {
                System.out.println(remoteFilePath + " 不存在.");
                choice = "overwrite";   //覆盖
            }


            /*****start*****/
            //请在此处编写文件不存在则上传 文件choice等于overwrite则覆盖   choice 等于append 则追加的逻辑

             if (!fileExists) { // 文件不存在,则上传
                hdfs.copyFromLocalFile(conf, localFilePath, remoteFilePath);
                System.out.println(localFilePath + " 已上传至 " + remoteFilePath);
            } else if (choice.equals("overwrite")) {    // 选择覆盖
                hdfs.copyFromLocalFile(conf, localFilePath, remoteFilePath);
                System.out.println(localFilePath + " 已覆盖 " + remoteFilePath);
            } else if (choice.equals("append")) {   // 选择追加
                hdfs.appendToFile(conf, localFilePath, remoteFilePath);
                System.out.println(localFilePath + " 已追加至 " + remoteFilePath);
            }

            /*****end*****/

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //创建HDFS文件
    public static void createHDFSFile(Configuration conf)throws IOException{
        FileSystem fs = FileSystem.get(conf);  //获取文件系统
        Path file = new Path("/user/hadoop/text.txt");        //创建文件   
        FSDataOutputStream outStream = fs.create(file); //获取输出流
        outStream.writeUTF("hello");
        outStream.close();
        fs.close();
    }
}

评测
在这里插入图片描述

3、第3关:HDFS Java API编程 ——文件下载

在这里插入图片描述

import java.io.*;
import java.sql.Date;
import java.util.Scanner;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

public class hdfs {
     /**
     * 下载文件到本地
     * 判断本地路径是否已存在,若已存在,则自动进行重命名
     */
    public static void copyToLocal(Configuration conf, String remoteFilePath, String localFilePath) throws IOException {
        FileSystem fs = FileSystem.get(conf);
        Path remotePath = new Path(remoteFilePath);
        File f = new File(localFilePath);
        /*****start*****/
        /*在此添加判断文件是否存在的代码,如果文件名存在,自动重命名(在文件名后面加上 _0, _1 ...) */
        if (f.exists()) {
            System.out.println(localFilePath + " 已存在.");
            Integer i = 0;
            while (  true) {
                f = new File(  localFilePath + "_" + i.toString()     );
                if (!f.exists()  ) {
                    localFilePath = localFilePath + "_" + i.toString()      ;
                    break;
                }
            }
            System.out.println("将重新命名为: " + localFilePath);
        }

        /*****end*****/

        /*****start*****/
        // 在此添加将文件下载到本地的代码

        Path localPath = new Path(localFilePath);   
        fs.copyToLocalFile(remotePath, localPath);

       /*****end*****/
       fs.close();
    }

    /**
     * 主函数
     */
    public static void main(String[] args)throws IOException {
        Configuration conf = new Configuration();
        createHDFSFile(conf);
        String localFilePath = "/tmp/output/text.txt";    // 本地路径
        String remoteFilePath = "/user/hadoop/text.txt";    // HDFS路径

        try {
            //调用方法下载文件至本地
            hdfs.copyToLocal(conf, remoteFilePath, localFilePath);
            System.out.println("下载完成");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //创建HDFS文件
    public static void createHDFSFile(Configuration conf)throws IOException{
        FileSystem fs = FileSystem.get(conf);  //获取文件系统
        Path file = new Path("/user/hadoop/text.txt");        //创建文件   
        FSDataOutputStream outStream = fs.create(file); //获取输出流
        outStream.writeUTF("hello hadoop HDFS www.educoder.net");
        outStream.close();
        fs.close();
    }
}

评测
在这里插入图片描述

4、第4关:HDFS Java API编程 ——使用字符流读取数据

在这里插入图片描述

import java.io.*;
import java.sql.Date;
import java.util.Scanner;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

public class hdfs {
 /**
     * 读取文件内容
     */
    public static void cat(Configuration conf, String remoteFilePath) throws IOException {

        /*****start*****/
        //1.读取文件中的数据
        Path remotePath = new Path(remoteFilePath); 
        FileSystem fs = FileSystem.get(conf); 
        FSDataInputStream in = fs.open(remotePath); 
        BufferedReader d = new BufferedReader(new InputStreamReader(in));      
        String line = null; 
        StringBuffer buffer = new StringBuffer();
        while ((line = d.readLine()) != null) 
        { buffer.append(line); } 
        String res = buffer.toString();

        //2.将读取到的数据输出到  /tmp/output/text.txt 文件中  提示:可以使用FileWriter

        FileWriter f1=new FileWriter("/tmp/output/text.txt");
        f1.write(res);
        f1.close();
       /*****end*****/
    }

    /**
     * 主函数
     */
    public static void main(String[] args)throws IOException {
        Configuration conf = new Configuration();
        createHDFSFile(conf);
        String remoteFilePath = "/user/hadoop/text.txt";    // HDFS路径

        try {
            System.out.println("读取文件: " + remoteFilePath);
            hdfs.cat(conf, remoteFilePath);
            System.out.println("\n读取完成");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //创建HDFS文件
    public static void createHDFSFile(Configuration conf)throws IOException{
        FileSystem fs = FileSystem.get(conf);  //获取文件系统
        Path file = new Path("/user/hadoop/text.txt");        //创建文件   
        FSDataOutputStream outStream = fs.create(file); //获取输出流
        outStream.writeUTF("hello hadoop HDFS step4 www.educoder.net");
        outStream.close();
        fs.close();
    }
}

评测
在这里插入图片描述

5、第5关:HDFS Java API编程 ——删除文件

在这里插入图片描述

import java.io.*;
import java.sql.Date;
import java.util.Scanner;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;

public class hdfs {
     /**
     * 删除文件 
     */
    public static boolean rm(Configuration conf, String remoteFilePath) throws IOException {
        /*****start*****/        
        //请在此添加删除文件的代码
        FileSystem fs = FileSystem.get(conf);
        Path remotePath = new Path(remoteFilePath);
        boolean result = fs.delete(remotePath,false);

        return   true    ;
        /*****end*****/
    }

    /**
     * 主函数
     */
    public static void main(String[] args) {
        Configuration conf = new Configuration();
        String remoteFilePath = "/user/hadoop/text.txt";    // HDFS文件

        try {
            if (rm(conf, remoteFilePath) ) {
                System.out.println("文件删除: " + remoteFilePath);
            } else {
                System.out.println("操作失败(文件不存在或删除失败)");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

评测
在这里插入图片描述

6、第6关:HDFS Java API编程 ——删除文件夹

在这里插入图片描述

import java.io.*;
import java.sql.Date;
import java.util.Scanner;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.*;

public class hdfs {
        /**
     * 判断目录是否为空
     * true: 空,false: 非空
     */
    public static boolean isDirEmpty(Configuration conf, String remoteDir) throws IOException {
        FileSystem fs = FileSystem.get(conf);
        Path dirPath = new Path(remoteDir);
        RemoteIterator<LocatedFileStatus> remoteIterator = fs.listFiles(dirPath, true);
        return !remoteIterator.hasNext();
    }
    /**
     * 删除目录
     */
    public static boolean rmDir(Configuration conf, String remoteDir, boolean recursive) throws IOException {
        FileSystem fs = FileSystem.get(conf);
        Path dirPath = new Path(remoteDir);
        /* 第二个参数表示是否递归删除所有文件 */
        boolean result = fs.delete(dirPath, recursive);
        fs.close();
        return result;
    }
    /**
     * 主函数
     */
    public static void main(String[] args) {
        Configuration conf = new Configuration();
        String remoteDir = "/user/hadoop/dir/";    // HDFS目录
        String remoteDir1 = "/user/hadoop/tmp/";    // HDFS目录
        Boolean forceDelete = false;  // 是否强制删除

        try {
            if ( !isDirEmpty(conf, remoteDir) && !forceDelete ) {
                System.out.println("目录不为空,不删除");
            } else {
               if ( rmDir(conf, remoteDir, forceDelete) ) {
                    System.out.println("目录已删除: " + remoteDir);
               } else {
                    System.out.println("操作失败");
               }
            }

            if ( !isDirEmpty(conf, remoteDir1) && !forceDelete ) {
                System.out.println("目录不为空,不删除");
            } else {
                if ( rmDir(conf, remoteDir1, forceDelete) ) {
                    System.out.println("目录已删除: " + remoteDir1);
                } else {
                    System.out.println("操作失败");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
       }
    }
}

评测
在这里插入图片描述

7、第7关:HDFS Java API编程 ——自定义数据输入流

在这里插入图片描述

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import java.io.*;

public class MyFSDataInputStream extends FSDataInputStream {
    public MyFSDataInputStream(InputStream in) {
        super(in);
    }

   /**
    * 实现按行读取     * 每次读入一个字符,遇到"\n"结束,返回一行内容
     */
    public static String readline(BufferedReader br) throws IOException {
        char[] data = new char[1024];
        int read = -1;
        int off = 0; // 循环执行时,br 每次会从上一次读取结束的位置继续读取,因此该函数里,off 每次都从0开始
        while ( (read = br.read(data, off, 1)) != -1 ) {
            if (String.valueOf(data[off]).equals("\n") ) {
                off += 1;
                return String.valueOf(data, 0, read);
            }
            off += 1;
            return String.valueOf(data, 0, read);
        }
        return null;
    }
    /**
     * 读取文件内容
     */
    public static void cat(Configuration conf, String remoteFilePath) throws IOException {
        FileSystem fs = FileSystem.get(conf);
        Path remotePath = new Path(remoteFilePath);
        FSDataInputStream in = fs.open(remotePath);
        BufferedReader br = new BufferedReader(new InputStreamReader(in));
        FileWriter f = new FileWriter("/tmp/output/text.txt");
        String line = null;
        while ( (line = MyFSDataInputStream.readline(br)) != null ) {
            f.write(line);
        }
        f.close();
        br.close();
        in.close();
        fs.close();
    }
    /**
   * 主函数
     */
    public static void main(String[] args) {
        Configuration conf = new Configuration();
       String remoteFilePath = "/user/hadoop/text.txt";    // HDFS路径
       try {
           MyFSDataInputStream.cat(conf, remoteFilePath);
       } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

评测
在这里插入图片描述

Ending!
更多课程知识学习记录随后再来吧!

就酱,嘎啦!

在这里插入图片描述

注:
人生在勤,不索何获。

  • 35
    点赞
  • 99
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 4
    评论
### 回答1: 头歌大数据入门实战 - 第2章 分布式文件系统hdfs 分布式文件系统HDFS是Apache Hadoop的核心组件之一,它是一个可扩展的、高可靠性的分布式文件系统,适用于大规模数据存储和处理。HDFS的设计目标是能够在廉价的硬件上运行,并且能够处理大量的数据。HDFS采用了主从架构,其中有一个NameNode负责管理文件系统的命名空间和客户端的访问,而多个DataNode负责存储实际的数据块。HDFS的数据块大小通常为128MB,这样可以减少寻道时间,提高数据读写效率。HDFS还提供了数据冗余机制,通过多个副本来保证数据的可靠性和高可用性。HDFS应用场景非常广泛,包括数据仓库、日志分析、机器学习等领域。 ### 回答2: 分布式文件系统(hdfs)在大数据处理中扮演着非常重要的角色,本文将以“头歌大数据入门实战”的第二章为基础,分享一些本人的看法和学习体会。 首先,为什么需要分布式文件系统? 在大数据处理中,数据量很大,单机存储和处理是非常困难的,因此需要将数据存储到多个机器上,并且通过网络互相传递进行处理和计算,这就需要一种分布式文件系统来解决。分布式文件系统可以将数据分布到多个节点上,使得每个节点上处理的数据量相对较小,从而降低了单节点的存储和处理压力。 具体而言,hdfs是如何实现分布式文件系统的呢? hdfs的核心组成部分是namenode和datanode。namenode负责管理文件系统的命名空间和客户端访问数据的控制,datanode则负责实际存储数据和处理读写请求。其中,namenode具有高可靠性,因为它存储了整个文件系统的关键数据,如果出现故障,将会对整个文件系统造成影响。因此,为了保证namenode的高可用性,通常会使用hadoop的另外一个子系统,即hadoop HA(High Availability)。 此外,在hdfs中,还提供了数据块(block)的概念,每个数据块的大小默认为128MB。hdfs中的大文件会自动被分为多个数据块存储在不同的datanode上,这些数据块之间的复制也可以由hdfs自动完成。在hdfs中,副本的存储策略和副本数量可以由管理员进行配置,首次存储数据时,可以指定数据块的复制因子,副本在hdfs集群中具有很好的容错性,即使某个datanode发生故障,也可以从其他datanode上获取副本,从而保证了数据的可靠性和一致性。 最后,对于初学者而言,在学习hdfs的时候,需要先了解hdfs的基本组成和特性,再通过具体的实践和案例去深入学习和了解。在hdfs的使用过程中,需要注意一些具体的细节,例如文件的存储路径、权限设置、读写方式、数据复制等,都会对hdfs的性能和可靠性产生影响,需要认真细致地进行调试和优化。 总之,分布式文件系统在大数据处理中是非常重要的一环,hdfs作为其中的代表产品,具有很好的可扩展性、高可靠性和容错性,被广泛应用大数据领域。学习hdfs需要注重基础知识的学习和实际练习的结合,全面深入地理解hdfs的原理和实现,从而能够更好地进行大数据处理和应用。 ### 回答3: 分布式文件系统HDFS是Apache Hadoop的核心组件之一,是一种适用于存储大量数据的分布式文件系统。该系统通过横向扩展,将大量的数据分散存储在多台计算机上,旨在提高数据的可靠性和可扩展性。 HDFS是由两个核心组件组成的:NameNode和DataNode。NameNode是HDFS的主节点,主要负责管理文件系统的命名空间和权限控制。它维护着整个文件系统的元数据信息,包括文件的名称、块的位置、副本数量等。DataNode是HDFS的数据节点,主要负责存储实际的数据块。在HDFS中,文件会被划分为一个个的块,并将每个块的多个副本分散存储在多台机器上,以确保数据的可靠性和高可用性。 HDFS还提供了一些重要的特性,例如数据的自动副本备份机制、故障转移系统、数据块的迁移和压缩等。这些特性可以帮助用户轻松地管理大规模的数据,从而降低存储和维护成本。 为了更好地理解HDFS的工作原理,用户需要学习Hadoop中的文件读写操作。针对文件的读操作主要分为两个阶段:第一阶段是客户端向NameNode查询文件的元数据信息,包括所有数据块的位置和大小;第二阶段是客户端根据元数据信息向对应的DataNode获取数据块,并将数据合并还原为一个完整的文件。文件的写操作大致分为三个步骤:首先,客户端向NameNode申请创建一个新的文件,并分配空间;其次,客户端向一个或多个DataNode写入数据;最后,客户端通知NameNode文件写入完成,NameNode更新文件系统中该文件的元数据信息。 总之,分布式文件系统HDFS大数据领域扮演着至关重要的角色,它能够协助用户轻松处理大规模的数据,降低存储和维护成本,提高数据的可靠性和可扩展性,具有重要的发展前景和应用价值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

发芽ing的小啊呜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值