我开始使用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技巧来组织工作流程,这有助于我在第二步中收缩数据?在这种情况下,我是否担心随机播放尺寸适合?
谢谢!
答案 0 :(得分:1)
根据您的产品设置的大小(因此定义可能的产品对的数量),您可以查看地图方面的“本地”聚合。
在映射器中维护产品对的映射到频率计数,而不是将每个产品对和值1写入上下文,将它们累积在映射中。当地图达到预定义大小时,将地图刷新到输出上下文。您甚至可以使用LRU映射来保持地图中最常观察到的对,并在强制退出时写出那些“过期”条目。
有关适用于字数统计示例的示例,请参阅http://www.wikidoop.com/wiki/Hadoop/MapReduce/Mapper#Map_Aggregation
当然,如果您拥有庞大的产品组合或随机产品配对,这不会为您节省太多。您还需要了解在可用的JVM内存到期之前地图的大小。
您还可以考虑减少输出键/值对象中存储的数据量: