如果我加载一个数据集,在具有parallel
子句的特定键上对其进行排序,然后存储它,我可以获得多个文件,部分-r-00000到部分-r-00XXX,具体取决于什么我在并行语句中指定。
如果我然后加载一个新的数据集,说一天的数据,一些新的密钥和一些相同的密钥,订购它,然后存储它,有没有办法保证part-r-00000来自昨天的数据将包含与今天数据部分-r-00000相同的密钥空间?
是否有办法保证所有记录都包含在单个零件文件中,或者在给定足够记录的情况下,密钥是否可以分割为2个文件?
我想这个问题实际上是关于排序函数如何在pig中工作 - 它是使用一致的hash-mod算法来分配数据,还是整个集合排序,然后将它分开?
意图或希望是,如果密钥空间一直被分区,那么对每个部分文件执行数据的滚动合并将非常容易。如果不是,我想问题就变成了,是否有一些操作员或写猪的方式来实现那种一致的哈希?
不确定我的问题是否非常明确,但我们会感激任何帮助 - 根据文档无法搞清楚。提前谢谢!
答案 0 :(得分:5)
好的,试图回答我自己的问题。
看来Pig没有办法确保将结果一致地分配到文件中。这部分是基于文档,部分基于有关hadoop如何工作的信息,部分基于观察。
当pig执行分区order-by(例如,使用PARALLEL子句获取多个reducer)时,它似乎强制在order-by之前的任何内容与排序本身之间进行中间作业。据我所知,猪看了1-10%的数据(基于中间作业中的映射器数量是加载步骤中数字的1-10%),并获得了你的密钥的样本分布试图排序。
我的猜测/思考是猪计算出密钥分配,然后使用从映射器到减速器的自定义分区器。分区器将一系列键映射到每个reducer,因此它成为一个简单的词法比较 - “这个记录是否大于我指定的end_key?将它传递给下一个reducer。”
当然,有两个因素需要考虑,这基本上意味着Pig在不同的数据集上不一致,甚至不能重新运行相同的数据集。首先,由于猪在中间工作中对数据进行采样,我想可以获得不同的样本,从而得到不同的密钥分布。另外,考虑具有广泛变化的密钥分布的两个不同数据集的示例。猪必然会想出一个不同的分布,因此如果关键的X有一天在部分-r-00111,它不一定会在第二天结束。
希望这可以帮助其他人调查此事。
修改的
我从O'Reilly那里找到了一些似乎支持我的假设的资源。
一个是关于map reduce patterns。它基本上将标准的总顺序问题描述为可通过两遍方法解决,一个“分析”阶段和一个最终分类阶段。
第二个是猪的order by。它说(如果链接死了):
正如前面“组”中所讨论的,数据中值的偏差非常常见。这会像分组一样影响顺序,导致某些减速器比其他减速器花费更长的时间。为了解决这个问题,Pig平衡了减速器的输出。它通过首先对订单语句的输入进行抽样来获得密钥分配的估计。基于此示例,它然后构建一个生成平衡总订单的分区器... Pig分配记录以最小化偏斜的方式的一个重要副作用是它违反了MapReduce约定,即给定键的所有实例都被发送到同一个分区。如果您有其他依赖于此约定的处理,请不要使用Pig的order语句为其排序数据... 此外,Pig还为您的管道添加了一个额外的MapReduce作业来进行采样。由于此抽样非常轻量级(它只读取每个块的第一个记录),因此通常只占总工作时间的5%。