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

Cig*_*ges 8 hadoop mapreduce mongodb

我现在正在做一些数据分析测试,在第一个,非常简单,我有非常奇怪的结果.

这个想法如下:从互联网访问日志(每个访问的文档集合,测试90万个文档).我希望获得域的访问次数(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);
Run Code Online (Sandbox Code Playgroud)

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;
Run Code Online (Sandbox Code Playgroud)

好吧,MongoDB需要30个小时才能获得结果,MySQL需要20分钟!在阅读了一点之后,我得出的结论是,对于数据分析,我们将不得不使用Hadoop,因为MongoDB非常慢.这样的问题的答案说:

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

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

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

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

Ada*_*ord 12

我之前已经回答了这个非常相似的问题.之前已经概述了MongoDB中Map Reduce的局限性 - 正如您所提到的,它是单线程的,必须转换为Java Script(spidermonkey)和返回等.

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

  1. MongoDB中的Hadoop连接器(官方支持)
  2. 聚合框架(需要2.1以上版本)

在撰写本文时,2.2.0稳定版本还没有发布,但它取决于RC2,所以发布应该是即将发布的.我建议给它一个镜头作为这种类型测试的更有意义的比较.

  • 不在分片环境中工作的聚合框架对我来说听起来很奇怪,然后我意识到你提供的引用不是关于聚合框架,而是关于旧的组函数,它与聚合框架不同,请参阅:http: //docs.mongodb.org/manual/applications/aggregation/#sharded-operation (3认同)

Cig*_*ges 5

显然在Aggregation Framework上使用组函数效果很好!:-)

以下Javascript代码在17分17秒内访问了10个访问量最大的域名!

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

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