我在hadoop中有一个需求,需要将一组日志文件加载到配置单元表中并对其进行查询。
示例日志文件看起来像
# Comment
# Comment
01 record1 record2 record3 record4
02 record1 record2 record3 record4
03 record1 record2 record3 record4
# Comment
# comment
我想删除每行中以#开头的#注释行。
我要加载的实际内容是以空格分隔和结构化的。
关于如何通过删除注释行来加载数据,有什么解决方案/建议吗?
请帮忙!
您可以使用unix命令清理文件:
如果字段不包含#
,请使用grep-v'#'filename.log>striped.logelse使用sed命令查看sed'/^#/d'filename.log>striped.log,这将删除所有以#开头的行
对于清理大文件,不建议使用UNIX命令。您应该使用MapReduce程序清理数据。
您可以对每一行执行清理操作,然后将其插入配置单元表中进行查询。PFA地图缩减程序,用于清除数据文件中的注释。
hadoop-jarCleanData.jar HDFS数据位置HDFS配置单元表文件夹名称节点主机名: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);
}
}
您可以在创建配置单元表时指定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/