在 MongoDb 中使用 MapReduce 与使用 Celery 和 RabbitMq 的分布式队列进行数据分析
Posted
技术标签:
【中文标题】在 MongoDb 中使用 MapReduce 与使用 Celery 和 RabbitMq 的分布式队列进行数据分析【英文标题】:Data analysis using MapReduce in MongoDb vs a Distributed Queue using Celery & RabbitMq 【发布时间】:2012-08-20 21:13:30 【问题描述】:我目前正在从事一个项目,该项目涉及对许多相对较小的数据集执行大量统计计算。其中一些计算就像计算移动平均线一样简单,而另一些则涉及更多的工作,例如 Spearman 的 Rho 或 Kendell 的 Tau 计算。
数据集本质上是打包到字典中的一系列数组,其键与 MongoDb 中的文档 ID 相关,该文档 ID 提供有关子集的更多信息。字典中的每个数组的值不超过 100 个。然而,字典可能无限大。然而,实际上,每年约有 150 个值被添加到字典中。
我可以使用 mapreduce 来执行所有必要的计算。或者,我可以在分布式系统上使用 Celery 和 RabbitMQ,并在 python 中执行相同的计算。
我的问题是:哪个途径最值得推荐或最佳实践?
以下是一些附加信息:
-
我还没有进行任何基准测试,因为我刚刚开始构建脚本以计算每个数据集的指标。
使用 celery/rabbitmq 分布式队列可能会增加对 Mongo 数据库的查询数量。
我认为这两种方法的内存使用都不是问题,除非同时执行的任务数量非常大。大多数任务本身只是在数据集中获取一个项目,加载它,进行计算,然后释放它。所以即使一个数据集中的数据量非常大,也不会一次全部加载到内存中。因此,在我看来,限制因素归结为 mapreduce 或排队系统执行计算的速度。此外,它还取决于并发任务的数量。
感谢您的帮助!
【问题讨论】:
【参考方案1】:如果不进行基准测试就无法确定,但我的直觉倾向于在 Python 中而不是 mapreduce 中进行更多计算。我主要担心的是 mapreduce 是单线程的:一个 MongoDB 进程一次只能运行一个 javascript 函数。但是,它可以同时处理数千个查询,因此您可以通过从多个 Python 进程查询 MongoDB 来利用这种并发性。
【讨论】:
我决定在应用程序中构建两者的能力,以便以后可以进行基准测试。完成后,我将在这里发布我的发现。您对 MongoDB MapReduce 引擎的单线程性是正确的。但是,如果我错了,请纠正我,但我相信每个 MongoD 实例上也有一个写锁。由于一台服务器通常只有一个mongod实例,那么如果对于每个分布式队列,我至少需要向数据库写入一次(可能是3次),那么瓶颈不是更依赖于此吗? MongoDB 确实每个服务器都有一个写锁(每个数据库从 2.2 开始)。在实践中,写入速度很快,并且锁很少成为瓶颈,只要您更新的数据主要适合内存。这与执行 Javascript 函数相比,后者不一定很快。所以我担心执行JS会成为瓶颈,但高度怀疑MongoDB的写入吞吐量会是。以上是关于在 MongoDb 中使用 MapReduce 与使用 Celery 和 RabbitMq 的分布式队列进行数据分析的主要内容,如果未能解决你的问题,请参考以下文章
如何在 mongoose/mongodb 查询子文档中使用 mapreduce?
使用hadoop mapreduce分析mongodb数据: