最近的副本集读取首选项仍然很慢

时间:2015-09-16 13:08:19

标签: mongodb mongoose replicaset

通知:我还posted this to dba.stackexchange.com。我不确定这个问题属于哪里。如果它不在这里,请告诉我,我将删除它。

我正在测试我的副本集,特别是读取首选项,即使使用最近的读取偏好设置,我仍然会慢速读取。

出于这个问题的目的,我们可以假设有2个mongodb实例(实际上有3个)。主要在阿姆斯特丹(AMS)。 SECONDARY在新加坡(SG)。

我在运行测试脚本(node + mongoose)的2个位置也有2个应用服务器。

  1. 来自AMS应用服务器(使用PRIMARY的低延迟),如果我运行 简单查找查询,我在一秒钟内收到回复。
  2. 但是,如果我从SG的app服务器运行相同的查询,我的响应时间约为4-7秒。
  3. 如果我只是从SG应用服务器连接到SG SECONDARY,我的查询时间将降至< 1s,类似于(1)。
  4. 回到标准的代表设置(最近的),如果我查看日志,我发现如果我使用'最近的'向SG发送查询,我可以在那里查看查询,但我也在PRIMARY日志中看到相同查询的条目(但行数较少)。但有趣的是,即使在查询SECONDARY时,PRIMARY日志中也总是有一个条目。我不确定这是否与某种程度有关。

    因此,如果我直接连接到最近的机器,我会得到一个响应< 1s,但是当使用副本集时,除非我在PRIMARY旁边,否则响应时间大于4秒。

    我的问题是,为什么?我是否错误地设置了副本服务器。这是客户端的一个问题(mongoose / mongodb),还是实际上它的意思是工作,而且我误解了它是如何工作的?

    以下是我的文件(对文字墙道歉):

    test.js

    mongoose.connect(configDB.url); 
    var start = new Date().getTime();
    Model.find({})
    .exec(function(err, betas){
        var end = new Date().getTime();
        var time = end - start;
        console.log(time/1000);
        console.log('finished');
        console.log(betas.length);
    });
    

    config,也尝试使用server和replSet选项

    module.exports = {
         'url' : 'user:pwd@ip-primary/db,user:pwd@ip-secondary/db,user:pwd@ip-secondary/db'
    }
    

    Betas模特

    var betaSchema = mongoose.Schema({
        .. some fields
    }, { read: 'n' });
    

    从SG app服务器执行上述读取查询的日志输出:

    主要记录:

    2015-09-16T07:49:23.120-0400 D COMMAND  [conn12520] run command db.$cmd { listIndexes: "betas", cursor: {} }
    2015-09-16T07:49:23.120-0400 I COMMAND  [conn12520] command db.$cmd command: listIndexes { listIndexes: "betas", cursor: {} } keyUpdates:0 writeConflicts:0 numYields:0 reslen:296 locks:{ Global: { acquireC
    ount: { r: 2 } }, MMAPV1Journal: { acquireCount: { r: 1 } }, Database: { acquireCount: { r: 1 } }, Collection: { acquireCount: { R: 1 } } } 0ms
    

    第二次登录

        2015-09-16T07:49:19.368-0400 D QUERY    [conn11831] [QLOG] Running query:
    ns=db.betas limit=1000 skip=0
    Tree: $and
    Sort: {}
    Proj: {}
    2015-09-16T07:49:19.368-0400 D QUERY    [conn11831] Running query: query: {} sort: {} projection: {} skip: 0 limit: 1000
    2015-09-16T07:49:19.368-0400 D QUERY    [conn11831] [QLOG] Beginning planning...
    =============================
    Options = INDEX_INTERSECTION KEEP_MUTATIONS
    Canonical query:
    ns=db.betas limit=1000 skip=0
    Tree: $and
    Sort: {}
    Proj: {}
    =============================
    2015-09-16T07:49:19.368-0400 D QUERY    [conn11831] [QLOG] Index 0 is kp: { _id: 1 } io: { v: 1, key: { _id: 1 }, name: "_id_", ns: "db.betas" }
    2015-09-16T07:49:19.368-0400 D QUERY    [conn11831] [QLOG] Index 1 is kp: { email: 1 } io: { v: 1, unique: true, key: { email: 1 }, name: "email_1", ns: "db.betas", background: true, safe: null }
    2015-09-16T07:49:19.368-0400 D QUERY    [conn11831] [QLOG] Rated tree:
    $and
    2015-09-16T07:49:19.368-0400 D QUERY    [conn11831] [QLOG] Planner: outputted 0 indexed solutions.
    2015-09-16T07:49:19.368-0400 D QUERY    [conn11831] [QLOG] Planner: outputting a collscan:
    COLLSCAN
    ---ns = db.betas
    ---filter = $and
    ---fetched = 1
    ---sortedByDiskLoc = 0
    ---getSort = []
    2015-09-16T07:49:19.368-0400 D QUERY    [conn11831] Only one plan is available; it will be run but will not be cached. query: {} sort: {} projection: {} skip: 0 limit: 1000, planSummary: COLLSCAN
    2015-09-16T07:49:19.368-0400 D QUERY    [conn11831] [QLOG] Not caching executor but returning 109 results.
    2015-09-16T07:49:19.368-0400 I QUERY    [conn11831] query db.betas planSummary: COLLSCAN ntoreturn:1000 ntoskip:0 nscanned:0 nscannedObjects:109 keyUpdates:0 writeConflicts:0 numYields:0 nreturned:109 resl
    en:17481 locks:{ Global: { acquireCount: { r: 2 } }, MMAPV1Journal: { acquireCount: { r: 1 } }, Database: { acquireCount: { r: 1 } }, Collection: { acquireCount: { R: 1 } } } 0ms
    

1 个答案:

答案 0 :(得分:1)

输出中的信息表明数据库服务器正在快速处理查询。所以这个问题很可能在数据库本身之外,可能在客户端。

您是否多次运行相同的查询并为每次执行计时?

我怀疑这可能是由于您的MongoDB客户端部分的一些初步发现 - 如果它最初没有点击每个节点并且响应时间,那么如何知道在响应之前最接近的是什么?

相关问题