2.1.7 hadoop体系之离线计算-hdfs分布式文件系统-hdfs命令行使用和API操作

叁歲伎倆 2022-12-11 11:22 279阅读 0赞

目录

1.hdfs命令行使用

2 在window配置hadoop运行环境

3.HDFS 的 API 操作

3.1 导入Maven依赖

3.2 概述

3.3 获取FileSystem的几种方式

3.4 遍历 HDFS 中所有文件

3.4.1 递归遍历

3.4.2 使用 API 遍历

3.5 下载文件到本地

3.6 HDFS 上创建文件夹

3.7 HDFS 文件上传

3.8 权限管理和伪造root用户

3.9 小文件合并


1.hdfs命令行使用

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1N1eWViaXViaXU_size_16_color_FFFFFF_t_70

2 在window配置hadoop运行环境

(1)将apache-hadoop-3.1.1文件拷贝到一个没有中文没有空格的路径下面

(2)在windows上面配置hadoop的环境变量:HADOOP_HOME,并且把bin添加到path中

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L1N1eWViaXViaXU_size_16_color_FFFFFF_t_70 1

20200930113724296.png

(3)把bin目录下的hadoop.dll文件放到系统盘里面去:c:\\Windows\System32

(4)关闭windows重启

3.HDFS 的 API 操作

3.1 导入Maven依赖

  1. <repositories>
  2. <repository>
  3. <id>cloudera</id>
  4. <url>https://repository.cloudera.com/artifactory/cloudera-repos/</url>
  5. </repository>
  6. </repositories>
  7. <dependencies>
  8. <dependency>
  9. <groupId>jdk.tools</groupId>
  10. <artifactId>jdk.tools</artifactId>
  11. <version>1.8</version>
  12. <scope>system</scope>
  13. <systemPath>${JAVA_HOME}/lib/tools.jar</systemPath>
  14. </dependency>
  15. <dependency>
  16. <groupId>org.apache.hadoop</groupId>
  17. <artifactId>hadoop-common</artifactId>
  18. <version>3.0.0</version>
  19. <scope>provided</scope>
  20. </dependency>
  21. <dependency>
  22. <groupId>org.apache.hadoop</groupId>
  23. <artifactId>hadoop-hdfs</artifactId>
  24. <version>3.0.0</version>
  25. </dependency>
  26. <dependency>
  27. <groupId>org.apache.hadoop</groupId>
  28. <artifactId>hadoop-hdfs-client</artifactId>
  29. <version>3.0.0</version>
  30. <scope>provided</scope>
  31. </dependency>
  32. <dependency>
  33. <groupId>org.apache.hadoop</groupId>
  34. <artifactId>hadoop-client</artifactId>
  35. <version>3.0.0</version>
  36. </dependency>
  37. <dependency>
  38. <groupId>junit</groupId>
  39. <artifactId>junit</artifactId>
  40. <version>4.12</version>
  41. <scope>test</scope>
  42. </dependency>
  43. </dependencies>

3.2 概述

在 Java 中操作 HDFS, 主要涉及以下 Class:

  • Configuration

    • 该类的对象封转了客户端或者服务器的配置
  • FileSystem

    • 该类的对象是一个文件系统对象, 可以用该对象的一些方法来对文件进行操作, 通过 FileSystem 的静态方法 get 获得该对象

      1. FileSystem fs = FileSystem.get(conf)
      • get 方法从 conf 中的一个参数 fs.defaultFS 的配置值判断具体是什么类型的文件系统
      • 如果我们的代码中没有指定 fs.defaultFS, 并且工程 ClassPath 下也没有给定相应的配置, conf 中的默认值就来自于 Hadoop 的 Jar 包中的 core-default.xml
      • 默认值为 file:///, 则获取的不是一个 DistributedFileSystem 的实例, 而是一个本地文件系统的客户端对象

3.3 获取FileSystem的几种方式

  • 第一种方式

    @Test
    public void getFileSystem() throws URISyntaxException, IOException {

    1. Configuration configuration = new Configuration();
    2. FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.52.250:8020"), configuration);
    3. System.out.println(fileSystem.toString());

    }

  • 第二种方式

    @Test
    public void getFileSystem2() throws URISyntaxException, IOException {

    1. Configuration configuration = new Configuration();
    2. configuration.set("fs.defaultFS","hdfs://192.168.52.250:8020");
    3. FileSystem fileSystem = FileSystem.get(new URI("/"), configuration);
    4. System.out.println(fileSystem.toString());

    }

  • 第三种方式

    @Test
    public void getFileSystem3() throws URISyntaxException, IOException {

    1. Configuration configuration = new Configuration();
    2. FileSystem fileSystem = FileSystem.newInstance(new URI("hdfs://192.168.52.250:8020"), configuration);
    3. System.out.println(fileSystem.toString());

    }

  • 第四种方式

    @Test
    public void getFileSystem4() throws Exception{

    1. Configuration configuration = new Configuration();
    2. configuration.set("fs.defaultFS","hdfs://192.168.52.250:8020");
    3. FileSystem fileSystem = FileSystem.newInstance(configuration);
    4. System.out.println(fileSystem.toString());

    }

3.4 遍历 HDFS 中所有文件

3.4.1 递归遍历

  1. @Test
  2. public void listFile() throws Exception{
  3. FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.52.100:8020"), new Configuration());
  4. FileStatus[] fileStatuses = fileSystem.listStatus(new Path("/"));
  5. for (FileStatus fileStatus : fileStatuses) {
  6. if(fileStatus.isDirectory()){
  7. Path path = fileStatus.getPath();
  8. listAllFiles(fileSystem,path);
  9. }else{
  10. System.out.println("文件路径为"+fileStatus.getPath().toString());
  11. }
  12. }
  13. }
  14. public void listAllFiles(FileSystem fileSystem,Path path) throws Exception{
  15. FileStatus[] fileStatuses = fileSystem.listStatus(path);
  16. for (FileStatus fileStatus : fileStatuses) {
  17. if(fileStatus.isDirectory()){
  18. listAllFiles(fileSystem,fileStatus.getPath());
  19. }else{
  20. Path path1 = fileStatus.getPath();
  21. System.out.println("文件路径为"+path1);
  22. }
  23. }
  24. }

3.4.2 使用 API 遍历

  1. @Test
  2. public void listMyFiles()throws Exception{
  3. //获取fileSystem类
  4. FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.52.250:8020"), new Configuration());
  5. //获取RemoteIterator 得到所有的文件或者文件夹,第一个参数指定遍历的路径,第二个参数表示是否要递归遍历
  6. RemoteIterator<LocatedFileStatus> locatedFileStatusRemoteIterator = fileSystem.listFiles(new Path("/"), true);
  7. while (locatedFileStatusRemoteIterator.hasNext()){
  8. LocatedFileStatus next = locatedFileStatusRemoteIterator.next();
  9. System.out.println(next.getPath().toString());
  10. }
  11. fileSystem.close();
  12. }

3.5 下载文件到本地

  1. @Test
  2. public void getFileToLocal()throws Exception{
  3. FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.52.250:8020"), new Configuration());
  4. FSDataInputStream open = fileSystem.open(new Path("/test/input/install.log"));
  5. FileOutputStream fileOutputStream = new FileOutputStream(new File("c:\\install.log"));
  6. IOUtils.copy(open,fileOutputStream );
  7. IOUtils.closeQuietly(open);
  8. IOUtils.closeQuietly(fileOutputStream);
  9. fileSystem.close();
  10. }

3.6 HDFS 上创建文件夹

  1. @Test
  2. public void mkdirs() throws Exception{
  3. FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.52.250:8020"), new Configuration());
  4. boolean mkdirs = fileSystem.mkdirs(new Path("/hello/mydir/test"));
  5. fileSystem.close();
  6. }

3.7 HDFS 文件上传

  1. @Test
  2. public void putData() throws Exception{
  3. FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.52.250:8020"), new Configuration());
  4. fileSystem.copyFromLocalFile(new Path("file:///c:\\install.log"),new Path("/hello/mydir/test"));
  5. fileSystem.close();
  6. }

3.8 权限管理和伪造root用户

  • 停止hdfs集群,在node01机器上执行以下命令
  • cd /export/servers/hadoop-3.1.1
    sbin/stop-dfs.sh
  • 修改node01机器上的hdfs-site.xml当中的配置文件
  • cd /export/servers/hadoop-3.1.1/etc/hadoop
    vim hdfs-site.xml


    dfs.permissions.enabled
    true
  • 修改完成之后配置文件发送到其他机器上面去
  • scp hdfs-site.xml node02:$PWD
    scp hdfs-site.xml node03:$PWD
  • 重启hdfs集群
  • cd /export/servers/hadoop-3.1.1
    sbin/start-dfs.sh
  • 随意上传一些文件到我们hadoop集群当中准备测试使用
  • cd /export/servers/hadoop-3.1.1/etc/hadoop
    hdfs dfs -mkdir /config
    hdfs dfs -put *.xml /config
    hdfs dfs -chmod 600 /config/core-site.xml
  • 使用代码准备下载文件
  • @Test
    public void getConfig()throws Exception{
    1. FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.52.250:8020"), new Configuration(),"hadoop");
    2. fileSystem.copyToLocalFile(new Path("/config/core-site.xml"),new Path("file:///c:/core-site.xml"));
    3. fileSystem.close();
    }

3.9 小文件合并

由于 Hadoop 擅长存储大文件,因为大文件的元数据信息比较少,如果 Hadoop 集群当中有大量的小文件,那么每个小文件都需要维护一份元数据信息,会大大的增加集群管理元数据的内存压力,所以在实际工作当中,如果有必要一定要将小文件合并成大文件进行一起处理

在我们的 HDFS 的 Shell 命令模式下,可以通过命令行将很多的 hdfs 文件合并成一个大文件下载到本地

  1. cd /export/servers
  2. hdfs dfs -getmerge /config/*.xml ./hello.xml

既然可以在下载的时候将这些小文件合并成一个大文件一起下载,那么肯定就可以在上传的时候将小文件合并到一个大文件里面去

  1. @Test
  2. public void mergeFile() throws Exception{
  3. //获取分布式文件系统
  4. FileSystem fileSystem = FileSystem.get(new URI("hdfs://192.168.52.250:8020"), new Configuration(),"hadoop");
  5. FSDataOutputStream outputStream = fileSystem.create(new Path("/bigfile.xml"));
  6. //获取本地文件系统
  7. LocalFileSystem local = FileSystem.getLocal(new Configuration());
  8. //通过本地文件系统获取文件列表,为一个集合
  9. FileStatus[] fileStatuses = local.listStatus(new Path("file:///F:\\大数据离线阶段课程资料\\3、大数据离线第三天\\上传小文件合并"));
  10. for (FileStatus fileStatus : fileStatuses) {
  11. FSDataInputStream inputStream = local.open(fileStatus.getPath());
  12. IOUtils.copy(inputStream,outputStream);
  13. IOUtils.closeQuietly(inputStream);
  14. }
  15. IOUtils.closeQuietly(outputStream);
  16. local.close();
  17. fileSystem.close();
  18. }

发表评论

表情:
评论列表 (有 0 条评论,279人围观)

还没有评论,来说两句吧...

相关阅读