8

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

想法如下:来自互联网访问日志(每次访问包含一个文档的集合,用于测试 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 上的虚拟服务器)
  • 内存:10 Gb
  • 核心数:32(AMD Opteron 处理器 6128)
4

3 回答 3

12

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

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

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

在撰写本文时,2.2.0 稳定版还没有发布,但它已经到了 RC2,所以发布应该是迫在眉睫。我建议试一试,作为此类测试的更有意义的比较。

于 2012-08-27T10:04:44.370 回答
5

显然使用聚合框架上的组功能效果很好!:-)

下面的 Javascript 代码在17 分钟 17 秒内获得了访问量最大的 10 个域!

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

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

于 2012-08-28T08:50:34.840 回答
0

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

于 2012-08-27T19:55:08.307 回答