将目录作为压缩文件从 Elastic MapReduce 上传到 S3

Posted

技术标签:

【中文标题】将目录作为压缩文件从 Elastic MapReduce 上传到 S3【英文标题】:Uploading a directory as a zipped file from Elastic MapReduce to S3 【发布时间】:2011-01-31 00:17:09 【问题描述】:

我想将 EMR 本地文件系统中的目录作为压缩文件上传到 s3。

有没有比我目前使用的方法更好的方法来解决这个问题?

是否可以将 ZipOutputStream 作为 Reducer 输出返回?

谢谢

zipFolderAndUpload("target", "target.zip", "s3n://bucketpath/");


static public void zipFolderAndUpload(String srcFolder, String zipFile, String dst) throws Exception 

    //Zips a directory
    FileOutputStream fileWriter = new FileOutputStream(zipFile);
    ZipOutputStream zip = new ZipOutputStream(fileWriter);
    addFolderToZip("", srcFolder, zip);
    zip.flush();
    zip.close();

    // Copies the zipped file to the s3 filesystem,
    InputStream in = new BufferedInputStream(new FileInputStream(zipFile));
    Configuration conf = new Configuration();
    FileSystem fs = FileSystem.get(URI.create(dst+zip), conf);
    OutputStream out = fs.create(new Path(dst+zip));
    IOUtils.copyBytes(in, out, 4096, true);



static private void addFileToZip(String path, String srcFile, ZipOutputStream zip) throws Exception 

    File folder = new File(srcFile);
    if (folder.isDirectory()) 
        addFolderToZip(path, srcFile, zip);
     else 
        byte[] buf = new byte[1024];
        int len;
        FileInputStream in = new FileInputStream(srcFile);
        zip.putNextEntry(new ZipEntry(path + "/" + folder.getName()));
        while ((len = in.read(buf)) > 0) 
            zip.write(buf, 0, len);
        
    


static private void addFolderToZip(String path, String srcFolder, ZipOutputStream zip) throws Exception 
    File folder = new File(srcFolder);

    for (String fileName : folder.list()) 
        if (path.equals("")) 
            addFileToZip(folder.getName(), srcFolder + "/" + fileName, zip);
         else 
            addFileToZip(path + "/" + folder.getName(), srcFolder + "/" + fileName, zip);
        
    

【问题讨论】:

【参考方案1】:

您采用的方法看起来不错。如果你发现它太慢是因为它是单线程的,那么你可以创建自己的写入 zip 文件的 Hadoop OutputFormat 实现。

需要注意的一点是,Java SE 的 ZipOutputFormat 实现不支持 Zip64,这意味着它不支持大小超过 4GB 的 ZIP 文件。 ZIP 还有其他 Java 实现,例如 TrueZIP。

【讨论】:

以上是关于将目录作为压缩文件从 Elastic MapReduce 上传到 S3的主要内容,如果未能解决你的问题,请参考以下文章

mr中间结果优化

用sqoop将数据从mysql导入hive报错:org.apache.hadoop.mapred.FileAlreadyExistsException: Output

Auto Scaling 无法与 Elastic Beanstalk 中的 Tomcat 一起正常工作

AWS Elastic Beanstalk 将文件保存到 S3 或应用程序目录

Hadoop集群配置

如果使用 jar,则从 jar 中解压缩文件,然后将提取的文件复制到目录