背景
工作中负责某OTA某业务线的数据,接手的数据中包括流量数据。原有的解析流程是将日志文件从存储池上传到hdfs,然后通过hadoop map reduce任务去格式化解析,解析后的数据导入特定的hive表对应的目录中。这个日志解析的流程有优势也有劣势:
优势:
- 日志解析实现上会比较灵活,只要是高级语言能实现的逻辑都能实现,例如在mapreduce中识别日志中乱码字符等。
- 对日志中的复杂字段的解析会比较好处理,例如日志中多个字段之间有相互关联,需要多个字段统一处理的时候。
劣势:
- 日志解析的可解释性不够强,读高级语言没有读sql或者脚本更直接。
- 日志解析不灵活,例如业务线因为新业务加了新业务必须要有的字段,那么如果想要在hive中露出这个字段的话,就必须重新更新mr的代码,打包上传才行,整个流程相对较长。
- 定位问题比较费劲,如果某天发现某个字段解析的不够正确,想定位出错的原因就需要读懂整个代码。
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
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。