当前位置:  开发笔记 > 编程语言 > 正文

我是否应该学习/使用MapReduce或其他类型的并行化来执行此任务?

如何解决《我是否应该学习/使用MapReduce或其他类型的并行化来执行此任务?》经验,为你挑选了1个好方法。

在与Google的一位朋友交谈后,我想实现某种Job/Worker模型来更新我的数据集.

此数据集镜像第三方服务的数据,因此,要进行更新,我需要对其API进行多次远程调用.我认为将花费大量时间等待第三方服务的回复.我想加快速度,更好地利用我的计算时间,通过并行化这些请求并同时保持其中许多请求,等待他们的个人响应.

在我解释我的特定数据集并解决问题之前,我想澄清一下我正在寻找的答案:

    这是一个非常适合与MapReduce并行化的流程吗?

    如果是的话,在亚马逊的mapreduce模块上运行是否具有成本效益,该模块按小时计费,并在作业完成时向上计算小时数?(我不确定究竟什么算作"工作",所以我不确切知道我将如何收费)

    如果不是,我应该使用另一种系统/模式吗?是否有一个库,这将有助于我在Python做到这一点(在AWS上,usign EC2 + EBS)?

    我在设计这个工作流程时遇到了什么问题?

好的,现在进入细节:

数据集由拥有最喜欢的项目并跟随其他用户的用户组成.目的是能够更新每个用户的队列 - 用户在加载页面时将看到的项目列表,基于她所关注的用户的最喜欢的项目.但是,在我可以处理数据并更新用户队列之前,我需要确保拥有最新的数据,这是API调用的来源.

我可以拨打两个电话:

获取关注用户 - 返回所请求用户所遵循的所有用户,以及

获取收藏的项目 - 返回所请求用户的所有喜爱的项目.

在我打电话给跟随用户更新用户之后,我需要为每个被关注的用户更新喜欢的项目.仅当为所有被跟踪的用户返回所有收藏夹时,才能开始处理该原始用户的队列.此流程如下:

更新UserX的队列

此流程中的工作包括:

开始为用户更新队列 - 通过提取用户,然后更新用户,存储它们,然后为每个用户创建获取收藏夹作业来启动流程.

获取用户的收藏夹 - 来自第三方服务的请求和存储,指定用户的收藏夹列表.

为用户计算新队列 - 现在已经获取了所有数据,处理新队列,然后将结果存储在应用程序层使用的缓存中.

所以,我的问题是:

    这是一个非常适合与MapReduce并行化的流程吗?我不知道它是否会让我启动UserX的进程,获取所有相关数据,并在完成所有操作后返回处理UserX的队列.

    如果是的话,在亚马逊的mapreduce模块上运行是否具有成本效益,该模块按小时计费,并在作业完成时向上计算小时数?如果我使用他们的模块,我有多少"线程"可以等待开放的API请求?

    如果不是,我应该使用另一种系统/模式吗?是否有一个库,这将有助于我在Python做到这一点(在AWS上,usign EC2 + EBS?)?

    我在设计这个工作流程时遇到了什么问题?

感谢阅读,我期待与大家进行一些讨论.

编辑,以回应JimR:

谢谢你的回复.在我写完原始问题后的阅读中,我已经倾向于使用MapReduce了.我还没有确定如何构建它,但我开始觉得MapReduce更适合分发/并行化计算负载,而我真的只是想要并行化HTTP请求.

什么是我的"减少"任务,即获取所有获取数据并将其压缩成结果的部分,并不是计算密集型的.我很确定它会成为一个大的SQL查询,每个用户执行一两秒钟.

所以,我倾向于:

Python编写的非MapReduce Job/Worker模型.我的一个谷歌朋友让我为此学习Python,因为它的开销很低,并且可以很好地扩展.

使用Amazon EC2作为计算层.我想这意味着我还需要一个EBS切片来存储我的数据库.

可能使用亚马逊的简单消息队列.听起来这个第三个亚马逊小部件旨在跟踪作业队列,将结果从一个任务移动到另一个任务的输入,并优雅地处理失败的任务.它很便宜.可能值得实现而不是自定义作业队列系统.

小智.. 5

您描述的工作可能非常适合队列或队列和作业服务器的组合.它当然可以作为一组MapReduce步骤工作.

对于作业服务器,我建议看看Gearman.文档并不是很棒,但是演示文稿很好地记录了它,并且Python模块也是相当不言自明的.

基本上,您在作业服务器中创建函数,客户端通过API调用这些函数.可以同步或异步调用这些函数.在您的示例中,您可能希望异步添加"开始更新"作业.这将执行任何准备任务,然后异步调用"获取跟随用户"作业.该作业将获取用户,然后调用"Update follow users"作业.这将一次性提交所有"获取UserA的收藏夹"和朋友工作,并同步等待所有这些工作的结果.全部返回后,将调用"计算新队列"作业.

这种仅限作业服务器的方法最初将不那么健壮,因为确保您正确处理错误以及任何正常服务器和持久性将会很有趣.

对于队列,SQS是一个明显的选择.它坚如磐石,从EC2进入非常快,价格便宜.当你刚入门时,比其他队列更容易设置和维护.

基本上,您将把消息放入队列,就像您将作业提交到上面的作业服务器一样,除非您可能不会同步执行任何操作.不是同步地为"获取UserA的收藏夹"等进行调用,而是异步进行调用,然后发出一条消息,说明是否所有这些调用都已完成.您需要某种持久性(您熟悉的SQL数据库,或亚马逊的SimpleDB,如果您想完全使用AWS)来跟踪工作是否完成 - 您无法在SQS中检查作业的进度(虽然你可以在其他队列).检查它们是否全部完成的消息将进行检查 - 如果它们未完成,则不执行任何操作,然后将在几分钟内重试该消息(基于visibility_timeout).

这种仅限队列的方法应该是健壮的,假设您没有在不执行工作的情况下错误地使用队列消息.这样的错误很难用SQS做 - 你真的要尝试.不要使用自动消耗队列或协议 - 如果出错,您可能无法确保将替换消息放回队列中.

在这种情况下,队列和作业服务器的组合可能很有用.您可以通过没有持久性存储来检查作业进度 - 作业服务器将允许您跟踪作业进度.您的"获取用户收藏夹"消息可以将所有"获取UserA/B/C收藏夹"作业放入作业服务器.然后,在队列中放入一个"检查所有收藏夹完成"消息,其中包含需要完成的任务列表(以及重新启动任何神秘消失的作业的足够信息).

奖励积分:

将此作为MapReduce应该相当容易.

您的第一份工作输入将是所有用户的列表.该地图将为每个用户及其跟随的用户提供每个用户,获取关注用户和输出行:

"UserX" "UserA"
"UserX" "UserB"
"UserX" "UserC"

身份减少步骤将保持不变.这将形成第二个工作的输入.第二个作业的地图将获得每行的收藏夹(您可能希望使用memcached来防止通过API获取UserX/UserA组合和UserY/UserA的收藏夹),并为每个收藏夹输出一行:

"UserX" "UserA" "Favourite1"
"UserX" "UserA" "Favourite2"
"UserX" "UserA" "Favourite3"
"UserX" "UserB" "Favourite4"

此作业的reduce步骤将转换为:

 "UserX" [("UserA", "Favourite1"), ("UserA", "Favourite2"), ("UserA", "Favourite3"), ("UserB", "Favourite4")]

此时,您可能有另一个MapReduce作业来为具有这些值的每个用户更新数据库,或者您可以使用一些与Hadoop相关的工具(如Pig,Hive和HBase)来为您管理数据库.

I'd recommend using Cloudera's Distribution for Hadoop's ec2 management commands to create and tear down your Hadoop cluster on EC2 (their AMIs have Python set up on them), and use something like Dumbo (on PyPI) to create your MapReduce jobs, since it allows you to test your MapReduce jobs on your local/dev machine without access to Hadoop.

Good luck!



1> 小智..:

您描述的工作可能非常适合队列或队列和作业服务器的组合.它当然可以作为一组MapReduce步骤工作.

对于作业服务器,我建议看看Gearman.文档并不是很棒,但是演示文稿很好地记录了它,并且Python模块也是相当不言自明的.

基本上,您在作业服务器中创建函数,客户端通过API调用这些函数.可以同步或异步调用这些函数.在您的示例中,您可能希望异步添加"开始更新"作业.这将执行任何准备任务,然后异步调用"获取跟随用户"作业.该作业将获取用户,然后调用"Update follow users"作业.这将一次性提交所有"获取UserA的收藏夹"和朋友工作,并同步等待所有这些工作的结果.全部返回后,将调用"计算新队列"作业.

这种仅限作业服务器的方法最初将不那么健壮,因为确保您正确处理错误以及任何正常服务器和持久性将会很有趣.

对于队列,SQS是一个明显的选择.它坚如磐石,从EC2进入非常快,价格便宜.当你刚入门时,比其他队列更容易设置和维护.

基本上,您将把消息放入队列,就像您将作业提交到上面的作业服务器一样,除非您可能不会同步执行任何操作.不是同步地为"获取UserA的收藏夹"等进行调用,而是异步进行调用,然后发出一条消息,说明是否所有这些调用都已完成.您需要某种持久性(您熟悉的SQL数据库,或亚马逊的SimpleDB,如果您想完全使用AWS)来跟踪工作是否完成 - 您无法在SQS中检查作业的进度(虽然你可以在其他队列).检查它们是否全部完成的消息将进行检查 - 如果它们未完成,则不执行任何操作,然后将在几分钟内重试该消息(基于visibility_timeout).

这种仅限队列的方法应该是健壮的,假设您没有在不执行工作的情况下错误地使用队列消息.这样的错误很难用SQS做 - 你真的要尝试.不要使用自动消耗队列或协议 - 如果出错,您可能无法确保将替换消息放回队列中.

在这种情况下,队列和作业服务器的组合可能很有用.您可以通过没有持久性存储来检查作业进度 - 作业服务器将允许您跟踪作业进度.您的"获取用户收藏夹"消息可以将所有"获取UserA/B/C收藏夹"作业放入作业服务器.然后,在队列中放入一个"检查所有收藏夹完成"消息,其中包含需要完成的任务列表(以及重新启动任何神秘消失的作业的足够信息).

奖励积分:

将此作为MapReduce应该相当容易.

您的第一份工作输入将是所有用户的列表.该地图将为每个用户及其跟随的用户提供每个用户,获取关注用户和输出行:

"UserX" "UserA"
"UserX" "UserB"
"UserX" "UserC"

身份减少步骤将保持不变.这将形成第二个工作的输入.第二个作业的地图将获得每行的收藏夹(您可能希望使用memcached来防止通过API获取UserX/UserA组合和UserY/UserA的收藏夹),并为每个收藏夹输出一行:

"UserX" "UserA" "Favourite1"
"UserX" "UserA" "Favourite2"
"UserX" "UserA" "Favourite3"
"UserX" "UserB" "Favourite4"

此作业的reduce步骤将转换为:

 "UserX" [("UserA", "Favourite1"), ("UserA", "Favourite2"), ("UserA", "Favourite3"), ("UserB", "Favourite4")]

此时,您可能有另一个MapReduce作业来为具有这些值的每个用户更新数据库,或者您可以使用一些与Hadoop相关的工具(如Pig,Hive和HBase)来为您管理数据库.

I'd recommend using Cloudera's Distribution for Hadoop's ec2 management commands to create and tear down your Hadoop cluster on EC2 (their AMIs have Python set up on them), and use something like Dumbo (on PyPI) to create your MapReduce jobs, since it allows you to test your MapReduce jobs on your local/dev machine without access to Hadoop.

Good luck!

推荐阅读
谢谢巷议
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有