Hadoopでmap-reduceジョブを効果的に利用するには、データをHadoopのシーケンスファイル形式で保存する必要があります。ただし、現在、データはフラットな.txt形式のみです。.txtファイルをシーケンスファイルに変換する方法を誰かが提案できますか?
7 に答える
したがって、より単純な答えは、SequenceFile出力を持つ単なる「ID」ジョブです。
Javaでは次のようになります。
public static void main(String[] args) throws IOException,
InterruptedException, ClassNotFoundException {
Configuration conf = new Configuration();
Job job = new Job(conf);
job.setJobName("Convert Text");
job.setJarByClass(Mapper.class);
job.setMapperClass(Mapper.class);
job.setReducerClass(Reducer.class);
// increase if you need sorting or a special number of files
job.setNumReduceTasks(0);
job.setOutputKeyClass(LongWritable.class);
job.setOutputValueClass(Text.class);
job.setOutputFormatClass(SequenceFileOutputFormat.class);
job.setInputFormatClass(TextInputFormat.class);
TextInputFormat.addInputPath(job, new Path("/lol"));
SequenceFileOutputFormat.setOutputPath(job, new Path("/lolz"));
// submit and wait for completion
job.waitForCompletion(true);
}
import java.io.IOException;
import java.net.URI;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.IntWritable;
import org.apache.hadoop.io.SequenceFile;
import org.apache.hadoop.io.Text;
//White, Tom (2012-05-10). Hadoop: The Definitive Guide (Kindle Locations 5375-5384). OReilly Media - A. Kindle Edition.
public class SequenceFileWriteDemo {
private static final String[] DATA = { "One, two, buckle my shoe", "Three, four, shut the door", "Five, six, pick up sticks", "Seven, eight, lay them straight", "Nine, ten, a big fat hen" };
public static void main( String[] args) throws IOException {
String uri = args[ 0];
Configuration conf = new Configuration();
FileSystem fs = FileSystem.get(URI.create( uri), conf);
Path path = new Path( uri);
IntWritable key = new IntWritable();
Text value = new Text();
SequenceFile.Writer writer = null;
try {
writer = SequenceFile.createWriter( fs, conf, path, key.getClass(), value.getClass());
for (int i = 0; i < 100; i ++) {
key.set( 100 - i);
value.set( DATA[ i % DATA.length]);
System.out.printf("[% s]\t% s\t% s\n", writer.getLength(), key, value);
writer.append( key, value); }
} finally
{ IOUtils.closeStream( writer);
}
}
}
TXTファイルの形式によって異なります。レコードごとに1行ですか?その場合は、TextInputFormatを使用して、行ごとに1つのレコードを作成できます。マッパーでは、その行を解析して、選択した方法で使用できます。
レコードごとに1行でない場合は、独自のInputFormat実装を作成する必要がある場合があります。詳細については、このチュートリアルをご覧ください。
中間テーブルを作成し、csvの内容を直接そのテーブルにロードしてから、2番目のテーブルをシーケンスファイル(パーティション化、クラスター化など)として作成し、中間テーブルからselectに挿入することもできます。圧縮のオプションを設定することもできます。
set hive.exec.compress.output = true;
set io.seqfile.compression.type = BLOCK;
set mapred.output.compression.codec = org.apache.hadoop.io.compress.SnappyCodec;
create table... stored as sequencefile;
insert overwrite table ... select * from ...;
その後、MRフレームワークが手間のかかる作業を処理し、Javaコードを作成する手間を省きます。
フォーマット指定子に注意してください:
。
たとえば(%
との間のスペースに注意してください s
)、System.out.printf("[% s]\t% s\t% s\n", writer.getLength(), key, value);
java.util.FormatFlagsConversionMismatchException: Conversion = s, Flags =
代わりに、次を使用する必要があります。
System.out.printf("[%s]\t%s\t%s\n", writer.getLength(), key, value);
データがHDFSにない場合は、HDFSにアップロードする必要があります。2つのオプション:
i)hdfs -.txtファイルを配置し、HDFSで取得したら、seqファイルに変換できます。
ii)テキストファイルをHDFSクライアントボックスの入力として受け取り、SequenceFile.Writerを作成して(key、values)を追加することにより、SequenceFileAPIを使用してSeqFileに変換します。
キーを気にしない場合は、行番号をキーとして、完全なテキストを値として作成できます。
Mahoutがインストールされている場合-seqdirectoryと呼ばれるものがあります-これを実行できます