• Hadoop基础-HDFS的API实现增删改查


                       Hadoop基础-HDFS的API实现增删改查

                                          作者:尹正杰

    版权声明:原创作品,谢绝转载!否则将追究法律责任。

      本篇博客开发IDE使用的是Idea,如果没有安装Idea软件的可以去下载安装,如何安装IDE可以参考我的笔记:https://www.cnblogs.com/yinzhengjie/p/9080387.html。当然如果有小伙伴已经有自己使用习惯的IDE就不用更换了,只是配置好相应的Maven即可,我这里配置Maven是针对idea界面进行说明的。

    一.将模块添加maven框架支持

    1>.点击"Add Frameworks Support"

     

    2>.添加Maven框架的支持

     

    3>.在pom.xml中添加以下依赖关系

     

    4>.启用自动导入

     

    5>.等待下载完成

     

    6>.手动刷新Maven项目

     

     

    二.将Linux服务器端的HDFS文件到项目中的resources目录

    1>.查看服务端配置文件

     [yinzhengjie@s101 ~]$ more /soft/hadoop/etc/hadoop/core-site.xml 
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    <property>
    <name>fs.defaultFS</name>
    <value>hdfs://s101:8020</value>
    </property>
    <property>
    <name>hadoop.tmp.dir</name>
    <value>/home/yinzhengjie/hadoop</value>
    </property>
    </configuration>
    
    <!--
    
    core-site.xml配置文件的作用:
    用于定义系统级别的参数,如HDFS URL、Hadoop的临时
    目录以及用于rack-aware集群中的配置文件的配置等,此中的参
    数定义会覆盖core-default.xml文件中的默认配置。
    
    fs.defaultFS 参数的作用:
    #声明namenode的地址,相当于声明hdfs文件系统。
    
    hadoop.tmp.dir 参数的作用:
    #声明hadoop工作目录的地址。
    
    -->
    [yinzhengjie@s101 ~]$ sz /soft/hadoop/etc/hadoop/core-site.xml 
    rz
    zmodem trl+C ȡ
    
    100% 850 bytes 85 bytes/s 00:00:10 0 Errors
    
    [yinzhengjie@s101 ~]$ 

    2>.将下载的文件拷贝到项目中resources目录下

     

    3>.查看下载的core-site.xml 文件内容

    三.HDFS的API实现增删改查

      1 /*
      2 @author :yinzhengjie
      3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
      4 EMAIL:y1053419035@qq.com
      5 */
      6 package cn.org.yinzhengjie.day01.note1;
      7 
      8 import org.apache.hadoop.conf.Configuration;
      9 import org.apache.hadoop.fs.FSDataInputStream;
     10 import org.apache.hadoop.fs.FSDataOutputStream;
     11 import org.apache.hadoop.fs.FileSystem;
     12 import org.apache.hadoop.fs.Path;
     13 import java.io.IOException;
     14 
     15 public class HdfsDemo {
     16     public static void main(String[] args) throws IOException {
     17         insert();
     18         update();
     19         read();
     20         delete();
     21     }
     22 
     23     //删除文件
     24     private static void delete() throws IOException {
     25         //由于我的Hadoop完全分布式根目录对yinzhengjie以外的用户(尽管是root用户也没有写入权限哟!因为是hdfs系统,并非Linux系统!)没有写入
     26         // 权限,所以需要手动指定当前用户权限。使用“HADOOP_USER_NAME”属性就可以轻松搞定!
     27         System.setProperty("HADOOP_USER_NAME","yinzhengjie");
     28         //实例化一个Configuration,它会自动去加载本地的core-site.xml配置文件的fs.defaultFS属性。(该文件放在项目的resources目录即可。)
     29         Configuration conf = new Configuration();
     30         //代码的入口点,初始化HDFS文件系统,此时我们需要把读取到的fs.defaultFS属性传给fs对象。
     31         FileSystem fs = FileSystem.get(conf);
     32         //这个path是指是需要在文件系统中写入的数据,里面的字符串可以写出“hdfs://s101:8020/yinzhengjie.sql”,但由于core-site.xml配置
     33         // 文件中已经有“hdfs://s101:8020”字样的前缀,因此我们这里可以直接写文件名称
     34         Path path = new Path("/yinzhengjie.sql");
     35         //通过fs的delete方法可以删除文件,第一个参数指的是删除文件对象,第二参数是指递归删除,一般用作删除目录
     36         boolean res = fs.delete(path, true);
     37         if (res == true){
     38             System.out.println("====================");
     39             System.out.println(path + "文件删除成功!");
     40             System.out.println("====================");
     41         }
     42         //释放资源
     43         fs.close();
     44     }
     45 
     46     //将数据追加到文件内容中
     47     private static void update() throws IOException {
     48         //由于我的Hadoop完全分布式根目录对yinzhengjie以外的用户(尽管是root用户也没有写入权限哟!因为是hdfs系统,并非Linux系统!)没有写入
     49         // 权限,所以需要手动指定当前用户权限。使用“HADOOP_USER_NAME”属性就可以轻松搞定!
     50         System.setProperty("HADOOP_USER_NAME","yinzhengjie");
     51 
     52         //实例化一个Configuration,它会自动去加载本地的core-site.xml配置文件的fs.defaultFS属性。(该文件放在项目的resources目录即可。)
     53         Configuration conf = new Configuration();
     54         //代码的入口点,初始化HDFS文件系统,此时我们需要把读取到的fs.defaultFS属性传给fs对象。
     55         FileSystem fs = FileSystem.get(conf);
     56         //这个path是指是需要在文件系统中写入的数据,里面的字符串可以写出“hdfs://s101:8020/yinzhengjie.sql”,但由于core-site.xml配置
     57         // 文件中已经有“hdfs://s101:8020”字样的前缀,因此我们这里可以直接写文件名称
     58         Path path = new Path("/yinzhengjie.sql");
     59         //通过fs的append方法实现对文件的追加操作
     60         FSDataOutputStream fos = fs.append(path);
     61         //通过fos写入数据
     62         fos.write("
    yinzhengjie".getBytes());
     63         //释放资源
     64         fos.close();
     65         fs.close();
     66 
     67     }
     68 
     69     //将数据写入HDFS文件系统
     70     private static void insert() throws IOException {
     71        //由于我的Hadoop完全分布式根目录对yinzhengjie以外的用户(尽管是root用户也没有写入权限哟!因为是hdfs系统,并非Linux系统!)没有写入
     72         // 权限,所以需要手动指定当前用户权限。使用“HADOOP_USER_NAME”属性就可以轻松搞定!
     73         System.setProperty("HADOOP_USER_NAME","yinzhengjie");
     74 
     75         //实例化一个Configuration,它会自动去加载本地的core-site.xml配置文件的fs.defaultFS属性。(该文件放在项目的resources目录即可。)
     76         Configuration conf = new Configuration();
     77         //代码的入口点,初始化HDFS文件系统,此时我们需要把读取到的fs.defaultFS属性传给fs对象。
     78         FileSystem fs = FileSystem.get(conf);
     79         //这个path是指是需要在文件系统中写入的数据,里面的字符串可以写出“hdfs://s101:8020/yinzhengjie.sql”,但由于core-site.xml配置
     80         // 文件中已经有“hdfs://s101:8020”字样的前缀,因此我们这里可以直接写文件名称
     81         Path path = new Path("/yinzhengjie.sql");
     82         //通过fs的create方法创建一个文件输出对象,第一个参数是hdfs的系统路径,第二个参数是判断第一个参数(也就是文件系统的路径)是否存在,如果存在就覆盖!
     83         FSDataOutputStream fos = fs.create(path,true);
     84         //通过fos写入数据
     85         fos.writeUTF("尹正杰");
     86         //释放资源
     87         fos.close();
     88         fs.close();
     89     }
     90 
     91     //在HDFS文件系统中读取数据
     92     private static void read() throws IOException {
     93         //实例化一个Configuration,它会自动去加载本地的core-site.xml配置文件的fs.defaultFS属性。(该文件放在项目的resources目录即可。)
     94         Configuration conf = new Configuration();
     95         //代码的入口点,初始化HDFS文件系统,此时我们需要把读取到的fs.defaultFS属性传给fs对象。
     96         FileSystem fs = FileSystem.get(conf);
     97         //这个path是指NameNode中的HDFS分布式系统中的路径映射(注意,我这里写的是主机名,你可以写IP,如果是测试环境的话需要在hosts文件中添加主机名映射哟!)
     98         Path path = new Path("hdfs://s101:8020/yinzhengjie.sql");
     99         //通过fs读取数据
    100         FSDataInputStream fis = fs.open(path);
    101         int len = 0;
    102         byte[] buf = new byte[4096];
    103         while ((len = fis.read(buf)) != -1){
    104             System.out.println(new String(buf, 0, len));
    105         }
    106     }
    107 }
    108 
    109 
    110 /*
    111 以上代码执行结果如下:
    112      尹正杰
    113 yinzhengjie
    114 ====================
    115 /yinzhengjie.sql文件删除成功!
    116 ====================
    117  */

    四.HDFS的API实现文件拷贝(不需要我们自己实现数据流的拷贝,而是使用Hadoop自带的IOUtils类实现)

     1 /*
     2 @author :yinzhengjie
     3 Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
     4 EMAIL:y1053419035@qq.com
     5 */
     6 package cn.org.yinzhengjie.day01.note1;
     7 
     8 import org.apache.hadoop.conf.Configuration;
     9 import org.apache.hadoop.fs.FSDataInputStream;
    10 import org.apache.hadoop.fs.FileSystem;
    11 import org.apache.hadoop.fs.Path;
    12 import org.apache.hadoop.io.IOUtils;
    13 
    14 import java.io.FileOutputStream;
    15 import java.io.IOException;
    16 
    17 public class HdfsDemo1 {
    18     public static void main(String[] args) throws IOException {
    19         get();
    20     }
    21 
    22     //定义方法下载文件到本地
    23     private static void get() throws IOException {
    24         //由于我的Hadoop完全分布式根目录对yinzhengjie以外的用户(尽管是root用户也没有写入权限哟!因为是hdfs系统,并非Linux系统!)没有写入
    25         // 权限,所以需要手动指定当前用户权限。使用“HADOOP_USER_NAME”属性就可以轻松搞定!
    26         System.setProperty("HADOOP_USER_NAME","yinzhengjie");
    27         //实例化一个Configuration,它会自动去加载本地的core-site.xml配置文件的fs.defaultFS属性。(该文件放在项目的resources目录即可。)
    28         Configuration conf = new Configuration();
    29         //代码的入口点,初始化HDFS文件系统,此时我们需要把读取到的fs.defaultFS属性传给fs对象。
    30         FileSystem fs = FileSystem.get(conf);
    31         //这个path是指是需要在文件系统中写入的数据,里面的字符串可以写出“hdfs://s101:8020/xrsync.sh”,但由于core-site.xml配置
    32         // 文件中已经有“hdfs://s101:8020”字样的前缀,因此我们这里可以直接写相对路径
    33         Path path = new Path("/xrsync.sh");
    34         //通过fs的open方法获取一个对象输入流
    35         FSDataInputStream fis = fs.open(path);
    36         //创建一个对象输出流
    37         FileOutputStream fos = new FileOutputStream("yinzhengjie.sql");
    38         //通过Hadoop提供的IOUtiles工具类的copyBytes方法拷贝数据,第一个参数是需要传一个输入流,第二个参数需要传入一个输出流,第三个指定传输数据的缓冲区大小。
    39         IOUtils.copyBytes(fis,fos,4096);
    40         System.out.println("文件拷贝成功!");
    41         //别忘了释放资源哟
    42         fis.close();
    43         fos.close();
    44         fs.close();
    45     }
    46 }
    47 
    48 /*
    49 以上代码执行结果如下:
    50 文件拷贝成功!
    51  */

    五.自定义块大小写入文件

      配置Hadoop的最小blocksize,必须是512的倍数,有可能你会问为什么要设置大小是512的倍数呢?因为hdfs在写入的过程中会进行校验,每512字节进行依次校验,因此需要设置是512的倍数。编辑“hdfs-site.xml”配置文件。

    1>.服务器端hdfs的配置文件,修改默认的块大小,默认块大小是1048576字节,我们手动改为1024字节,配合过程如下:(别忘记重启服务,修改配置文件一般都是需要重启服务的哟)

    [yinzhengjie@s101 ~]$ more `which xrsync.sh`
    #!/bin/bash
    #@author :yinzhengjie
    #blog:http://www.cnblogs.com/yinzhengjie
    #EMAIL:y1053419035@qq.com
    
    #判断用户是否传参
    if [ $# -lt 1 ];then
            echo "请输入参数";
            exit
    fi
    
    
    #获取文件路径
    file=$@
    
    #获取子路径
    filename=`basename $file`
    
    #获取父路径
    dirpath=`dirname $file`
    
    #获取完整路径
    cd $dirpath
    fullpath=`pwd -P`
    
    #同步文件到DataNode
    for (( i=102;i<=104;i++ ))
    do
            #使终端变绿色 
            tput setaf 2
            echo =========== s$i %file ===========
            #使终端变回原来的颜色,即白灰色
            tput setaf 7
            #远程执行命令
            rsync -lr $filename `whoami`@s$i:$fullpath
            #判断命令是否执行成功
            if [ $? == 0 ];then
                    echo "命令执行成功"
            fi
    done
    [yinzhengjie@s101 ~]$ 
    [yinzhengjie@s101 ~]$ more /soft/hadoop/etc/hadoop/hdfs-site.xml 
    <?xml version="1.0" encoding="UTF-8"?>
    <?xml-stylesheet type="text/xsl" href="configuration.xsl"?>
    <configuration>
            <property>
                    <name>dfs.replication</name>
                    <value>3</value>
            </property>
            <property>
                    <name>dfs.namenode.fs-limits.min-block-size</name>
                    <value>1024</value>
            </property>
    </configuration>
    
    <!--
    hdfs-site.xml 配置文件的作用:
            #HDFS的相关设定,如文件副本的个数、块大小及是否使用强制权限
    等,此中的参数定义会覆盖hdfs-default.xml文件中的默认配置.
    
    dfs.replication 参数的作用:
            #为了数据可用性及冗余的目的,HDFS会在多个节点上保存同一个数据
    块的多个副本,其默认为3个。而只有一个节点的伪分布式环境中其仅用
    保存一个副本即可,这可以通过dfs.replication属性进行定义。它是一个
    软件级备份。

    dfs.namenode.fs-limits.min-block-size 参数的作用:
      #该参数是用指定hdfs最小块存储设置
    --> [yinzhengjie@s101 ~]$ xrsync.sh /soft/hadoop/etc/full/hdfs-site.xml =========== s102 %file =========== 命令执行成功 =========== s103 %file =========== 命令执行成功 =========== s104 %file =========== 命令执行成功 [yinzhengjie@s101 ~]$

    2>.客户端编写API代码如下

    /*
    @author :yinzhengjie
    Blog:http://www.cnblogs.com/yinzhengjie/tag/Hadoop%E8%BF%9B%E9%98%B6%E4%B9%8B%E8%B7%AF/
    EMAIL:y1053419035@qq.com
    */
    package cn.org.yinzhengjie.day01.note1;
    
    import org.apache.hadoop.conf.Configuration;
    import org.apache.hadoop.fs.*;
    import org.apache.hadoop.io.IOUtils;
    import java.io.FileInputStream;
    import java.io.IOException;
    
    public class HdfsDemo4 {
        public static void main(String[] args) throws IOException {
            String path = "F:/yinzhengjie.sql";
            customWrite(path);
        }
    
        //定制化写入副本数和块大小(blocksize)
        private static void customWrite(String path) throws IOException {
            //由于我的Hadoop完全分布式根目录对yinzhengjie以外的用户(尽管是root用户也没有写入权限哟!因为是hdfs系统,并非Linux系统!)没有写入
            // 权限,所以需要手动指定当前用户权限。使用“HADOOP_USER_NAME”属性就可以轻松搞定!
            System.setProperty("HADOOP_USER_NAME","yinzhengjie");
            //实例化一个Configuration,它会自动去加载本地的core-site.xml配置文件的fs.defaultFS属性。(该文件放在项目的resources目录即可。)
            Configuration conf = new Configuration();
            //代码的入口点,初始化HDFS文件系统,此时我们需要把读取到的fs.defaultFS属性传给fs对象。
            FileSystem fs = FileSystem.get(conf);
            //这个path是指是需要在文件系统中写入的数据,里面的字符串可以写出“hdfs://s101:8020/yinzhengjie.sql”,但由于core-site.xml配置文件中已经有“hdfs://s101:8020”字样的前缀,因此我们这里可以直接写相对路径
            Path hdfsPath = new Path("/yinzhengjie.sql");
            //通过fs的create方法创建一个文件输出对象,第一个参数是hdfs的系统路径,第二个参数是判断第一个参数(也就是文件系统的路径)是否存在,如果存在就覆盖!第三个参数是指定缓冲区大小,第四个参数是指定存储的副本数(规定数据类型必须为short类型),第五个参数是指定块大小。
            FSDataOutputStream fos = fs.create(hdfsPath,true,1024,(short) 8,2048);
            //创建出本地的文件输入流,也就是我们真正想要上传的文件。
            FileInputStream fis = new FileInputStream(path);
            //拷贝文件
           IOUtils.copyBytes(fis,fos,1024);
           //释放资源
            fos.close();
            fis.close();
        }
    }

    3>.客户端通过浏览器访问NameNode的WEBUI

       看完上面的信息发现和API设置的几乎一致呢,那必定得一致啊,由于块大小是2KB,而上传的文件是19.25kb,最少得10个块进行存储,我们也可以通过WEBUI来查看。

  • 相关阅读:
    git安装
    git
    运维项目维护个人总结经验
    redis基本命令
    mysql基础常用命令
    进入Linux单用户模式
    Nginx查看并发链接数
    linux编写脚本检测本机链接指定IP段是否畅通
    集体干死java 在启动.sh
    系统优化小脚本
  • 原文地址:https://www.cnblogs.com/yinzhengjie/p/9093850.html
Copyright © 2020-2023  润新知