【问题标题】:Pig load files using tuple's fieldPig 使用元组的字段加载文件
【发布时间】:2014-09-25 17:38:51
【问题描述】:

我需要以下用例的帮助:

最初我们会加载一些文件并处理这些记录(或更严格地说是元组)。经过这样的处理,最后我们得到了以下形式的元组:

(some_field_1, hdfs://localhost:9000/user/kailashgupta/data/1/part-r-00000, some_field_3)
(some_field_1, hdfs://localhost:9000/user/kailashgupta/data/2/part-r-00000, some_field_3)
(some_field_1, hdfs://localhost:9000/user/kailashgupta/data/1/part-r-00001, some_field_3)

所以基本上,元组将文件路径作为其字段的值(我们显然可以将这个只有一个字段的元组以文件路径作为值或转换为只有一个字段的单个元组,并带有一些分隔符(比如逗号)分隔字符串)。

所以现在我必须在 Pig 脚本中加载这些文件,但我无法这样做。您能否建议如何进一步进行。我想到了使用高级foreach 运算符并尝试如下:

data = foreach tuples_with_file_info {
    fileData = load $2 using PigStorage(',');
    ....
    ....
};

但它不起作用。

编辑: 为简单起见,假设我有一个单元组,其中一个字段具有文件名:

(hdfs://localhost:9000/user/kailashgupta/data/1/part-r-00000)

【问题讨论】:

  • 您不能在嵌套的 FOREACH 中编写 LOAD 语句,它不支持。
  • @Gaurav,还有其他解决方案吗?
  • 也许,预处理文件并将它们放在 1 目录下?或者创建具有多个加载函数的动态 PIG 脚本 - 每个文件 1 个 - 然后将所有数据源联合起来?
  • 我确实理解了这个问题。您的一个 i/p 数据确定输入文件路径,并且您要加载这些文件。我的上述评论仍然有效。
  • @GauravPhapale,我们无法预处理,因为当时不知道要选择哪个文件。此信息是在运行时从其他输入中提取的。您能否阐明“创建具有多个加载功能的动态 PIG 脚本 - 每个文件 1 个”的意思?

标签: hadoop mapreduce apache-pig


【解决方案1】:

您不能使用开箱即用的 Pig 来执行此操作。

我要做的是使用其他一些脚本语言(bash、Python、Ruby...)从 hdfs 读取文件并将文件连接成单个字符串,然后您可以将其作为参数推送到 Pig 脚本在您的 LOAD 语句中使用。 Pig 支持 globbing,因此您可以执行以下操作:

a = LOAD '{hdfs://localhost:9000/user/kailashgupta/data/1/part-r-00000,hdfs://localhost:9000/user/kailashgupta/data/2/part-r-00000}' ...

所以剩下要做的就是读取包含这些文件名的文件,将它们连接成一个 glob,例如:

{hdfs://localhost:9000/user/kailashgupta/data/1/part-r-00000,hdfs://localhost:9000/user/kailashgupta/data/2/part-r-00000}

并将其作为参数传递给 Pig,以便您的脚本以:

a = LOAD '$input'

你的猪叫声看起来像这样:

pig -f script.pig -param input={hdfs://localhost:9000/user/kailashgupta/data/1/part-r-00000,hdfs://localhost:9000/user/kailashgupta/data/2/part-r-00000}

【讨论】:

  • 感谢您的解决方案。使用 Pig 版本 0.12.0(6 年后),它不适用于花括号,但它通过连接没有花括号的文件名来工作。对于使用更高版本的 Pig 阅读此解决方案的人们,这是仅供参考。
【解决方案2】:

首先,将tuples_with_file_info 存储到某个文件中:

STORE tuples_with_file_info INTO 'some_temporary_file';

那么,

data = LOAD 'some_temporary_file' using MyCustomLoader();

在哪里 MyCustomLoader 只不过是一个扩展LoadFuncPig 加载程序,它使用MyInputFormat 作为InputFormat

MyInputFormat 是对实际 InputFormat(例如 TextInputFormat)的封装,它必须用于从文件中读取实际数据(例如,在我的情况下,来自文件 hdfs://localhost:9000/user/kailashgupta/数据/1/part-r-00000)。

MyInputFormat 中,覆盖getSplits 方法;首先从some_temporary_file 中读取实际文件名(您必须从Configurationmapred.input.dir 属性中获取此文件名),然后使用检索到的文件名更新相同的Configuration mapred.input.dir,然后从包装好的 InputFormat 返回结果(例如,在我的情况下为 TextInputFormat)。

注意: 1. 您不能使用LoadFunc 中的setLocation API(或其他类似的API)来读取some_temporary_file 的内容,因为它的内容将只可用在运行时。 2.你可能会产生一个疑问,如果LOAD语句在STORE之前执行怎么办?但这不会发生,因为如果STORELOAD 在脚本中使用相同的文件,Pig 会确保作业以正确的顺序执行。有关更多详细信息,您可以阅读Pig Wiki

上的存储加载序列部分

【讨论】:

    猜你喜欢
    • 2011-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多