在apache配置单元中使用regex创建表将返回所有空值

5sxhfpxr  于 2021-05-29  发布在  Hadoop
关注(0)|答案(1)|浏览(370)

我有许多日志文件*.log,我想用以下语法导入配置单元表:

CREATE EXTERNAL TABLE cache_22 ( 
a STRING, 
b STRING, 
c STRING, 
d STRING, 
e STRING, 
f STRING,
g STRING,
h  STRING, 
i STRING
)
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe' 
WITH SERDEPROPERTIES ( 'input.regex' =  '(\d+\w+\d+)\:.*?\[.*?\]\s(\d+\.\d+)\s(\d+\.\d+)\s\w*\s\d*\s(\d*)\s\d\s\w*\s(((?:[0-9]{1,3}\.){3}[0-9]{1,3}))\s(((?:[0-9]{1,3}\.){3}[0-9]{1,3}))\:\d*\s(?:-|http:\/\/|www\.|https:\/\/)([^\/]+)','output.format.string' = "%1$$s %2$$s %3$$s %4$$s %5$$s %6$$s %7$$s %8$$s %9$$s")';

但当我查询时,它会带来如下空值:

NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL

这是我的日志示例:

25Oct2016:103130.123456 [1234567a3] 0.522550 1.244476 TCP_PARTIAL_HIT 206 65871 0 GET 10.10.10.199 11.11.11.11:80 
25Oct2016:103130.654321 [1234567e8] 0.144449 0.178851 TCP_MISS 200 7035 0 GET 5.5.5.5 10.20.30.40:80 http://stackoverflow.com/questions/23668713/getting-null-values-in-hive-create-load-query-with-regex

请纠正我的错误。
谢谢。

weylhg0b

weylhg0b1#

在你的例子中是正则表达式( \\s(?:-|http:\\/\\/|www\\.|https:\\/\\/)([^\\/]+) )你用的serde好像有问题。您正在使用的serde似乎无法编译正则表达式的这些部分,因此无法获取数据。
我尝试了多种方案,其结果如下。
场景1:不修改数据和正则表达式
输入数据

[user1@server1 ~]$ hdfs dfs -cat /user/user1/hive_poc/hive3/file1.txt
25Oct2016:103130.123456 [1234567a3] 0.522550 1.244476 TCP_PARTIAL_HIT 206 65871 0 GET 10.10.10.199 11.11.11.11:80
25Oct2016:103130.654321 [1234567e8] 0.144449 0.178851 TCP_MISS 200 7035 0 GET 5.5.5.5 10.20.30.40:80 http://stackoverflow.com/questions/23668713/getting-null-values-in-hive-create-load-query-with-regex
[user1@server1 ~]$

配置单元创建表语句

hive> CREATE EXTERNAL TABLE tbl_regex_test3 (
    > a STRING,
    > b STRING,
    > c STRING,
    > d STRING,
    > e STRING,
    > f STRING,
    > g STRING,
    > h STRING,
    > i STRING
    > )
    > ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
    > WITH SERDEPROPERTIES ( 'input.regex' =  '(\\d+\\w+\\d+)\\:.*?\\[.*?\\]\\s(\\d+\\.\\d+)\\s(\\d+\\.\\d+)\\s\\w*\\s\\d*\\s(\\d*)\\s\\d\\s\\w*\\s(((?:[0-9]{1,3}\\.){3}[0-9]{1,3}))\\s(((?:[0-9]{1,3}\\.){3}[0-9]{1,3}))\\:\\d*\\s(?:-|http:\\/\\/|www\\.|https:\\/\\/)([^\\/]+)',
    > 'output.format.string' = "%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s")
    > LOCATION '/user/user1/hive_poc/hive3/';
OK
Time taken: 0.046 seconds
hive>

结果:没有得到任何数据。

hive> set hive.cli.print.header=true;
hive> add jar /home/user1/hive-contrib-0.10.0-cdh4.2.0.jar;
Added [/home/user1/hive-contrib-0.10.0-cdh4.2.0.jar] to class path
Added resources: [/home/user1/hive-contrib-0.10.0-cdh4.2.0.jar]
hive> select * from tbl_regex_test3;
OK
tbl_regex_test3.a       tbl_regex_test3.b       tbl_regex_test3.c       tbl_regex_test3.d       tbl_regex_test3.e       tbl_regex_test3.f       tbl_regex_test3.g    tbl_regex_test3.h        tbl_regex_test3.i
NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
Time taken: 0.047 seconds, Fetched: 2 row(s)
hive>

场景2:只删除错误的正则表达式。
输入数据

[user1@server1 ~]$ hdfs dfs -cat /user/user1/hive_poc/hive/file1.txt
25Oct2016:103130.123456 [1234567a3] 0.522550 1.244476 TCP_PARTIAL_HIT 206 65871 0 GET 10.10.10.199 11.11.11.11:80
25Oct2016:103130.654321 [1234567e8] 0.144449 0.178851 TCP_MISS 200 7035 0 GET 5.5.5.5 10.20.30.40:80 http://stackoverflow.com/questions/23668713/getting-null-values-in-hive-create-load-query-with-regex
[user1@server1 ~]$

配置单元创建表语句

hive> CREATE EXTERNAL TABLE tbl_regex_test2 (
    > a STRING,
    > b STRING,
    > c STRING,
    > d STRING,
    > e STRING,
    > f STRING,
    > g STRING,
    > h STRING,
    > i STRING
    > )
    > ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
    > WITH SERDEPROPERTIES ( 'input.regex' =  '(\\d+\\w+\\d+)\\:.*?\\[.*?\\]\\s(\\d+\\.\\d+)\\s(\\d+\\.\\d+)\\s\\w*\\s\\d*\\s(\\d*)\\s\\d\\s\\w*\\s(((?:[0-9]{1,3}\\.){3}[0-9]{1,3}))\\s(((?:[0-9]{1,3}\\.){3}[0-9]{1,3}))\\:\\d*',
    > 'output.format.string' = "%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s")
    > LOCATION '/user/user1/hive_poc/hive';
OK
Time taken: 0.134 seconds

结果:仅从第一行获取数据,第二行为空,因为它与输入regex不匹配。

hive> set hive.cli.print.header=true;
hive> add jar /home/user1/hive-contrib-0.10.0-cdh4.2.0.jar;
Added [/home/user1/hive-contrib-0.10.0-cdh4.2.0.jar] to class path
Added resources: [/home/user1/hive-contrib-0.10.0-cdh4.2.0.jar]
hive> select * from tbl_regex_test2;
OK
tbl_regex_test2.a       tbl_regex_test2.b       tbl_regex_test2.c       tbl_regex_test2.d       tbl_regex_test2.e       tbl_regex_test2.f       tbl_regex_test2.g    tbl_regex_test2.h        tbl_regex_test2.i
25Oct2016       0.522550        1.244476        65871   10.10.10.199    10.10.10.199    11.11.11.11     11.11.11.11     NULL
NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL    NULL
Time taken: 0.046 seconds, Fetched: 2 row(s)
hive>

场景3:从数据中删除url部分并删除错误的regex。
输入数据

[user1@server1 ~]$ hdfs dfs -cat /user/user1/hive_poc/hive1/file.log
25Oct2016:103130.123456 [1234567a3] 0.522550 1.244476 TCP_PARTIAL_HIT 206 65871 0 GET 10.10.10.199 11.11.11.11:80
25Oct2016:103130.654321 [1234567e8] 0.144449 0.178851 TCP_MISS 200 7035 0 GET 5.5.5.5 10.20.30.40:80
[user1@server1 ~]$

配置单元创建表语句

hive> CREATE EXTERNAL TABLE tbl_regex_test1 (
    > a STRING,
    > b STRING,
    > c STRING,
    > d STRING,
    > e STRING,
    > f STRING,
    > g STRING,
    > h STRING,
    > i STRING
    > )
    > ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe'
    > WITH SERDEPROPERTIES ( 'input.regex' =  '(\\d+\\w+\\d+)\\:.*?\\[.*?\\]\\s(\\d+\\.\\d+)\\s(\\d+\\.\\d+)\\s\\w*\\s\\d*\\s(\\d*)\\s\\d\\s\\w*\\s(((?:[0-9]{1,3}\\.){3}[0-9]{1,3}))\\s(((?:[0-9]{1,3}\\.){3}[0-9]{1,3}))\\:\\d*',
    > 'output.format.string' = "%1$s %2$s %3$s %4$s %5$s %6$s %7$s %8$s %9$s")
    > LOCATION '/user/user1/hive_poc/hive1';
OK
Time taken: 0.15 seconds
hive>

结果:太好了!它从两行获取记录。

hive> set hive.cli.print.header=true;
hive> add jar /home/user1/hive-contrib-0.10.0-cdh4.2.0.jar;
Added [/home/user1/hive-contrib-0.10.0-cdh4.2.0.jar] to class path
Added resources: [/home/user1/hive-contrib-0.10.0-cdh4.2.0.jar]
hive> select * from tbl_regex_test1;
OK
tbl_regex_test1.a       tbl_regex_test1.b       tbl_regex_test1.c       tbl_regex_test1.d       tbl_regex_test1.e       tbl_regex_test1.f       tbl_regex_test1.g    tbl_regex_test1.h        tbl_regex_test1.i
25Oct2016       0.522550        1.244476        65871   10.10.10.199    10.10.10.199    11.11.11.11     11.11.11.11     NULL
25Oct2016       0.144449        0.178851        7035    5.5.5.5 5.5.5.5 10.20.30.40     10.20.30.40     NULL
Time taken: 0.057 seconds, Fetched: 2 row(s)
hive>

根据以上结果,我得出结论,您使用的regex无法获取url,或者它与这个配置单元serde不兼容。
当我使用在线正则表达式编译器验证regex并从第二行得到结果时,我再次感到惊讶。请看下图了解更多说明

其结果是:

从上面的结果,我悬而未决的决定,这是一个serde问题或正则表达式的问题,并将等待一些其他答案。
另一方面,我们应该避免在hive中使用正则表达式技术,因为它与数据的位置紧密耦合,并且可以随着输入数据的微小变化而中断。

相关问题