zoukankan      html  css  js  c++  java
  • hdfs学习(三)

    HDFS 的 API 操作

    使用url方式访问数据(了解)

    @Test
        public void urlHdfs() throws IOException {
            //1.注册url
            URL.setURLStreamHandlerFactory(new FsUrlStreamHandlerFactory());
            //2.获取hdfs文件的输入流
            InputStream inputStream=new URL("hdfs://hadoop101:8020/a.txt").openStream();
            //3.获取本地文件的输出流
            OutputStream outputStream= new FileOutputStream(new File("E:\hello.txt"));
            //4.实现文件的拷贝
            IOUtils.copy(inputStream,outputStream);
            //5.关流
            IOUtils.closeQuietly(inputStream);
            IOUtils.closeQuietly(outputStream);
        }

    使用文件系统方式访问数据(掌握)

    获取 FileSystem 的几种方式

    /*
        获取FileSystem,方式1
         */
        @Test
        public void getFileSystem1() throws IOException{
            //1.创建Configuration对象
            Configuration configuration=new Configuration();
            //2.设置文件系统类型
            configuration.set("fs.defaultFS","hdfs://hadoop101:8020");
            //3.获取指定的文件系统
            FileSystem fileSystem= FileSystem.get(configuration);
            //4.输出
            System.out.println(fileSystem);
        }

    ②用的次数比较多

    /*
        获取FileSystem,方式2
        ctrl+alt+v自动补全返回值
         */
        @Test
        public void getFileSystem2() throws URISyntaxException, IOException, InterruptedException {
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop101:8020"), new Configuration(),"root");
            System.out.println(fileSystem);
        }

    /*
        获取FileSystem,方式3
        ctrl+alt+v自动补全返回值
         */
        @Test
        public void getFileSystem3() throws IOException {
            Configuration configuration = new Configuration();
            configuration.set("fs.defaultFS","hdfs://hadoop101:8020","root");
            //3.获取指定的文件系统
            FileSystem fileSystem= FileSystem.newInstance(configuration);
            //4.输出
            System.out.println(fileSystem.toString());
        }

    /*
        获取FileSystem,方式4
        ctrl+alt+v自动补全返回值
         */
        @Test
        public void getFileSystem4() throws URISyntaxException, IOException, InterruptedException {
            FileSystem fileSystem= FileSystem.newInstance(new URI("hdfs://hadoop101:8020"), new Configuration(),"root");
            System.out.println(fileSystem);
        }

    遍历 HDFS中所有文件

    /*
        hdfs文件的遍历
         */
        @Test
        public void listFiles() throws URISyntaxException, IOException, InterruptedException {
            //1.获取FileSystem实例
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop101:8020"), new Configuration(),"root");
            //2.调用方法listFiles获取/目录下的所有文件信息
            RemoteIterator<LocatedFileStatus> iterator = fileSystem.listFiles(new Path("/"), true);
            //3.遍历迭代器
            while (iterator.hasNext()){
                LocatedFileStatus fileStatus = iterator.next();
    
                //获取文件的绝对路径:hdfs://hadoop101:/xxx
                System.out.println(fileStatus.getPath()+"----"+fileStatus.getPath().getName());
                //文件的block信息
                BlockLocation[] blockLocations = fileStatus.getBlockLocations();
                System.out.println("block数目:"+blockLocations.length);
            }
        }

    输出:

     HDFS 上创建文件夹

     /*
        hdfs创建文件夹
         */
        @Test
        public void mkdirsTest() throws URISyntaxException, IOException, InterruptedException {
            //1.获取FileSystem实例
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop101:8020"), new Configuration(),"root");
            //2.获取文件夹
            boolean bl=fileSystem.mkdirs(new Path("/aaa/bbb/ccc/a.txt"));
            //fileSystem.create(new Path("/aaa/bbb/ccc/a.txt"));
            System.out.println(bl);
            //3.关闭FileSystem
            fileSystem.close();
        }

     下载文件

    /*
       文件下载2:使用方法copyToLocalFile下载到本地E盘下的bbb.txt
        */
        @Test
        public void downloadFile2() throws URISyntaxException, IOException, InterruptedException {
            //1.获取FileSystem
            FileSystem fileSystem=FileSystem.get(new URI("hdfs://hadoop101:8020"),new Configuration(),"root");
    
            fileSystem.copyToLocalFile(new Path("/a.txt"),new Path("E://bbb.txt"));
    
            fileSystem.close();
    
        }
        /*
       文件下载
        */
        @Test
        public void downloadFile() throws URISyntaxException, IOException {
            //1.获取FileSystem
            FileSystem fileSystem=FileSystem.get(new URI("hdfs://hadoop101:8020"),new Configuration());
            //2.获取hdfs的输入流
            FSDataInputStream inputStream = fileSystem.open(new Path("/a.txt"));
            //3.获取本地路径的输出流
            FileOutputStream outputStream = new FileOutputStream("E://a.txt");
            //4.文件的拷贝
            IOUtils.copy(inputStream,outputStream);
            //5.关闭流
            IOUtils.closeQuietly(inputStream);
            IOUtils.closeQuietly(outputStream);
            fileSystem.close();
        }

     HDFS 文件上传

     /*
      文件的上传
       */
        @Test
        public void uploadFile() throws URISyntaxException, IOException, InterruptedException {
            FileSystem fileSystem=FileSystem.get(new URI("hdfs://hadoop101:8020"),new Configuration(),"root");
            fileSystem.copyFromLocalFile(new Path("E://hello.txt"),new Path("/"));
            fileSystem.close();
        }

    小文件合并

    由于 Hadoop 擅长存储大文件,因为大文件的元数据信息比较少,如果 Hadoop 集群当中有大
    量的小文件,那么每个小文件都需要维护一份元数据信息,会大大的增加集群管理元数据的
    内存压力,所以在实际工作当中,如果有必要一定要将小文件合并成大文件进行一起处理
    在我们的 HDFS 的 Shell 命令模式下,可以通过命令行将很多的 hdfs 文件合并成一个大文件下
    载到本地

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

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

    /*
        小文件的合并
         */
        @Test
        public void mergeFile() throws URISyntaxException, IOException, InterruptedException {
            //1.获取FileSystem
            FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop101:8020"), new Configuration(), "root");
            //2.获取hdfs大文件的输出流
            FSDataOutputStream outputStream = fileSystem.create(new Path("/big_txt.txt"));
    
            //3.获取一个本地文件系统
            LocalFileSystem localFileSystem = FileSystem.getLocal(new Configuration());
            //4.获取本地文件夹下的所有文件的详情
            FileStatus[] fileStatuses = localFileSystem.listStatus(new Path("E:\input"));
            //5.遍历每个文件,获取每个文件的输入流
            for (FileStatus fileStatus:fileStatuses){
                FSDataInputStream inputStream=localFileSystem.open(fileStatus.getPath());
                //6.将小文件的数据复制到大文件
                IOUtils.copy(inputStream,outputStream);
                IOUtils.closeQuietly(inputStream);
            }
            IOUtils.closeQuietly(outputStream);
            localFileSystem.close();
            fileSystem.close();
        }

    输出:

     里面的内容是:在E盘下input文件夹下的5个txt文件的总和

    完成本地小文件的合并,上传

     

     HDFS的高可用机制

    在Hadoop 中,NameNode 所处的位置是非常重要的,整个HDFS文件系统的元数据信息都由
    NameNode 来管理,NameNode的可用性直接决定了Hadoop 的可用性,一旦NameNode进程
    不能工作了,就会影响整个集群的正常使用。
    在典型的HA集群中,两台独立的机器被配置为NameNode。在工作集群中,NameNode机器中
    的一个处于Active状态,另一个处于Standby状态。Active NameNode负责群集中的所有客户端
    操作,而Standby充当从服务器。Standby机器保持足够的状态以提供快速故障切换(如果需
    要)。

     Hadoop的联邦机制(Federation)

    HDFS Federation是解决namenode内存瓶颈问题的水平横向扩展方案。
    Federation意味着在集群中将会有多个namenode/namespace。这些namenode之间是联合的,
    也就是说,他们之间相互独立且不需要互相协调,各自分工,管理自己的区域。分布式的
    datanode被用作通用的数据块存储存储设备。每个datanode要向集群中所有的namenode注
    册,且周期性地向所有namenode发送心跳和块报告,并执行来自所有namenode的命令。

    Federation一个典型的例子就是上面提到的NameNode内存过高问题,我们完全可以将上面部分
    大的文件目录移到另外一个NameNode上做管理.更重要的一点在于,这些NameNode是共享集
    群中所有的DataNode的,它们还是在同一个集群内的**。**
    这时候在DataNode上就不仅仅存储一个Block Pool下的数据了,而是多个(在DataNode的datadir
    所在目录里面查看BP-xx.xx.xx.xx打头的目录)。


    概括起来:
    多个NN共用一个集群里的存储资源,每个NN都可以单独对外提供服务。
    每个NN都会定义一个存储池,有单独的id,每个DN都为所有存储池提供存储。
    DN会按照存储池id向其对应的NN汇报块信息,同时,DN会向所有NN汇报本地存储可用资源
    情况。

    HDFS Federation不足:

    HDFS Federation并没有完全解决单点故障问题。虽然namenode/namespace存在多个,但是从
    单个namenode/namespace看,仍然存在单点故障:如果某个namenode挂掉了,其管理的相
    应的文件便不可以访问。Federation中每个namenode仍然像之前HDFS上实现一样,配有一个
    secondary namenode,以便主namenode挂掉一下,用于还原元数据信息。
    所以一般集群规模真的很大的时候,会采用HA+Federation的部署方案。也就是每个联合的
    namenodes都是ha的。

     

  • 相关阅读:
    组装query,query汇总,query字段
    POJ 1276, Cash Machine
    POJ 1129, Channel Allocation
    POJ 2531, Network Saboteur
    POJ 1837, Balance
    POJ 3278, Catch That Cow
    POJ 2676, Sudoku
    POJ 3126, Prime Path
    POJ 3414, Pots
    POJ 1426, Find The Multiple
  • 原文地址:https://www.cnblogs.com/xiaofengzai/p/13509732.html
Copyright © 2011-2022 走看看