我在hadoop中有一个要求,我需要将一组日志文件加载到hive表中并对其进行查询。
示例日志文件如下所示,
# Comment
# Comment
01 record1 record2 record3 record4
02 record1 record2 record3 record4
03 record1 record2 record3 record4
# Comment
# comment
我想要消除这条#注释行,每行以#开头。
我要加载的实际内容是空格分隔和结构化的。
关于如何通过消除注释行来加载数据的任何解决方案/建议?
请帮忙!
答案 0 :(得分:0)
您可以使用unix命令清理文件:
如果字段不包含#
,请使用grep -v'#' filename.log> stripped.log
否则请使用sed命令
sed' / ^#/ d' filename.log> stripped.log,这将删除以#
为了清理大文件,不会重新开始UNIX命令。您应该使用MapReduce程序清理数据。
您可以在每一行上执行清理操作,然后将其插入配置单元表进行查询。 PFA map reduce程序,用于清除数据文件中的注释。
hadoop jar CleanData.jar HDFS数据位置HDFS Hive表文件夹Namenode主机名:PortNo
示例地图减少程序以清理数据
public class CleanData {
public static class Map extends Mapper<LongWritable, Text, Text,NullWritable> {
@Override
public void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {
NullWritable nullWritable = NullWritable.get();
String line = value.toString();
if(line.substring(0, 1).equals("#")){}
else
context.write(value,nullWritable);
}
}
public static void main(String[] args) throws Exception {
Configuration conf=new Configuration();
conf.set("fs.default.name", args[2]);
Job job = new Job(conf);
job.setJarByClass(CleanData.class);
job.setJobName("wordcount");
FileInputFormat.addInputPath(job, new Path(args[0]));
FileOutputFormat.setOutputPath(job, new Path(args[1]));
job.setMapperClass(Map.class);
job.setOutputKeyClass(Text.class);
job.setOutputValueClass(NullWritable.class);
job.waitForCompletion(true);
}
}
答案 1 :(得分:0)
您可以在创建配置单元表时指定serde。 内置的RegexSerde将满足您的需求。
CREATE TABLE regex_log_table (
id STRING ,
val1 STRING,
val2 STRING,
val3 STRING,
val4 STRING
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "(^[0-9]+) (.+) (.+) (.+) (.+)$",
"output.format.string" = "%1$s %2$s %3$s %4$s %5$s"
)
STORED AS TEXTFILE;
如果您需要更多自定义数据加载,可以编写自定义serde。
参考:http://shout.setfive.com/2013/12/10/hive-how-to-write-a-custom-serde-class/