使用预先排序的数据加速 Hive 或 Pig 聚合

Posted

技术标签:

【中文标题】使用预先排序的数据加速 Hive 或 Pig 聚合【英文标题】:Speed up Hive or Pig aggregation by using pre-sorted data 【发布时间】:2015-06-27 15:26:19 【问题描述】:

我想加速 Amazon EMR 上的简单 Apache Hive (0.13.1) 或 Pig(版本 0.12.0)聚合作业。我的数据已经按需要聚合的键排序,我希望作业能够使用它。

蜂巢:

[..some 'set' calls etc...]
CREATE EXTERNAL TABLE ngrams (gram string, year int, occurrences bigint,pages bigint, books bigint)
  ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
  STORED AS TEXTFILE
  LOCATION 's3://mybucket/3gram/';
INSERT OVERWRITE TABLE s3 select gram, sum(occurrences) from ngrams where year >= 1910 group by gram;

对于 Hive,我找不到告诉它数据已经排序的方法。

猪:

ngrams = LOAD 's3://mybucket/3gram/' AS (ngram:chararray, year:int, counter:int, pages:int);
filtered = FILTER ngrams BY year >= 1910;
grouped = GROUP filtered BY (ngram);
summed = FOREACH grouped GENERATE group, SUM(filtered.counter);

对于 Pig,我发现 GROUP ... USING 'collected' 应该使用排序,但我得到:

While using 'collected' on group; data must be loaded via loader implementing CollectableLoadFunc

那么我怎样才能以排序的方式加载数据呢?我在网上找到了 LOADUSING org.apache.hadoop.zebra.pig.TableLoader() 的例子,但 Pig 抱怨它不知道那个类。

【问题讨论】:

您能提供一个完整的 PIG 脚本示例吗? 猪的例子已经差不多完成了,只有最后一个store summed into 's3://mybucket/3gram-pig-output'; 它是,除了使用 zebra TableLoader 加载数据的加载阶段。 我试过ngrams = LOAD 's3://mybucket/3gram/' USING org.apache.hadoop.zebra.pig.TableLoader('ngram, year, counter, pages', 'sorted');(在本地,而不是在 AWS 中 - 当我在 AWS 中尝试时,作业失败,但我还没有找到有用的错误消息) 【参考方案1】:

首先,如果它不是 hadoop 的一部分,您需要 REGISTERzebra。

如果你需要构建jar:

    获取PIG 12.0的源码 编译猪

    编译斑马(ant zebra)

    注册 '/yourpath/pig-0.12.0/build/contrib/zebra/zebra-0.8.0-dev.jar';

其次,据我所知(并尝试过),您不能使用 TableLoader 使用行格式(通常的文本文件)LOAD 数据。数据必须事先使用 TableStorer 存储,后者将以面向列的格式写入数据,包括架构。

您可以试试这个并检查输出/错误:

ngrams_row = LOAD 's3://mybucket/3gram/' AS (ngram: chararray, year:int, counter: int, pages: int);
STORE ngrams_row INTO 's3://mybucket/3gram-zebra/' using org.apache.hadoop.zebra.pig.TableStorer('[ngram];[year,counter,pages]');
ngrams_zebra = LOAD 's3://mybucket/3gram-zebra/' USING org.apache.hadoop.zebra.pig.TableLoader('ngram,year,counter,pages', 'sorted'); 

DESCRIBE ngrams_zebra;
DUMP ngrams_zebra;

【讨论】:

谢谢,转换步骤有效,但后来我得到java.io.IOException: The table is not sorted。对数据进行排序,可能与 zebra 预期的方式不同。另外,我看到 zebra 已被弃用 (issues.apache.org/jira/browse/PIG-3996),最初的想法是加速聚合,我不确定如果我还有另一个步骤可以运行。 如果你必须写和读一次,这不是一个好主意。但是,如果您有可以写入一次并读取数千次的数据,那么它可能是有意义的。关于排序问题,在存储之前尝试按ngrams排序。

以上是关于使用预先排序的数据加速 Hive 或 Pig 聚合的主要内容,如果未能解决你的问题,请参考以下文章

使用 Hive 或 Pig 在字段中查找重复次数最多的值

Hive 或 Pig 动态表

使用 AWS Elastic MapReduce 获取时间序列数据的 Hive、HBase 和 Pig

使用 PIG 或 HIVE 从 CSV 中删除前两行

何时使用 Hadoop、HBase、Hive 和 Pig?

PL/SQL 能否可靠地转换为 Pig Latin 或带有 Pig Latin 和 Hive 的 Oozie 管道