我需要在 Hadoop 作业中处理和操作许多图像,输入将通过网络传输,使用MultiThreadedMapper
.
但是减少输出的最佳方法是什么?我想我应该将原始二进制图像数据写入序列文件,将这些文件传输到它们最终的位置,然后编写一个小应用程序来将单个图像从其中提取SequenceFile
到单个 JPG 和 GIF 中。
还是有更好的选择可以考虑?
如果你觉得可以(或者通过一些谷歌搜索你可以找到一个实现),你可以编写一个 FileOutputFormat ,它用 ZipOutputStream 包装一个 FSDataOutputStream ,为每个减速器提供一个 Zip 文件(从而节省你编写 seq 的工作量文件提取程序。
不要被自己编写的 OutputFormat 吓倒,它真的没有那么难(而且比编写必须担心拆分的自定义 InputFormat 容易得多)。事实上,这是一个起点——你只需要实现 write 方法:
// Key: Text (path of the file in the output zip)
// Value: BytesWritable - binary content of the image to save
public class ZipFileOutputFormat extends FileOutputFormat<Text, BytesWritable> {
@Override
public RecordWriter<Text, BytesWritable> getRecordWriter(
TaskAttemptContext job) throws IOException, InterruptedException {
Path file = getDefaultWorkFile(job, ".zip");
FileSystem fs = file.getFileSystem(job.getConfiguration());
return new ZipRecordWriter(fs.create(file, false));
}
public static class ZipRecordWriter extends
RecordWriter<Text, BytesWritable> {
protected ZipOutputStream zos;
public ZipRecordWriter(FSDataOutputStream os) {
zos = new ZipOutputStream(os);
}
@Override
public void write(Text key, BytesWritable value) throws IOException,
InterruptedException {
// TODO: create new ZipEntry & add to the ZipOutputStream (zos)
}
@Override
public void close(TaskAttemptContext context) throws IOException,
InterruptedException {
zos.close();
}
}
}