蜂巢:由和 SERDEPROPERTIES 分区

Hive: PARTITIONED BY and SERDEPROPERTIES

我正在尝试创建一个由单个字段分区的配置单元 table。我要处理的数据是日志数据。日志格式为:

DATE TIME IPAddress HTTP_METHOD MESSAGE

创建 table 配置单元查询:

CREATE EXTERNAL TABLE test_Part(
logdate string,
logtime string,
ip string,
message string)
PARTITIONED BY(method string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "(\d{4}-\d{2}-\d{2})\s(\d{2}:\d{2}:\d{2})\s(\d+\.\d+\.\d+\.\d+)\s(\S+)\s(.*$)",
"output.format.string" = "%1$s %2$s %3$s %5$s %4$s"
)
STORED AS TEXTFILE;

并加载脚本:

LOAD DATA LOCAL INPATH '/home/user/tools/apache-hive-1.2.2-bin/scripts/sample1.log' OVERWRITE INTO TABLE test_Part PARTITION(method='GET');

当我 运行 对上述 table 进行 select 查询时,它给我的错误消息是

Failed with exception java.io.IOException:org.apache.hadoop.hive.serde2.SerDeException: Number of matching groups doesn't match the number of columns

我错过了什么?

应该是 4 组,因为 table DDL 中有 4 列。在您的正则表达式中有 5 个组。 method是一个分区(有文件的目录),该列通常在文件本身中不存在,您不需要在正则表达式中指定它。

分区存储为包含分区位置和键值的元数据。 位置看起来像 table_dir/method=GET/

在此处查看很好的示例: http://www.dowdandassociates.com/blog/content/howto-use-hive-with-apache-logs/

如果分区列也存在于文件中,您应该在 table 定义中添加更多列。似乎专栏存在。是HTTP_METHOD吗?然后只需在消息列之前再添加一列 HTTP_METHOD 并再次检查您的正则表达式。

分区反映了一种情况,在这种情况下,可以直接访问以特定值(分区列值)为特征的行,而无需访问额外的不必要数据。
此处显然不是这种情况,因此您不能在数据文件上声明分区 table。

从现在开始,您可以执行以下操作:

1.

省略分区。

CREATE EXTERNAL TABLE test_Part_stg(
logdate string,
logtime string,
ip string,
method string,
message string)
ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.RegexSerDe'
WITH SERDEPROPERTIES (
"input.regex" = "(\d{4}-\d{2}-\d{2})\s(\d{2}:\d{2}:\d{2})\s(\d+\.\d+\.\d+\.\d+)\s(\S+)\s(.*$)"
)
STORED AS TEXTFILE;

2。 (可选)

创建一个额外的分区 table 并使用上一步的 table 填充它。

(这个table存储不必是TEXTFILE)

CREATE EXTERNAL TABLE test_Part(
logdate string,
logtime string,
ip string,
message string)
PARTITIONED BY(method string)
STORED AS TEXTFILE;

set hive.exec.dynamic.partition.mode=nonstrict
;

insert into test_Part partition (method)
select logdate,logtime,ip,message,method 
from   test_Part_stg
;

insert into test_Part partition (method) (logdate,logtime,ip,method,message)
select * 
from   test_Part_stg
;

P.s.

output.format.string 已弃用,它未在 RegexSerDe 中定义,并且与任何其他未定义的 SerDe 参数一样没有功能意义。