“购买x的客户也买了y”的Hadoop数据流效率

时间:2012-03-19 16:34:39

标签: hadoop

我开始使用Hadoop,并正在为“购买x也购买了y的客户”构建MapReduce链,其中y是最常用x购买的产品。我正在寻找有关提高此任务效率的建议,我的意思是减少从映射器节点到减速器节点的数据量。我的目标与其他“客户购买的x”方案略有不同,因为我只想存储给定产品的最常购买的产品,而不是按给定产品排序的产品列表频率。

我正在关注this blog post来指导我的方法。

据我了解,如果Hadoop中的一个重要性能限制器是将数据从映射器节点转移到reducer节点,那么,对于MapReduce链的每个阶段,我都希望将洗牌数据的数量保持在最小。

假设我的初始数据集是一个SQL表purchases_products,它是购买产品与购买产品之间的连接表。我会将select x.product_id, y.product_id from purchases_products x inner join purchases_products y on x.purchase_id = y.purchase_id and x.product_id != y.product_id提供给我的MapReduce操作。

我的MapReduce策略是将product_id_x, product_id_y映射到product_id_x_product_id_y, 1,然后将我的reduce步骤中的值相加。最后,我可以将密钥和存储对分割回SQL表。

我对这个操作的问题在于,它会对可能存在的大量行进行混洗,即使我想要生成的结果集的大小只有count(products)大。理想情况下,我想让一个组合器步骤缩小在这个阶段中拖曳到减速器的行数,但我没有办法可靠地做到这一点。

这仅仅是对手头任务的限制,还是有Hadoop技巧来组织工作流程,这有助于我在第二步中收缩数据?在这种情况下,我是否担心随机播放尺寸适合?

谢谢!

1 个答案:

答案 0 :(得分:1)

根据您的产品设置的大小(因此定义可能的产品对的数量),您可以查看地图方面的“本地”聚合。

在映射器中维护产品对的映射到频率计数,而不是将每个产品对和值1写入上下文,将它们累积在映射中。当地图达到预定义大小时,将地图刷新到输出上下文。您甚至可以使用LRU映射来保持地图中最常观察到的对,并在强制退出时写出那些“过期”条目。

有关适用于字数统计示例的示例,请参阅http://www.wikidoop.com/wiki/Hadoop/MapReduce/Mapper#Map_Aggregation

当然,如果您拥有庞大的产品组合或随机产品配对,这不会为您节省太多。您还需要了解在可用的JVM内存到期之前地图的大小。

您还可以考虑减少输出键/值对象中存储的数据量:

  • 产品ID是否为整数(它们的价值相对较低 - 它们是否可以从写入VIntWritable而非IntWritable中获益?)
  • 如果它们是整数,您是将产品对密钥写为连接ID的字符串表示形式,还是使用带有两个int字段的自定义密钥(因此,如果使用,则写入4 + 4字节而不是可能更大的数字字符串表示)
  • 您是否将值'1'作为VIntWritable写出来?