背景

工作中负责某OTA某业务线的数据,接手的数据中包括流量数据。原有的解析流程是将日志文件从存储池上传到hdfs,然后通过hadoop map reduce任务去格式化解析,解析后的数据导入特定的hive表对应的目录中。这个日志解析的流程有优势也有劣势:
优势:

  1. 日志解析实现上会比较灵活,只要是高级语言能实现的逻辑都能实现,例如在mapreduce中识别日志中乱码字符等。
  2. 对日志中的复杂字段的解析会比较好处理,例如日志中多个字段之间有相互关联,需要多个字段统一处理的时候。

劣势:

  1. 日志解析的可解释性不够强,读高级语言没有读sql或者脚本更直接。
  2. 日志解析不灵活,例如业务线因为新业务加了新业务必须要有的字段,那么如果想要在hive中露出这个字段的话,就必须重新更新mr的代码,打包上传才行,整个流程相对较长。
  3. 定位问题比较费劲,如果某天发现某个字段解析的不够正确,想定位出错的原因就需要读懂整个代码。

RegexSerDe解析器

RegexSerDe是hive自带的一种序列化/反序列化的方式,主要用来处理正则表达式。
使用RegexSerDe解析器,需要理解几个关键的参数:

参数 解释
input.regex 输入的正则表达式
output.format.string 输出的正则表达式
input.regex.case.insensitive 是否忽略字母大小写,默认为false

用法

假设某端的日志格式如下:
[2019-09-05 00:00:01.271 INFO api:180]####business={"city":"海口","page":1,"cat":"current_city=营口&dist_city=海口"}####common={"osVersion":"11.3.1","usid":"244396639","vid":"333333333"}

日志分析

以上的日志分为三部分:日志的头部,日志的business部分,日志的common部分,其中business和common都是原生的json字符串。

建表

针对上述的日志,用RegexSerDe解析器去匹配整行数据,这里需要注意,input.regex中需要全匹配日志的整行,每个括号表示一个字段。
`
CREATE EXTERNAL TABLE log_table(
log_head string COMMENT '日志头部',
business string COMMENT 'B',
commonparams string COMMENT 'C'
)
COMMENT 'test'
PARTITIONED BY (
dt string COMMENT '日期分区',
hour string COMMENT '小时分区')
ROW FORMAT SERDE
'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
'input.regex'='(\[.\])####businessParams=(\{.\})####commonParams=(\{.*\})',
'output.format.string'='%1$s %2$s %3$s')
STORED AS ORC;
`
至此原始日志的解析已经完成,日志已经在hive中被分割为三个字段,日志头部加上两个json字符串。

后续解析

后续可以将json中使用最频繁的字段从json中拆出来,单独在表中存放一个字段方便使用。
例如要取出common中的usid:
select get_json_object(common,'$.usid') from log_table


nizaikanwome
7 声望0 粉丝