Mongo map /减少大型集合的减速

时间:2012-05-23 19:24:57

标签: mongodb mapreduce

我们有一个看似简单的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。

这是地图代码:

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);
};

这是减少代码:

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}
};

没有完成,我们将map / reduce作业输出到现有集合,并将“merge”选项设置为true。

非常感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

因为它是在开发和生产中运行的相同代码,并且你已经在非常大的集合中运行它并且它很快就会返回,你怀疑你的代码可能出错的任何特殊原因?

您是否有可能在Micro实例上运行?如果你不知道,Micro instances cap average CPU usage这可能会破坏你的Map-Reduce活动,因为它会构建一个巨大的数据队列,而不会被允许处理它(I / O没有被限制在同样的方式,所以它继续进入,然后Linux内核花费大部分时间来管理它并使事情变得更糟。)

即使CPU速度较低,从Micro切换到Small也可以帮助您,因为您可以使用CPU循环的恒定“流量”(正常机器一直有),MongoDB的内部调度可能会更好地适应。

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