【51CTO.com快译】Pig与Hive已经成为企业实现大规模数据交互的必要工具,其突出优势在于无需编写复杂的MapReduce代码。作为Hadoop生态系统中的重要力量,这两款组件都提供一套立足于核心执行程序的抽象层。Hive的初步设计思路在于提供与SQL类似的使用体验,同时简化了RDBMS的过渡流程。Pig则拥有更多规程化方案,旨在帮助使用者在无需编写MapReduce的前提下实现数据操作。
本篇文章将通过示例及代码对Pig与Hive进行一番全面比较。
Hive的固有优势
Apache Hive是一款极为强大的大数据组件,其主要长项在于数据整理与提取。在处理已经存在关联模式的数据时,Hive拥有极为出色的表现。另外,Hive metastore工具还能够根据用户指定的条件对全部数据进行划分,这将进一步提升数据的检索速度。然而,在利用大量分区进行单一查询时,大家需要当心Hive可能造成的以下问题:
1)查询当中分区数量的增加意味着与之相关的路径数量亦将同步增加。我们假设在某一用例当中,某条查询需要指向一套包含10000个***分区的表,且其中各个分区又包含更多嵌套分区。有些朋友可能已经意识到,Hive在这时会尝试在任务配置中为全部分区设置路径,同时将该查询转译为MapReduce任务。因此,分区数量会直接影响到任务的自身大小。由于默认jobconf的大小为5 MB,因此超出这一上限将引发运行时执行错误。举例来说,其可能显示“java.io.IOException: Exceeded max jobconf size: 14762369 limit: 5242880”。大家可以点击此处查看更多相关细节信息。
2)通过“MSCK REPAIR TABLE 表名称”实现的批量分区注册(例如10000 x 100000个分区)同样会受到Hadoop Heap大小以及GCOverheadlimit的限制。超出这一上限显然会导致错误或者如下所示的stackoverflow执行崩溃错误:
Exception in thread "main" java.lang.StackOverflowError
at org.datanucleus.query.expression.ExpressionCompiler.isOperator(ExpressionCompiler.java:819)
at org.datanucleus.query.expression.ExpressionCompiler.compileOrAndExpression(ExpressionCompiler.java:190)
at org.datanucleus.query.expression.ExpressionCompiler.compileExpression(ExpressionCompiler.java:179)
at org.datanucleus.query.expression.ExpressionCompiler.compileOrAndExpression(ExpressionCompiler.java:192)
at org.datanucleus.query.expression.ExpressionCompiler.compileExpression(ExpressionCompiler.java:179)
3)利用更为复杂的多层操作,例如接入多个分区,也同样有其局限性。大规模查询可能由于Hive编译器利用metastore进行语义验证时发生错误。这是因为Hive metastore在本质上属于一类SQL模式存储,因此大规模查询可能引发以下错误:“com.mysql.jbdc.PacketTooBigException: Packet for query is too large”。
包括jobconf大小、Hadoop Heap大小以及数据包大小在内的各类属性显然无法进行配置。为了避免这些问题,我们应当更好地设计语义,而非频繁改变配置。
Hive的优势在于其基于HDFS上的数据系统模式而设计完成。其能够在各可接受分区内容纳大量数据,但却不适合利用大量分区分别容纳少量数据。毕竟分区的存在意义在于加快特定数据查询速度,而不需要对整体数据集进行操作。分区数量的减少,意味着我们能够实现***负载并***程度提升集群资源利用率。
何时使用Pig
Apache Pig的胃口可以用“毫不挑食”来形容,其能够消费各种数据类型,包括结构化、半结构化以及非结构化。与Hive不同,Pig不会使用任何相关metastore,但却能够利用Hive中的Hcatalog。事实上,Pig的设计初衷正是为了立足于大规模数据集执行复杂的可扩展操作,因为其能够随时随地进行自我优化。尽管Pig看起来采用多级脚本结构,但其各项内部操作都会在执行时得到优化,这就显著减少了数据的实际扫描次数。
下面我们仍然以10000个分区为例,考虑其在Pig中的处理效果。在这种情况下,由于不涉及metastore,因此分区概念完全不会限制Pig的执行。要使用Hive中的Hcatalog,我们可以在Pig中运用以下脚本(这里我们使用的是Pig 0.15版本):
/* myscript.pig */
A = LOAD 'tablename' USING org.apache.hive.hcatalog.pig.HCatLoader();
-- date is a partition column; age is not
B = filter A by date == '20100819' and age < 30;
-- both date and country are partition columns
C = filter A by date == '20100819' and country == 'US';
...
不过如果假定这里存在无数个分区,且我们打算利用Hcatalog通过单一请求对其进行全部查询,那么Pig也将遭遇与Hive类似的问题。在这种情况下,使用glob与通配符来表达可能更为方便。
例如:
Partition-1, Partition-2, Partition-3,....Partition-n exist within the location /user/inputLocation/
Using globs we can provide the input to Pig as:
/user/inputLocation/{Partition-1, Partition-2, Partition-3,....Partition-n}
And with wildcards it would be:
/user/inputLocation/*
And in case of nested partitions, we can have a combination of globs and wildcards, such as:
/user/inputLocation/{Partition-1,Partition-2, Partition-3,....Partition-n}/*
Pig能够顺利从对应位置读取数据,并在操作执行当中对其加以优化。如此一来,Pig面临的惟一障碍就是集群资源的不可用性。除此之外,在对数据进行大量变换的情况下,Apache Pig的表现可以说***。
Hive与Pig间的对决
以下信息能够帮助大家了解Hive与Pig各自的设计思路与工作原理。
Hive:
Apache Hive在本质上属于一套数据仓储平台,用于同存储在HDFS或者HBase内的大规模结构化数据集进行交互。Hive查询语言在这一点上类似于SQL,二者都能够与Hadoop实现良好集成。而Pig则不同,其执行流程为纯声明性,因此适合供数据科学家用于实现数据呈现与分析。
在与Hive进行交互时,用户可以直接通过Hive命令行界面直接接入,或者与Hiveserver交互。任何提交查询都会首先由该驱动程序占用,而后由编译器进行语法及语义验证。另外,Hive metastore负责保存全部与Hive相关数据的模式/映射关系,其在验证查询中信息语义方面扮演着重要角色。该驱动立足于语义之上执行优化,同时负责准备执行规划并将其提交至HQL查询引擎。这套引擎依赖于实际执行引擎(例如MapReduce与Spark等)。任何对模式的成功修改都会通过HQL处理引擎被更新至metastore当中。
大家可以参阅更多细节信息:
https://en.wikipedia.org/wiki/Apache_Hive
Pig:
Apache PIG提供一套高级语言平台,用于对结构化与非结构化数据集进行操作与分析。这种语言被称为Pig Latin,其属于一种脚本形式,可直接立足于PIG shell执行或者通过Pig Server进行触发。用户所创建的脚本会在初始阶段由Pig Latin处理引擎进行语义有效性解析,而后被转换为包含整体执行初始逻辑的定向非循环图(简称DAG)。另外,这套处理引擎亦可接受DAG并在内部执行计划优化——具体优化方式包括PIG程序方法以及惰性计算。
为了理解这一优化机制的原理,我们假定用户编写了一套脚本,该脚本对两套数据集进行一项连接操作,而后是一条过滤标准。PIG优化器能够验证过滤操作是否能够在连接之前进行,从而保证连接负载最小化。如果可以,则其将据此进行逻辑规划设计。如此一来,用户即可专注于最终结果,而非将精力分散在性能保障身上。
只有在经过完全优化的逻辑规划准备就绪之后,编译才会生效。其负责生成物理规划,即为最终驻留于HDFS中的数据分配与之交互的执行引擎。
总结:
Pig与Hive无疑已经成为大数据世界中的重要组成部分。二者皆提供出色的灵活性以及可扩展性,用于实现各类定制化功能。另外,二者也拥有自己的明确角色定位,因此其具体优劣完全取决于您在项目当中的实际要求。
【51CTO译稿,合作站点转载请注明原文译者和出处为51CTO.com】