我最近一直在广泛使用Hive,想知道是否有办法改进以下工作流程。
每晚从我们的Oracle集群中导出一个以制表符分隔的未压缩文本文件到HDFS上,然后由Hive进行处理。
我是这样加载表格的:
CREATE EXTERNAL TABLE ACCOUNTINGTABLE (
ts STRING,
duid STRING,
owner STRING,
hidden STRING,
lgroup STRING,
nbfiles INT,
length BIGINT,
replicas INT,
provenance STRING,
state STRING,
campaign STRING,
rlength BIGINT,
rnbfiles INT,
rowner STRING,
rgroup STRING,
rarchived STRING,
rsuspicious STRING,
name STRING,
ami STRING,
site STRING)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n'
LOCATION '/user/accounting/dump';
LOAD DATA INPATH '/user/accounting/dump_REPLACEWITHTIMESTAMP.lst' INTO TABLE ACCOUNTINGTABLE;
然后运行多个类似这样的会计摘要,以生成文本输出进行后处理:
set hive.exec.reducers.max=90;
CREATE EXTERNAL TABLE ACCOUNTINGTABLE_site_project_datatype_tag (
ts STRING,
project STRING,
datatype STRING,
tag STRING,
site STRING,
duids INT,
replicas INT,
nbfiles INT,
rnbfiles INT,
length BIGINT,
rlength BIGINT)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n'
LOCATION '/user/accounting/summary/REPLACEWITHTIMESTAMP/site_project_datatype_tag';
INSERT OVERWRITE TABLE ACCOUNTINGTABLE_site_project_datatype_tag
SELECT
'REPLACEWITHTIMESTAMP',
regexp_extract(name, '^(?:(?!\2)([^.]*)(?:\.|$())){1}', 1),
regexp_extract(name, '^(?:(?!\2)([^.]*)(?:\.|$())){5}', 1),
split(regexp_extract(name, '^(?:(?!\2)([^.]*)(?:\.|$())){6}', 1), '_tid')[0],
site,
count(distinct duid),
sum(replicas),
sum(nbfiles),
sum(rnbfiles),
sum(length),
sum(rlength)
from
ACCOUNTINGTABLE
where
(
ami='project.datasetnumber.physicsshort.prodstep.datatype.version'
or
ami='project.runnumber.streamname.prodstep.datatype.version'
)
group by
'REPLACEWITHTIMESTAMP',
regexp_extract(name, '^(?:(?!\2)([^.]*)(?:\.|$())){1}', 1),
regexp_extract(name, '^(?:(?!\2)([^.]*)(?:\.|$())){5}', 1),
split(regexp_extract(name, '^(?:(?!\2)([^.]*)(?:\.|$())){6}', 1), '_tid')[0],
site;
DROP TABLE ACCOUNTINGTABLE_site_project_datatype_tag;
现在: Oracle转储文件的平均大小约为5GB(并不是很大),包含大约2.5亿行。摘要不超过1-2 MB。 如上所述,平均Hive作业需要大约一个小时才能运行。映射阶段进展非常顺利,在约15分钟后就达到了100%,但是reduce阶段几乎始终需要45分钟,并且一直显示100%。 现在我们逐渐添加了越来越多不同的摘要,很快我们将达到24小时的摘要处理的魔法极限。我们的基础设施监视还显示节点利用率低(cpu〜30-40%,io〜10%)。 我尝试过调整io.sort.mb,io.sort.factor等参数,但几乎总是使事情变得更糟。因此,现在我正在运行Hadoop默认值(顺便说一下,这是Cloudera发行版)。集群有12个节点(8核心),每个节点配置有24GB内存和2TB磁盘,配置为8个mappers,8个reducers(namenode上为6/6)。 我还尝试创建一个临时表作为压缩的sequencefile,并使用INSERT INTO SELECT,但那个INSERT太长时间了... 我怀疑工作流本身可能存在问题,而不仅仅是集群/配置。 欢迎任何建议。