regex - 使用正则表达式在Apache Hive中创建表将返回所有NULL值

标签 regex hadoop hive

我有很多日志文件* .log,我想使用以下语法导入到Hive表:

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

请纠正我的错误。

谢谢。

最佳答案

在您的情况下,正则表达式(\\s(?:-|http:\\/\\/|www\\.|https:\\/\\/)([^\\/]+))对于您使用的Serde似乎有问题。您正在使用的Serde似乎无法编译正则表达式的那些部分,因此它限制了数据的获取。

我尝试了多种情况,其结果如下。

方案1:在Data和regEx中未做任何修改

输入数据

[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:仅删除了有问题的regEx。

输入数据
[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或与该Hive Serde不兼容。

当我使用online regular expression compiler验证regEx并从第二行得到结果时,我再次感到惊讶。请参阅下图以获取更多说明

enter image description here

其结果是:
enter image description here

根据以上结果,我想确定这是一个SERDE问题还是正则表达式问题,并且还将等待其他答案。

另一方面,我们应该避免在 hive 中使用正则表达式技术,因为它与数据的位置紧密相关,并且可能因输入数据的微小变化而中断。

关于regex - 使用正则表达式在Apache Hive中创建表将返回所有NULL值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41208305/

相关文章:

c++ - 正则表达式匹配 url 权限部分

php - 如何使用preg_match提取数据?

hadoop - EMRFS 是否使 S3 对外部客户端保持一致

apache-spark - Spark 数据框列命名约定/限制

performance - Hive 联合所有效率和最佳实践

hadoop - MapReduce 现实生活中的用途

c++ - 如何对 vector 中的字符串进行模式匹配?

c# - 计算文本文件中特定单词的频率

hadoop - Hive ORC 压缩

hadoop - 如何选择 hive 中不按句子分组的列?