在AWS EMR上的Hadoop输出上使用LZO时,是否会对文件(存储在S3中)进行索引以便将来自动拆分?

Dol*_*cci 4 amazon-s3 lzo amazon-web-services elastic-map-reduce

我想在存储在S3上的Elastic Map Reduce作业输出上使用LZO压缩,但不清楚文件是否自动编入索引,以便将来对该数据运行的作业会将文件拆分为多个任务.

例如,如果我的输出是一堆TSV数据行,在1GB LZO文件中,未来的地图作业将只创建1个任务,或类似(1GB/blockSize)任务(即文件未压缩时的行为) ,或者如果目录中有LZO索引文件)?

编辑:如果没有自动完成,建议将输出设为LZO索引?将文件上传到S3 之前进行索引编制?

Dol*_*cci 6

简短的回答我的第一个问题: AWS并没有做自动索引.我已经用自己的工作证实了这一点,并且在他们的论坛上也从Andrew @ AWS中读到了相同内容.

以下是如何进行索引编制的方法:

要为某些LZO文件编制索引,您需要使用我自己的Jar来自Twitter hadoop-lzo项目.如果要直接使用EMR进行索引,则需要在某处构建Jar,然后上传到Amazon S3.

另外,Cloudera对在您自己的群集上进行此设置的所有步骤都有很好的说明.我在我的本地群集上执行了此操作,这允许我构建Jar并上传到S3.如果您不想自己构建,可以在网上找到预先构建的Jar.

从Hadoop作业输出数据时,请确保使用LzopCodec而不是LzoCodec,否则文件不可索引(至少根据我的经验).示例Java代码(相同的想法延续到Streaming API):

import com.hadoop.compression.lzo.LzopCodec;
TextOutputFormat.setCompressOutput(job, true); 
TextOutputFormat.setOutputCompressorClass(job, LzopCodec.class)
Run Code Online (Sandbox Code Playgroud)

一旦您的hadoop-lzo Jar在S3上,并且您的Hadoop作业输出了.lzo文件,请在输出目录上运行您的索引器(下面的说明您已经运行了EMR作业/集群):

elastic-mapreduce -j <existingJobId> \
  --jar s3n://<yourBucketName>/hadoop-lzo-0.4.17-SNAPSHOT.jar \
    --args com.hadoop.compression.lzo.DistributedLzoIndexer \
    --args s3://<yourBucketName>/output/myLzoJobResults \
    --step-name "Lzo file indexer Jar"
Run Code Online (Sandbox Code Playgroud)

然后,当您在将来的作业中使用数据时,请确保指定输入是LZO格式,否则不会发生拆分.示例Java代码:

import com.hadoop.mapreduce.LzoTextInputFormat;
job.setInputFormatClass(LzoTextInputFormat.class);
Run Code Online (Sandbox Code Playgroud)