hdfs大量小文件压缩

继上一期的文件压缩之后,遇到两个问题:

  1. 部分日志数量量较大,一天的量级已经超过100G了,所以通过ftp拉数据到本地,时间太长了,这种方式不太可取。
  2. 因为日志是spark streaming实时采集的,数据分布不太均匀,大的有5个G,小的只有几十MB,这样即便压缩之后大量小文件对hdfs的读取性能也是有很大影响的。

针对这种情况,给出以下方案:

1.归档

先将这部分数据进行归档,归档可以合并大量小文件,数据量不会改变

原始数据
在这里插入图片描述
归档之后
在这里插入图片描述
在这里插入图片描述
数据分布很均匀

2.压缩

由于数据量较大,ftp方式不可取,故使用程序进行压缩

/**
 * Created by wpq on 2019/3/27.
 * 压缩测试
 */
public class HdfsCompressTest {
    public static void main(String[] args) throws ClassNotFoundException, IOException {
        SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        System.out.println("stattime:" + df.format(new Date()));
        Class<?> cal = Class.forName("org.apache.hadoop.io.compress.GzipCodec");
        Configuration conf = new Configuration();
        conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem");
        FileSystem fs = FileSystem.get(conf);
        CompressionCodec codec = (CompressionCodec) ReflectionUtils.newInstance(cal, conf);
        //指定压缩和被压缩的文件
        String inputfile = "/user/hdfs/rsync";
        //String inputfile = "/user/hdfs/wpq/tmp";
        RemoteIterator<LocatedFileStatus> files = fs.listFiles(new Path(inputfile), true);
        while (files.hasNext()) {
            LocatedFileStatus next = files.next();
            if (next.isFile()) {
                Path path = next.getPath();
                if (path.toString().endsWith("gz")) {
                } else {
                    //指定压缩输入流
                    FSDataInputStream in = fs.open(path);
                    //指定压缩输出流
                    String outfile = path.toString() + codec.getDefaultExtension();//添加压缩格式为后缀
                    FSDataOutputStream outputStream = fs.create(new Path(outfile));
                    CompressionOutputStream out = codec.createOutputStream(outputStream);
                    IOUtils.copyBytes(in, out, 4096, false);
                    in.close();
                    out.close();
                    fs.delete(path, true);
                }
            }
        }
        System.out.println("endtime:" + df.format(new Date()));
    }
}

3.校验

抽取每月1号,15号数据各100条以及当天数据的总条数,进行对比,验证ok,干掉源数据即可

猜你喜欢

转载自blog.csdn.net/qq_42264264/article/details/88885740