Mongo大型集合中的map/reduce速度变慢

3
我们有一个看似简单的Map/Reduce任务,每天要处理日志数据。在开发服务器上,我们可以运行这个任务处理大量文档,约1M个文档,一分钟内轻松完成。但是在Amazon EC2生产服务器上,任务将会快速处理约50%的行,然后在其余的数据中爬行。处理几十万个文档可能需要数小时,而不是预期的一两分钟。因此,我希望我们在Map/Reduce任务中没有犯明显的错误。
下面是样本输入文档:
{
    "_id" : ObjectId("4f147a92d72b292c02000057"),
    "cid" : 25,
    "ip" : "123.45.67.89",
    "b" : "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_6_8) AppleWebKit/535.7 (KHTML, like Gecko) Chrome/16.0.912.63 Safari/535.7",
    "r" : "",
    "l" : "en-US,en;q=0.8",
    "ts" : ISODate("2012-01-16T19:29:22Z"),
    "s" : 0,
    "cv" : "4f143a5fd72b292d7f000007",
    "c" : ""
}
我们仅查询一系列_id范围。
以下是map代码:
function() { 
    var browser = {}
    ,referrer = {};
    browser[this.b] = {
        'count': 1
    };
    referrer[this.r] = {
        'count': 1
    };
    var objEmit =  {
        'count': 1
        ,'browsers' : browser
        ,'referrers' : referrer
    };
    var date = this._id.getTimestamp();
    date.setHours(0);
    date.setMinutes(0);
    date.setSeconds(0);
    emit({'cv' : this.cv, 'date' : date, 'cid' : this.cid }, objEmit);
};
以下是reduce代码:
function (key, emits) {
    var total = 0
    ,browsers = {}
    ,referrers = {};
    for (var i in emits) {
        total += emits[i].count;
        for (var key in emits[i].browsers) {
            if (emits[i].browsers.hasOwnProperty(key)) {
                !(browsers[key]) && (browsers[key] = { count : 0 });
                browsers[key].count +=  emits[i].browsers[key].count;
            }
        }
        for (var key in emits[i].referrers) {
            if (emits[i].referrers.hasOwnProperty(key)) {
                !(referrers[key]) && (referrers[key] = { count : 0 });
                referrers[key].count += emits[i].referrers[key].count;
            }
        }
    }
    return {'count' : total, 'browsers' : browsers, 'referrers' : referrers}
};

这段代码是一个处理emit数据的函数,主要是计算总数以及浏览器和来源(referrer)的数量。其中,“!”表示not运算符,“&&”表示逻辑与运算符。

在输出map/reduce任务到现有集合时,不需要使用finalize函数,可以将“merge”选项设置为true。希望以上内容对您有所帮助。

1个回答

0

既然在开发和生产环境中运行的是相同的代码,并且您已经在大型数据集上运行了开发环境,而且返回速度非常快,那么您怀疑代码有问题的特别原因是什么呢?

您是否在微型实例上运行?如果您不知道,微型实例限制平均 CPU 使用率,这可能会通过导致大量数据排队而无法处理它(I/O 没有以同样的方式被限制,因此它继续进入,Linux 内核随后花费大部分时间来管理它并使情况变得更糟)来损害您的 Map-Reduce 活动。

即使 CPU 速度较低,从微型实例切换到小型实例也可能会帮助您,因为您有一个恒定的 CPU 周期“流”可供使用(与正常机器一样),MongoDB 的内部调度可能会更好地适应。

这可能之前不是问题,因为正常查询的“峰值”持续时间不足以导致 CPU 限制启动。


谢谢。CPU使用似乎会在生产环境中被固定,所以这可能是正确的方向。我们据说没有使用微型实例,而是使用了“高内存双倍超大”实例。 - Spencer
你的开发机器有什么样的规格?这种情况不应该出现这些问题。我还会研究一下在开发和生产环境中MongoDB的设置。它们是相同版本、相同设置、相同架构(开发和生产都是64位)吗? - user1207456

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接