对mongodb的重要查询会挂起网站

时间:2016-12-28 09:28:19

标签: node.js mongodb performance nosql

我的网站(使用MEAN.JS)有1个登录页面,它还有多个统计页面(报告页面建立在db中的数据上)。

有1份重量级报告会从数据库中抽取~100MB,并需要大约10秒才能完成。问题是在运行此报告时,大多数其他网页都无法在浏览器上加载,因为它们也会向MongoDB发出查询。例如,即使已经显示登录页面的UI,用户也无法登录登录页面。

MongoDB能否并行执行多个查询或仅查询队列?

MongoDB服务器版本是v3.2.3。该报告使用了2个集合:users,trackinglocations。我正在建立一个月的报告:

30 days * 100 users * 10000 gps locations/day/user
= 30 million locations

user: {
    username: (string),
    organization: (objectid)
}

trackinglocation: {
    username: (string),
    date: (date),
    locations: [
        {
            speed: (number),
            long: (number),
            lat: (number)
        }
    ]
}

我首先查询在管理员组织中查找这些用户。然后查询以在该日期范围内报告该组织中用户的旅行距离。

在制作报告时,不仅登录页面,许多其他页面都没有响应浏览器(UI部分仍然由ExpressJS响应,但内部数据表没有机会)。

2 个答案:

答案 0 :(得分:1)

这种情况并不仅限于mongodb。是的,它可以并行运行查询,但即使其他数据库系统具有更好的并行化,如果你发布一个特别大的报告,它也会停止运行。

缓解此问题的常见方法是在辅助/从属服务器上运行繁重的查询(报告等)。这样,主/主不受影响,并继续提供写入和更轻松的读取。

答案 1 :(得分:0)

除了从辅助读取之外的另一个解决方案是多次读取db,每次读取一小段文档,然后在每次读取操作后短暂休息。

//some lines below are pseudocode
function getLocs(callback) {
    var idList  = ...;
    var index   = 0;
    var maxRead = 1000;
    var results = [];

    (function readATrunk(){
        TrackingLocation.find({
            id: {
                $in: idList[index]...idList[min(index+maxRead,idList.length-1)]
            }
        }).
        exec(function(error,trunk){
            results = results.concat(trunk);

            if (index+maxRead<idList.length) {
                index += maxRead;

                //give a spare 1 second for other queries in 
                //other web pages
                setTimeout(readATrunk,1000); 
            }
            else {
                callback(results);
            }
        });
    })();
}