2016-08-11 1 views
0

Я очень новичок в hadoop. Просто начал с куста, импала cdh5 на ubuntu 14.04. ФорматHadoop, обрабатывая файл с помощью delimater, но различной длины

Моих Дейтов, как

A¦aa¦bb¦cc 
A¦bb¦cc¦ac¦dd¦ff¦fg 
B¦aa¦ac 
... 

Первый столбец может быть ключом, но другая часть не имеет фиксированную длину или фиксированное число столбцов. Все разные. Я не знаю, сколько столбцов в каждой строке. Поэтому я изменил это

Col1¦col2 
A¦aa 
A¦bb 
A¦cc 
A¦bb 
A¦cc 
A¦ac 
A¦dd 
.... 

Но это занимает так много времени, так как у меня есть сотни файлов и каждый из них имеет более 10M линий и размер 30GB. И после того, как я преобразовал первый формат во второй, размер файла был увеличен два или три раза. Поэтому я хочу пропустить этот процесс.

Вопрос 1. Если я импортировать исходный файл в HDFS, могу ли я использовать некоторые SQLs как это «выбрать отличный col1, col2 из ...» на кусте или импала? Какой будет результат

Col1¦col2 
A¦aa 
A¦bb 
A¦cc 
A¦ac 
A¦dd 
.... 

Вопрос 2. Если Q1 возможно, что о SQL Server? То же самое? «Выберите отчетливый col1, col2 от ...»

+0

ДОБАВИТЬ В Q1. Я имел в виду, можно ли без трансформации? Я хочу загрузить исходный файл в hdfs и использовать sql. –

ответ

0

Вопрос 1 Да, можно прочитать файл упорядочивать (после того, как все ваши первоначальные работы) через улья или Impala. Решение, которое я вам даю ниже, находится в Hive.

Войдите в Улей и создайте внешнюю таблицу.

CREATE EXTERNAL TABLE Test_table(column1 string, column2 string) 
    ROW FORMAT DELIMITED 
    FIELDS TERMINATED BY '|' 
    STORED AS TEXTFILE 
    LOCATION '/location/of/your/file/on/hdfs'; 

На основании введенного в вопрос ввода, я принимаю ваш разделитель как '|' и формат для текста. Это создаст таблицу поверх ваших данных.

Этот же код можно использовать при создании таблицы в Импале.

Вопрос 2.

Войти в Hive и запустить ниже.

select column1,column2 from test_table; 
+0

Ваш ответ хорош, но сначала он нуждается в преобразовании. Когда я создал внешнюю таблицу с исходным файлом, это дало мне ошибку. A | aa (оставим остальную часть права) A | bb (оставим остальную часть права) B | aa ... Я добавил дополнительную информацию к сообщению. –

0

прямо вперед и простая программа MapReduce будет наилучшим образом соответствовать вашему сценарию, вот код для справки:

Ниже программа будет выполнять 2 операции одновременно:

1) Сбор строка данных и преобразовать в пары значений ключа

2) Устраните дубликаты и сохраните только отдельные значения для вывода, поскольку ключ представляет собой комбинацию маркера начального токена +, поэтому дубликаты будут устранены. пример (A | bb) будет вашим ключом и нулевым значением.

Код:

import java.io.IOException; 

import org.apache.hadoop.conf.Configuration; 
import org.apache.hadoop.conf.Configured; 
import org.apache.hadoop.fs.Path; 
import org.apache.hadoop.io.LongWritable; 
import org.apache.hadoop.io.NullWritable; 
import org.apache.hadoop.io.Text; 
import org.apache.hadoop.mapreduce.Job; 
import org.apache.hadoop.mapreduce.Mapper; 
import org.apache.hadoop.mapreduce.Reducer; 
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat; 
import org.apache.hadoop.mapreduce.lib.input.TextInputFormat; 
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat; 
import org.apache.hadoop.mapreduce.lib.output.TextOutputFormat; 
import org.apache.hadoop.util.Tool; 
import org.apache.hadoop.util.ToolRunner; 

public class MRTranspose extends Configured implements Tool { 

    public static void main(String args[]) throws Exception { 
     int res = ToolRunner.run(new MRTranspose(), args); 
     System.exit(res); 
    } 

    public int run(String[] args) throws Exception { 
     Path inputPath = new Path(args[0]); 
     Path outputPath = new Path(args[1]); 

     Configuration conf = getConf(); 
     Job job = new Job(conf, this.getClass().toString()); 

     FileInputFormat.setInputPaths(job, inputPath); 
     FileOutputFormat.setOutputPath(job, outputPath); 

     job.setJobName("transpose"); 
     job.setJarByClass(MRTranspose.class); 
     job.setInputFormatClass(TextInputFormat.class); 
     job.setOutputFormatClass(TextOutputFormat.class); 
     job.setMapOutputKeyClass(Text.class); 
     job.setMapOutputValueClass(NullWritable.class); 
     job.setOutputKeyClass(Text.class); 
     job.setOutputValueClass(Text.class); 
     job.setMapperClass(Map.class); 
     job.setReducerClass(Reduce.class); 

     return job.waitForCompletion(true) ? 0 : 1; 
    } 

    public static class Map extends 
      Mapper<LongWritable, Text, Text, NullWritable> { 

     @Override 
     public void map(LongWritable key, Text value, Mapper.Context context) 
       throws IOException, InterruptedException { 
      String line = value.toString(); 
      String words[] = line.split("¦"); 
      for (int i = 1; i < words.length; i++) { 
       context.write(new Text(words[0] + "¦" + words[i]), 
         NullWritable.get()); 
      } 
     } 
    } 

    public static class Reduce extends 
      Reducer<Text, NullWritable, Text, NullWritable> { 

     @Override 
     public void reduce(Text key, Iterable<NullWritable> values, 
       Context context) throws IOException, InterruptedException { 

      context.write(key, NullWritable.get()); 
     } 
    } 

} 

обеспечивают сырец папку данных в качестве первого аргумента, а второй аргумент в качестве выходной папки

входного файла: input.txt

A¦aa¦bb¦cc 
A¦bb¦cc¦ac¦dd¦ff¦fg 
B¦aa¦ac 

выходного файла : part-r-00000 file

A¦aa 
A¦ac 
A¦bb 
A¦cc 
A¦dd 
A¦ff 
A¦fg 
B¦aa 
B¦ac 

Наконец, связав свой MapReduce выходного пути в качестве входного пути для ваших ульев таблиц для дальнейшего запрашивая

Надеется, что это полезно.