在 Hadoop Hive 中优化几 GB 的数据
Posted
技术标签:
【中文标题】在 Hadoop Hive 中优化几 GB 的数据【英文标题】:Optimizing few GB of data in Hadoop Hive 【发布时间】:2012-01-17 15:21:44 【问题描述】:我现在已经非常广泛地使用 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%,但随后减少几乎需要 45 分钟,一直显示 100%。 现在我们逐渐添加了越来越多不同的摘要,很快我们将达到 24 小时摘要处理的神奇限制。我们的基础设施监控还显示节点利用率较低(cpu ~30-40%,io ~10%)。
我尝试过使用 io.sort.mb、io.sort.factor 等……但这几乎总是让事情变得更糟。所以现在我正在运行 Hadoop 默认值(顺便说一句,Cloudera 发行版)。集群有 12 个节点(8 核),每个节点有 24GB 内存和 2TB 磁盘,配置为 8 个映射器、8 个减速器(6/6 在名称节点上)。
我还尝试使用 INSERT INTO SELECT 将临时表创建为压缩序列文件,但该 INSERT 耗时太长...
我怀疑工作流本身可能有问题,而不仅仅是集群/配置。
我们很乐意为您提供任何建议。
【问题讨论】:
回答我自己的问题:多组插入是解决方案。通过一些魔术,现在运行整个会计套件需要 20 分钟。 困惑 好吧,那还为时过早。再次运行同样的东西,它又回到了原来的运行时。 您的网络和磁盘利用率如何? 网络已达到极限...始终聚合 60-70MB/s,节点以 10M/s 的最大值抽水,这大约是网络可以使用的最大值。然而,磁盘利用率相当低。 IO 等待率约为 10-20%。 尝试将 mapred.compress.map.output 设置为 True。这将在您的地图输出通过网络之前对其进行压缩。 【参考方案1】:你有没有尝试过分区或索引
分区可以大大加快分组速度,因为数据在物理上按分区划分到节点上,因此减少操作大大减少,在某些情况下是即时的。
【讨论】:
我有多个与许多分区方案正交的分析,所以它并没有太大帮助。到现在为止,我已经在 Pig 中完成了。【参考方案2】:除了 Partitioning,你还可以做 Bucketing,你可以在其中指定 Sort By。
检查创建视图。这可能比没有分区的表也有帮助。
【讨论】:
以上是关于在 Hadoop Hive 中优化几 GB 的数据的主要内容,如果未能解决你的问题,请参考以下文章
016-Hadoop Hive sql语法详解6-job输入输出优化数据剪裁减少job数动态分区