使用MongoDB的MapReduce真的非常慢(对于同等数据库,在MySQL中为30小时vs 20分钟)



我现在正在做一些数据分析测试,在第一个非常简单的测试中,我得到了非常奇怪的结果。

想法如下:来自互联网访问日志(每个访问都有一个文档的集合,用于测试9000万个文档)。我想按域获取访问次数(MySQL中的GROUP by),并获得访问次数最多的10个域

我用JavaScript编写的脚本非常简单:

/* Counts each domain url */
m = function () {
    emit(this.domain, 1 );
}
r = function (key, values)    {
    total = 0;
    for (var i in values)    {
        total += Number(i);
    }
    return total;
}
/* Store of visits per domain statistics on NonFTP_Access_log_domain_visits collection */
res = db.NonFTP_Access_log.mapReduce(m, r, { out: { replace : "NonFTP_Access_log_domain_visits" } } );
db.NonFTP_Access_log_domain_visits.ensureIndex({ "value": 1});
db.NonFTP_Access_log_domain_visits.find({}).sort({ "value":-1 }).limit(10).forEach(printjson);

MySQL中的等价物是:

drop table if exists NonFTP_Access_log_domain_visits;
create table NonFTP_Access_log_domain_visits (
    `domain` varchar(255) NOT NULL,
    `value` int unsigned not null,
    PRIMARY KEY  (`domain`),
    KEY `value_index` (`value`)
    ) ENGINE=MyISAM DEFAULT CHARSET=utf8
    select domain, count(*) as value from NonFTP_Access_log group by domain;
select * from NonFTP_Access_log_domain_visits order by value desc limit 10;

好吧,MongoDB需要30个小时才能得到结果,MySQL需要20分钟读了一点之后,我得出结论,对于数据分析,我们将不得不使用Hadoop,因为MongoDB确实很慢。像这样的问题的答案是:

  • MongoDB只使用线程
  • Javascript太慢了

我做错了什么?这个结果正常吗?我应该使用Hadoop吗

我们正在以下环境中进行此测试:

  • 操作系统:Suse Linux Enterprise Server 10(Xen上的虚拟服务器)
  • RAM:10 Gb
  • 核心:32(AMD Opteron处理器6128)

实际上我以前也回答过这个非常类似的问题。Map Reduce在MongoDB中的局限性之前已经概述过了——正如您所提到的,它是单线程的,必须转换为Java脚本(spidermonkey)和返回等。

这就是为什么还有其他选择:

  1. MongoDB Hadoop连接器(官方支持)
  2. 聚合框架(需要2.1+)

截至本文撰写之时,2.2.0的稳定版本尚未发布,但它已经发布到RC2,因此发布应该迫在眉睫。我建议尝试一下,作为这种类型测试的更有意义的比较。

显然,在聚合框架上使用group函数效果很好!:-)

下面的Javascript代码获取访问量最大的10个域,它们的访问量在17m17s中!

db.NonFTP_Access_log.aggregate(
    { $group: {
        _id: "$domain",
        visits: { $sum: 1 }
        }},
    { $sort: { visits: -1 } },
    { $limit: 10 }
    ).result.forEach(printjson);

无论如何,我仍然不明白为什么MapReduce替代方案如此缓慢。我在MongoDB JIRA中打开了以下问题。

我认为您的结果很正常,并将尝试证明它们的合理性<。br>1.MySQL使用二进制格式,MongoDB使用JSON时对其进行了优化处理。因此,解析时间被添加到处理中。我估计它至少是10倍
2.JS确实比C慢得多。我认为至少可以假设系数为10。我们一起得到了大约x100——类似于你所看到的。20分钟x 1000是2000分钟或大约33小时
3.Hadoop在数据处理方面也不高效,但它能够使用所有的核心,这会有所不同。Java还对JIT进行了10多年的开发和优化
4.我建议不要看MySQL,而是看TPC-H基准Q1——这是纯粹的聚合。我认为像VectorWise这样的系统将显示每个核心的最大可能吞吐量

相关内容

  • 没有找到相关文章

最新更新