HDFS操作及小文件合并

小文件合并是针对文件上传到HDFS之前

这些文件夹里面都是小文件

参考代码

package com.gong.hadoop2;

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;
/**
 * function 合并小文件至 HDFS
 * @author 小讲
 *
 */
public class MergeSmallFilesToHDFS {
    private static FileSystem fs = null;
    private static FileSystem local = null;
    /**
     * @function main
     * @param args
     * @throws IOException
     * @throws URISyntaxException
     */
    public static void main(String[] args) throws IOException,
            URISyntaxException {
        list();
    }

    /**
     *
     * @throws IOException
     * @throws URISyntaxException
     */
    public static void list() throws IOException, URISyntaxException {
        // 读取hadoop文件系统的配置
        Configuration conf = new Configuration();
        //文件系统访问接口
        URI uri = new URI("hdfs://dajiangtai:9000");
        //创建FileSystem对象
        fs = FileSystem.get(uri, conf);
        // 获得本地文件系统
        local = FileSystem.getLocal(conf);
        //过滤目录下的 svn 文件,globStatus从第一个参数通配符合到文件,剔除满足第二个参数到结果,因为PathFilter中accept是return!
        FileStatus[] dirstatus = local.globStatus(new Path("D://data/73/*"),new RegexExcludePathFilter("^.*svn$"));
        //获取73目录下的所有文件路径,注意FIleUtil中stat2Paths()的使用,它将一个FileStatus对象数组转换为Path对象数组。
        Path[] dirs = FileUtil.stat2Paths(dirstatus);
        FSDataOutputStream out = null;
        FSDataInputStream in = null;
        for (Path dir : dirs) {
            String fileName = dir.getName().replace("-", "");//文件名称
            //只接受日期目录下的.txt文件,^匹配输入字符串的开始位置,$匹配输入字符串的结束位置,*匹配0个或多个字符。
            FileStatus[] localStatus = local.globStatus(new Path(dir+"/*"),new RegexAcceptPathFilter("^.*txt$"));
            // 获得日期目录下的所有文件
            Path[] listedPaths = FileUtil.stat2Paths(localStatus);
            //输出路径
            Path block = new Path("hdfs://dajiangtai:9000/middle/tv/"+ fileName + ".txt");
            // 打开输出流
            out = fs.create(block);
            for (Path p : listedPaths) {
                in = local.open(p);// 打开输入流
                IOUtils.copyBytes(in, out, 4096, false); // 复制数据,IOUtils.copyBytes可以方便地将数据写入到文件,不需要自己去控制缓冲区,也不用自己去循环读取输入源。false表示不自动关闭数据流,那么就手动关闭。
                // 关闭输入流
                in.close();
            }
            if (out != null) {
                // 关闭输出流
                out.close();
            }
        }

    }

    /**
     *
     * @function 过滤 regex 格式的文件
     *
     */
    public static class RegexExcludePathFilter implements PathFilter {
        private final String regex;

        public RegexExcludePathFilter(String regex) {
            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) {
            this.regex = regex;
        }

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

    }
}

最后一点,分清楚hadoop fs 和dfs的区别

hadoop fs <args>

FS涉及可以指向任何文件系统(如本地,HDFS等)的通用文件系统。因此,当您处理不同的文件系统(如本地FS,HFTP FS,S3 FS等)时,可以使用它

hadoop dfs <args>

dfs非常具体到HDFS。 将工作与HDFS有关。 这已被弃用,我们应该使用hdfs dfs。

 hdfs   dfs <args>与第二个相同,即适用于与HDFS相关的所有操作,并且是推荐的命令,而不是hadoop dfs
时间: 2024-11-05 02:40:28

HDFS操作及小文件合并的相关文章

HDFS小文件合并问题的优化:copyMerge的改进

1.问题分析 用fsck命令统计 查看HDFS上在某一天日志的大小,分块情况以及平均的块大小,即 [[email protected] jar]$ hadoop fsck /wcc/da/kafka/report/2015-01-11 DEPRECATED: Use of this script to execute hdfs command is deprecated. Instead use the hdfs command for it. 15/01/13 18:57:23 WARN ut

hive小文件合并设置参数

Hive的后端存储是HDFS,它对大文件的处理是非常高效的,如果合理配置文件系统的块大小,NameNode可以支持很大的数据量.但是在数据仓库中,越是上层的表其汇总程度就越高,数据量也就越小.而且这些表通常会按日期进行分区,随着时间的推移,HDFS的文件数目就会逐渐增加. 小文件带来的问题 关于这个问题的阐述可以读一读Cloudera的这篇文章.简单来说,HDFS的文件元信息,包括位置.大小.分块信息等,都是保存在NameNode的内存中的.每个对象大约占用150个字节,因此一千万个文件及分块就

Hive merge(小文件合并)

当Hive的输入由很多个小文件组成时,如果不涉及文件合并的话,那么每个小文件都会启动一个map task. 如果文件过小,以至于map任务启动和初始化的时间大于逻辑处理的时间,会造成资源浪费,甚至发生OutOfMemoryError错误. 因此,当我们启动一个任务时,如果发现输入数据量小但任务数量多时,需要注意在Map前端进行输入小文件合并操作. 同理,向一个表写数据时,注意观察reduce数量,注意输出文件大小. 1. Map输入小文件合并 #每个Map处理的最大输入文件大小(256MB) s

MR案例:小文件合并SequeceFile

SequeceFile是Hadoop API提供的一种二进制文件支持.这种二进制文件直接将<key, value>对序列化到文件中.可以使用这种文件对小文件合并,即将文件名作为key,文件内容作为value序列化到大文件中.这种文件格式有以下好处: 1). 支持压缩,且可定制为基于Record或Block压缩(Block级压缩性能较优)2). 本地化任务支持:因为文件可以被切分,因此MapReduce任务时数据的本地化情况应该是非常好的.3). 难度低:因为是Hadoop框架提供的API,业务

将小文件合并大文件上传

自定义方法将本地多个小文件合并成一个大文件上传到HDFS上. package test; import java.net.URI; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.fs.FSDataInputStream; import org.apache.hadoop.fs.FSDataOutputStream; import org.apache.hadoop.fs.FileStatus; impo

hive压缩之小文件合并

Hive压缩之二 小文件合并 调研背景 当Hive输入由很多个小文件组成,由于每个小文件都会启动一个map任务,如果文件过小,以至于map任务启动和初始化的时间大于逻辑处理的时间,会造成资源浪费,甚至OOM.为此,当我们启动一个任务,发现输入数据量小但任务数量多时,需要注意在Map前端进行输入合并.当然,在我们向一个表写数据时,也需要注意输出文件大小. 输入合并 合并输入小文件,减少map数? 主要的决定因素有: input的文件总个数,input的文件大小,集群设置的文件块大小. 举例: a)

hadoop 将HDFS上多个小文件合并到SequenceFile里

背景:hdfs上的文件最好和hdfs的块大小的N倍.如果文件太小,浪费namnode的元数据存储空间以及内存,如果文件分块不合理也会影响mapreduce中map的效率. 本例中将小文件的文件名作为key,其内容作为value生成SequenceFile 1.生成文件 //将目标目录的所有文件以文件名为key,内容为value放入SequenceFile中 //第一个参数是需要打包的目录,第二个参数生成的文件路径和名称 private static void combineToSequenceF

hadoop小文件合并

1.背景 在实际项目中,输入数据往往是由许多小文件组成,这里的小文件是指小于HDFS系统Block大小的文件(默认128M), 然而每一个存储在HDFS中的文件.目录和块都映射为一个对象,存储在NameNode服务器内存中,通常占用150个字节. 如果有1千万个文件,就需要消耗大约3G的内存空间.如果是10亿个文件呢,简直不可想象.所以在项目开始前, 我们选择一种适合的方案来解决本项目的小文件问题 2.介绍 本地 D:\data目录下有 2012-09-17 至 2012-09-23 一共7天的

Facebook图片存储系统Haystack——存小文件,本质上是将多个小文件合并为一个大文件来降低io次数,meta data里存偏移量

转自:http://yanyiwu.com/work/2015/01/04/Haystack.html 一篇14页的论文Facebook-Haystack, 看完之后我的印象里就四句话: 因为[传统文件系统的弊端] 因为[缓存无法解决长尾问题] 所以[多个图片信息(Needle)存在同一个文件(SuperBlock)中] 所以[显著提高性能] 传统文件系统的弊端 传统的 POSIX 文件系统不适合高性能的图片存储, 主要原因是基于该文件系统来存储的话,是讲每个图片存储成某目录下的一个文件, 每次