当前位置: 首页 > news >正文

Hadoop实战项目:小文件合并

项目背景

   在实际项目中,输入数据往往是由许多小文件组成,这里的小文件是指小于HDFS系统Block大小的文件(默认128M),早期的版本所定义的小文件是64M,这里的hadoop-2.2.0所定义的小文件是128M然而每一个存储在HDFS中的文件、目录和块都映射为一个对象,存储在NameNode服务器内存中,通常占用150个字节。 如果有1千万个文件,就需要消耗大约3G的内存空间。如果是10亿个文件呢,简直不可想象。所以在项目开始前, 我们要先了解一下 hadoop 处理小文件的各种方案,然后本课程选择一种适合的方案来解决本项目的小文件问题。Hadoop 自身提供了几种机制来解决相关的问题,包括HAR, SequeueFile和CombineFileInputFormat。

项目介绍

   在本地 D://Code/EclipseCode/mergeSmallFilesTestData目录下有 2018-03-23 至 2018-03-29 一共7天的数据集,我们需要将这7天的数据集按日期合并为7个大文件上传至 HDFS。

思路分析

     基于项目的需求,我们通过下面几个步骤完成:

  1)首先通过 globStatus()方法过滤掉 svn 格式的文件,获取 D://Code/EclipseCode/mergeSmallFilesTestData目录下的其它所有文件路径。

  2)然后循环第一步的所有文件路径,通过globStatus()方法获取所有 txt 格式文件路径。

  3)最后通过IOUtils.copyBytes(in, out, 4096, false)方法将数据集合并为7个大文件,并上传至 HDFS。

程序

  在Hadoop项目路径下新建MergeSmallFilesToHDFS.java:

 

/**
 * 
 */
package com.hadoop.train;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

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.FileUtil;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.fs.PathFilter;
import org.apache.hadoop.io.IOUtils;


/**
 * @author Zimo
 * 合并小文件到HDFS
 *
 */
public class MergeSmallFilesToHDFS {

    private static FileSystem hdfs = null; //定义HDFS上的文件系统对象
    private static FileSystem local = null; //定义本地文件系统对象
    
    /**
     * 
     * @function 过滤 regex 格式的文件
     *
     */
    public static class RegexExcludePathFilter implements PathFilter 
    {

        private final String regex;

        public RegexExcludePathFilter(String regex) {
            // TODO Auto-generated constructor stub
            this.regex = regex;
        }

        @Override
        public boolean accept(Path path) {
            // TODO Auto-generated method stub
            boolean flag = path.toString().matches(regex);
            return !flag;
        }

    }
    
    /**
     * 
     * @function 接受 regex 格式的文件
     *
     */
    public static class RegexAcceptPathFilter implements PathFilter
    {

        private final String regex;

        public RegexAcceptPathFilter(String regex) {
            // TODO Auto-generated constructor stub
            this.regex = regex;
        }

        @Override
        public boolean accept(Path path) {
            // TODO Auto-generated method stub
            boolean flag = path.toString().matches(regex);
            return flag;
        }
    
    }
    
    /**
     * @param args
     * @throws IOException 
     * @throws URISyntaxException 
     */
    public static void main(String[] args) throws URISyntaxException, IOException {
        // TODO Auto-generated method stub
        list();

    }

    private static void list() throws URISyntaxException, IOException {
        // TODO Auto-generated method stub
        Configuration conf = new Configuration();//读取Hadoop配置文件
        
        //设置文件系统访问接口,并创建FileSystem在本地的运行模式
        URI uri = new URI("hdfs://Centpy:9000");
        hdfs = FileSystem.get(uri, conf);
        
        local = FileSystem.getLocal(conf);//获取本地文件系统
        
        //过滤目录下的svn文件
        FileStatus[] dirstatus = local.globStatus(new Path("D://Code/EclipseCode/mergeSmallFilesTestData/*"),
                new RegexExcludePathFilter("^.*svn$"));
        
        //获取D:\Code\EclipseCode\mergeSmallFilesTestData目录下的所有文件路径
        Path[] dirs = FileUtil.stat2Paths(dirstatus);
        FSDataOutputStream out = null;
        FSDataInputStream in = null;
        for(Path dir:dirs)
        {//比如拿2018-03-23为例
            
            //将文件夹名称2018-03-23的-去掉,直接,得到20180323文件夹名称
            String fileName = dir.getName().replace("-", "");//文件名称

            
            //只接受2018-03-23日期目录下的.txt文件
            FileStatus[] localStatus = local.globStatus(new Path(dir + "/*"), 
                    new RegexAcceptPathFilter("^.*txt$"));
            
            // 获得2018-03-23日期目录下的所有文件
            Path[] listPath = FileUtil.stat2Paths(localStatus);
            
            // 输出路径
            Path outBlock = new Path("hdfs://Centpy:9000/mergeSmallFiles/result/"+ fileName + ".txt");
            System.out.println("合并后的文件名称:"+fileName+".txt");
            
            // 打开输出流
            out = hdfs.create(outBlock);
            
            //循环操作2018-03-23日期目录下的所有文件
            for(Path p:listPath)
            {
                in = local.open(p);// 打开输入流
                IOUtils.copyBytes(in, out, 4096, false);// 复制数据
                in.close();// 关闭输入流
            }
            
            if (out != null) {
                out.close();// 关闭输出流
            }
        }
        
    }

}

测试结果

  运行程序之后会将本地D://Code/EclipseCode/mergeSmallFilesTestData路径下的每个文件夹下的n个.txt文件内容合并到一个.txt文件中,并存放到指定的HDFS路径("hdfs://Centpy:9000/mergeSmallFiles/result/")下。

 

 

以上就是博主为大家介绍的这一板块的主要内容,这都是博主自己的学习过程,希望能给大家带来一定的指导作用,有用的还望大家点个支持,如果对你没用也望包涵,有错误烦请指出。如有期待可关注博主以第一时间获取更新哦,谢谢!

 

 

 

 版权声明:本文为博主原创文章,未经博主允许不得转载。

 

转载于:https://www.cnblogs.com/zimo-jing/p/8670684.html

相关文章:

  • Apache Calcite Avatica 1.10.0 发布,动态数据管理框架
  • Ambari-单步创建cluster
  • worker模式 多线程实现
  • Akamai 发布互联网安全报告:DDoS 攻击量激增
  • Android 采用AOP方式封装6.0权限管理
  • WebMIS 2016-09 稳定版,基于 Phalcon 的 CMS
  • 实验吧_加了料的报错注入
  • 常用的去重和排序
  • 记一例DCDIAG /A报错0x6ba rpc服务器不可用
  • 看直播卡顿问题,排除网络卡顿,排除cpu太差
  • Windows 10 RedStone 新版 Edge 浏览器上手图集
  • python数据类型之集合
  • javaWeb服务详解(含源代码,测试通过,注释) ——Emp的Service层
  • E - Box of Bricks (注意很多文章是错的)
  • centos安装iftop监控服务器流量
  • 【162天】黑马程序员27天视频学习笔记【Day02-上】
  • 2017 年终总结 —— 在路上
  • CSS实用技巧
  • express.js的介绍及使用
  • Java超时控制的实现
  • JDK9: 集成 Jshell 和 Maven 项目.
  • Mac转Windows的拯救指南
  • Redis在Web项目中的应用与实践
  • RxJS: 简单入门
  • UEditor初始化失败(实例已存在,但视图未渲染出来,单页化)
  • VuePress 静态网站生成
  • 开源SQL-on-Hadoop系统一览
  • 可能是历史上最全的CC0版权可以免费商用的图片网站
  • 让你成为前端,后端或全栈开发程序员的进阶指南,一门学到老的技术
  • 如何在 Tornado 中实现 Middleware
  • 思维导图—你不知道的JavaScript中卷
  • 线上 python http server profile 实践
  • 限制Java线程池运行线程以及等待线程数量的策略
  • 一道面试题引发的“血案”
  • 这几个编码小技巧将令你 PHP 代码更加简洁
  • Semaphore
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException
  • #gStore-weekly | gStore最新版本1.0之三角形计数函数的使用
  • #前后端分离# 头条发布系统
  • $分析了六十多年间100万字的政府工作报告,我看到了这样的变迁
  • (1)bark-ml
  • (6)添加vue-cookie
  • (C语言)球球大作战
  • (论文阅读31/100)Stacked hourglass networks for human pose estimation
  • (三)uboot源码分析
  • (转) RFS+AutoItLibrary测试web对话框
  • (转)mysql使用Navicat 导出和导入数据库
  • (转)项目管理杂谈-我所期望的新人
  • (轉貼) 資訊相關科系畢業的學生,未來會是什麼樣子?(Misc)
  • ***php进行支付宝开发中return_url和notify_url的区别分析
  • .bat批处理(三):变量声明、设置、拼接、截取
  • .Net mvc总结
  • .net php 通信,flash与asp/php/asp.net通信的方法
  • .NET6使用MiniExcel根据数据源横向导出头部标题及数据