无法通过在 Azure HDInsight 中运行的 piggybank.jar 使用 PIG 读取 Avro 文件

Posted

技术标签:

【中文标题】无法通过在 Azure HDInsight 中运行的 piggybank.jar 使用 PIG 读取 Avro 文件【英文标题】:Can not read Avro Files using PIG via piggybank.jar running in Azure HDInsight 【发布时间】:2013-11-21 16:58:57 【问题描述】:

尝试将一些在本地和 Hortonworks 上完美运行的现有 PIG 脚本移植到 HDInsights,但在尝试通过 Pig 的 piggybank(piggybank 包含在 HDInsight 发行版中)读取 Avro 文件时出现类未找到错误。

想知道是否有其他人让 Avro 在 HDInsight 中工作或有解决方法(例如,将哪个 jar 复制到哪里?)

更详细... 追查到这一点,我直接通过 Azure HDInsight 实例上的远程终端运行了 PIG。

我看到的错误是:java.lang.ClassNotFoundException: org.json.simple.parser.ParseException

我认为这是 https://code.google.com/p/json-simple/ 的 json-simple 库

我尝试将它添加到 HDInsight VM 中的几个位置(并在 PIG 中显式注册库),但仍然收到错误。

该错误很容易通过 RDP 重现到 HDinsight Azure 实例桌面上的 Hadoop 命令行提示符中:

详细介绍 PIG ...

c:\apps\dist\pig-0.11.0.1.3.1.0-06\bin>pig -verbose -warning

使用 AvroStorage 输入任意行。例如。

grunt> LocationRecordAvro = LOAD 'wasb:///testinput/20130901.avro' USING org.apache.pig.
piggybank.storage.avro.AvroStorage();

获取异常...

2013-11-21 16:27:53,732 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1200: Pig script failed to parse:
<line 1, column 21> pig script failed to validate: java.lang.RuntimeException: could not instantiate 'org.apache.pig.piggybank.storage.avro.AvroStorage' with arguments 'null'
2013-11-21 16:27:53,732 [main] ERROR org.apache.pig.tools.grunt.Grunt - Failed to parse: Pig script failed to parse:
<line 1, column 21> pig script failed to validate: java.lang.RuntimeException: could not instantiate 'org.apache.pig.piggybank.storage.avro.AvroStorage' with arguments 'null'
        at org.apache.pig.parser.QueryParserDriver.parse(QueryParserDriver.java:
191)
        at org.apache.pig.PigServer$Graph.validateQuery(PigServer.java:1571)
        at org.apache.pig.PigServer$Graph.registerQuery(PigServer.java:1544)
        at org.apache.pig.PigServer.registerQuery(PigServer.java:516)
        at org.apache.pig.tools.grunt.GruntParser.processPig(GruntParser.java:99
1)
        at org.apache.pig.tools.pigscript.parser.PigScriptParser.parse(PigScript
Parser.java:412)
        at org.apache.pig.tools.grunt.GruntParser.parseStopOnError(GruntParser.j
ava:194)
        at org.apache.pig.tools.grunt.GruntParser.parseStopOnError(GruntParser.j
ava:170)
        at org.apache.pig.tools.grunt.Grunt.run(Grunt.java:69)
        at org.apache.pig.Main.run(Main.java:538)
        at org.apache.pig.Main.main(Main.java:157)
Caused by:
<line 1, column 21> pig script failed to validate: java.lang.RuntimeException: could not instantiate 'org.apache.pig.piggybank.storage.avro.AvroStorage' with arguments 'null'
        at org.apache.pig.parser.LogicalPlanBuilder.buildLoadOp(LogicalPlanBuild
er.java:835)
        at org.apache.pig.parser.LogicalPlanGenerator.load_clause(LogicalPlanGen
erator.java:3236)
        at org.apache.pig.parser.LogicalPlanGenerator.op_clause(LogicalPlanGener
ator.java:1315)
        at org.apache.pig.parser.LogicalPlanGenerator.general_statement(LogicalP
lanGenerator.java:799)
        at org.apache.pig.parser.LogicalPlanGenerator.statement(LogicalPlanGener
ator.java:517)
        at org.apache.pig.parser.LogicalPlanGenerator.query(LogicalPlanGenerator
.java:392)
        at org.apache.pig.parser.QueryParserDriver.parse(QueryParserDriver.java:
184)
        ... 10 more
Caused by: java.lang.RuntimeException: could not instantiate 'org.apache.pig.piggybank.storage.avro.AvroStorage' with arguments 'null'
        at org.apache.pig.impl.PigContext.instantiateFuncFromSpec(PigContext.jav
a:618)
        at org.apache.pig.parser.LogicalPlanBuilder.buildLoadOp(LogicalPlanBuild
er.java:823)
        ... 16 more
Caused by: java.lang.NoClassDefFoundError: org/json/simple/parser/ParseException

        at java.lang.Class.getDeclaredConstructors0(Native Method)
        at java.lang.Class.privateGetDeclaredConstructors(Class.java:2404)
        at java.lang.Class.getConstructor0(Class.java:2714)
        at java.lang.Class.newInstance0(Class.java:343)
        at java.lang.Class.newInstance(Class.java:325)
        at org.apache.pig.impl.PigContext.instantiateFuncFromSpec(PigContext.jav
a:588)
        ... 17 more
Caused by: java.lang.ClassNotFoundException: org.json.simple.parser.ParseExcepti
on
        at java.net.URLClassLoader$1.run(URLClassLoader.java:366)
        at java.net.URLClassLoader$1.run(URLClassLoader.java:355)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(URLClassLoader.java:354)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:423)
        at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)
        at java.lang.ClassLoader.loadClass(ClassLoader.java:356)
        ... 23 more

grunt>

【问题讨论】:

【参考方案1】:

目前不建议在 HDInsight 中设置环境变量(例如 PIG_CLASSPATH),因为您没有头节点的管理员访问权限来执行此操作。

相反,我们可以在 HDInsight 中使用 Pig+Avro 的两个维度解决方法

A.将 Avro 和 JSON jar 放入 Windows Azure 存储 Blob,然后从那里注册它们。

B.此外,对于 Avro,创建一个与 Avro 名称不同的虚拟空类并放入 Piggybank。

类加载器没有找到必要的依赖项,因为 Avro 已经在 Piggybank 中,它不会在正确的位置搜索 JSON 依赖项。

这个障碍的细节......我相信它与Java如何使用自定义类加载器加载类有关。 Pig 实现这个 REGISTER 关键字的方式是它使用自定义类加载器,添加搜索位置以包含这些自定义 jar,但在这种情况下,包含 AvroStorage 类的 piggybank jar 已经在类路径中,因此它没有使用自定义类加载器。那么问题是,当 Pig 尝试实例化它并且它需要更多自定义 jar 时,它不使用自定义类加载器,因此它无法找到所需的类。

解决方法:为了解决这个问题,我创建了一个空类 MyAvroStroage,它只是从 AvroStorage 空继承,并将其放入自己的小 jar 中(只有 650 字节)。然后我把它和它的所有依赖项放在 WASB 上,注册它们并使用 MyAvroStorage 而不是 AvroStorage 然后一切正常。

可能的解决方法:

1.复制到 WASB 对于 A 部分,例如将 jar 复制到 WASB 作为“PigExtras”文件夹。在另一个中是这些命令(您的源位置会有所不同,而您的目标位置将是您的容器和帐户)。对于 B 部分,请指向虚拟代码 MyAvroStorage.jar 的 jar 以将其上传...

hadoop fs -copyFromLocal C:\files\MyAvroStorage.jar wasb://container@account.blob.core.windows.net/PigExtras/MyAvroStorage.jar
hadoop fs -copyFromLocal c:\apps\dist\pig-0.11.0.1.3.1.0-06\piggybank.jar wasb://container@account.blob.core.windows.net/PigExtras/piggybank.jar
hadoop fs -copyFromLocal c:\apps\dist\oozie-3.3.2.1.3.1.0-06\oozie-win-distro\share\lib\pig\avro-1.5.3.jar wasb://container@account.blob.core.windows.net/PigExtras/avro-1.5.3.jar
hadoop fs -copyFromLocal C:\apps\dist\oozie-3.3.2.1.3.1.0-06\oozie-win-distro\share\lib\oozie\json-simple-1.1.jar wasb://container@account.blob.core.windows.net/PigExtras/json-simple-1.1.jar

2。创建一个简单的复制脚本, myscript.pig,并将它也放在 Windows Azure 存储 Blob 上。您可以使用 *.jar 通配符语法注册整个文件夹。

REGISTER wasb:///PigExtras/*.jar;
myset = load 'wasb:///example/data/test.avro' using MyAvroStorage();
dump myset

然后将 .pig 也上传到 WASB

hadoop fs -copyFromLocal C:\files\myscript.pig wasb://container@account.blob.core.windows.net/PigExtras/myscript.pig

3.从客户端提交作业到集群:

$job = New-AzureHDInsightPigJobDefinition -File    wasb://container@account.blob.core.windows.net/PigExtras/myscript.pig
Start-AzureHDInsightJob -Cluster $clust.Name -Subscription $sub.SubscriptionId -JobDefinition $job -Certificate $sub.Certificate

【讨论】:

忘了提及 MyAvroStorage.class 的代码 import org.apache.pig.piggybank.storage.avro.AvroStorage;公共类 MyAvroStorage 扩展 AvroStorage 【参考方案2】:

按照 Jason 的建议进行操作,将 jars(piggybank、avro 和 json)复制到 blob 存储并在您的 pig 脚本中注册它们。但是,您不需要创建一个扩展 AvroStorage 的虚拟类。只需远程桌面到头节点并重命名/删除 C:\apps\dist\pig-0.11.0.1.3.2.0-05\piggybank.jar 以确保 pigscript 将 piggybank 文件加载到 blob 存储中。

【讨论】:

我希望 MS 可以解决这个问题,或者保留 piggybank.jar 并添加依赖项(或者对我来说更好)删除 piggyback.jar 并让用户在需要时注册。【参考方案3】:

我也有同样的问题。

我解决的方法是在pig脚本中注册json-simple-1.1.jar。

【讨论】:

以上是关于无法通过在 Azure HDInsight 中运行的 piggybank.jar 使用 PIG 读取 Avro 文件的主要内容,如果未能解决你的问题,请参考以下文章

如何通过 Azure Hdinsight 在 Visual Studio 中使用 pig

Azure HDInsight Jupyter笔记本无法正常工作

China Azure 在HDinsight 中使用Spark 功能

HDInsight:HBase 还是 Azure 表存储?

如何有效地将大数据从数据中心移动到 Azure Blob 存储,以便以后通过 HDInsight 进行处理?

带有企业安全包的 HDInsight 上的 Zeppelin 笔记本