【问题标题】:Hadoop data flow efficiency for "customers who bought x also bought y"“买了 x 的客户也买了 y”的 Hadoop 数据流效率
【发布时间】:2012-03-19 16:34:38
【问题描述】:

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

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

据我所知,如果 Hadoop 中的一个主要性能限制因素是将数据从映射器节点转移到减速器节点,那么对于 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 技巧来组织工作流来帮助我在第二步中缩小数据混洗?在这种情况下,我担心随机播放大小是否合适?

谢谢!

【问题讨论】:

  • 我很确定“购买 x 的客户也购买了 y”可以通过一个 mapreduce 作业来计算。不能直接从数据库中导出加入的数据吗?
  • 是的,你是对的。我可能会更新我的问题以简化。

标签: hadoop


【解决方案1】:

根据您的产品集有多大(因此定义可能的产品对的数量),您可以查看地图端的“本地”聚合。

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

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

当然,如果您有大量产品集或随机产品配对,这不会为您节省那么多。您还需要了解在您的可用 JVM 内存到期之前您的地图可以变得多大。

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

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

【讨论】:

  • 感谢您的提示。我没有做任何这些优化,所以这些肯定会有所帮助。
猜你喜欢
  • 2010-12-31
  • 2011-06-08
  • 1970-01-01
  • 2020-07-30
  • 1970-01-01
  • 2022-11-15
  • 2021-12-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多