0

我有来自 IIS 的日志文件存储在 hdfs 中,但由于网络服务器配置,一些日志没有所有列,或者它们以不同的顺序出现。我想生成具有通用架构的文件,以便可以在它们上定义 Hive 表。

好的日志示例:

#Fields: date time s-ip cs-method cs-uri-stem useragent
2013-07-16 00:00:00 10.1.15.8 GET /common/viewFile/1232 Mozilla/5.0+Chrome/27.0.1453.116

缺少列的示例日志(缺少 cs 方法和用户代理):

#Fields: date time s-ip cs-uri-stem 
2013-07-16 00:00:00 10.1.15.8 /common/viewFile/1232

缺少列的日志需要映射到完整的架构,如下所示:

#Fields: date time s-ip cs-method cs-uri-stem useragent
2013-07-16 00:00:00 10.1.15.8 null /common/viewFile/1232 null

坏日志可以启用列的任意组合并且以不同的顺序。

如何根据日志文件中的字段行将可用列映射到完整架构?

编辑:通常我会通过将列模式定义为将列名映射到索引的字典来解决此问题。即: col['date']=0 col['time']=1 等然后我会从文件中读取#Fields行并解析出启用的列并生成标题dict映射标题名称到文件中的列索引. 然后对于剩余的数据行,我通过索引知道它的标题,通过 header=column name 将其映射到我的列模式,并以正确的顺序生成新行,插入带有空数据的缺失列。我的问题是我不明白如何在 hadoop 中执行此操作,因为每个地图都是单独执行的,因此如何与每个地图共享#Fields 信息?

4

1 回答 1

1

您可以使用来将标题应用于创建地图的列。从那里您可以使用UDF,例如:

myudf.py

#!/usr/bin/python

@outputSchema('newM:map[]')
def completemap(M):
    if M is None:
        return None
    to_add = ['A', 'D', 'F']
    for item in to_add:
        if item not in M:
            M[item] = None
    return M

@outputSchema('A:chararray, B:chararray, C:chararray, D:chararray, E:chararray, F:chararray')
def completemap_v2(M):
    if M is None:
        return (None,
                None,
                None,
                None,
                None,
                None)
    return (M.get('A', None),
            M.get('B', None),
            M.get('C', None),
            M.get('D', None),
            M.get('E', None),
            M.get('F', None))

将缺失的元组添加到地图中。

样本输入:

csv1.in             csv2.in
-------            ---------
A|B|C               D|E|F
Hello|This|is       PLEASE|WORK|FOO
FOO|BAR|BING        OR|EVERYTHING|WILL
BANG|BOSH           BE|FOR|NAUGHT

示例脚本:

A = LOAD 'tests/csv' USING myudfs.ExampleCSVLoader('\\|') AS (M:map[]); 
B = FOREACH A GENERATE FLATTEN(myudf.completemap_v2(M));

输出:

B: {null::A: chararray,null::B: chararray,null::C: chararray,null::D: chararray,null::E: chararray,null::F: chararray}
(,,,,,)
(,,,PLEASE,WORK,FOO)
(,,,OR,EVERYTHING,WILL)
(,,,BE,FOR,NAUGHT)
(,,,,,)
(Hello,This,is,,,)
(FOO,BAR,BING,,,)
(BANG,BOSH,,,,)
于 2013-08-20T22:38:02.187 回答