MongoDB提取文档速度慢(使用索引)

Vil*_*tor 5 performance amazon-ec2 mongodb amazon-web-services

FETCH阶段是我的查询中的限制因素.我一直在研究,似乎mongodb读取的内容远远超过它的需要,并且没有充分利用带宽.

我的mongoDB-mongod实例似乎在一个查询上阅读很多.使用1个EBS io 5000Piops附加(100GB)SSD在AWS EC2 m4.xlarge上进行测试.16 GB内存.

  • 该机器仅包含用于测试目的的mongodb实例.
  • 该数据库总共约为60GB(在磁盘上)(多个集合).
  • 主要集合用于以下方案和查询.

db stats

db.stats()
{
    "db" : "database",
    "collections" : 4,
    "objects" : 406496932,
    "avgObjSize" : 326.3196544642064,
    "dataSize" : 132647938391,
    "storageSize" : 55475830784,
    "numExtents" : 0,
    "indexes" : 5,
    "indexSize" : 8940408832,
    "ok" : 1
 }
Run Code Online (Sandbox Code Playgroud)

收集摘要:

db.collection.stats()  ->  
{    "ns" : "database.[collection###]",
    "count" : 367614513,
    "size" : 121155225858,
    "avgObjSize" : 329,
    "storageSize" : 52052197376,
    "capped" : false,
    "wiredTiger" : {"Left empty"},
    "nindexes" : 2,
    "totalIndexSize" : 8131604480,
    "indexSizes" : {
            "_id_" : 4373012480,
            "id_1_ts_-1" : 3758592000
    },
    "ok" : 1
Run Code Online (Sandbox Code Playgroud)

查询:

db.[#######].find({ id : "######", 
   ts : { 
    "$gte" :
       ISODate("2016-10-01T00:00:00.000Z"), 
     $lt :
       ISODate("2016-10-07T02:00:00.000Z")
}}, {_id : 0,"u1"
     :1,"u2":1,"u3":1,"eq1" :1 ,"eq2" : 1,"eq3": 1,"ts" :1});
Run Code Online (Sandbox Code Playgroud)

并解释结果:

{
    "queryPlanner" : {
            "plannerVersion" : 1,
            "namespace" : "database.[collection]",
            "d" : false,
            "parsedQuery" : {
                    "$and" : [
                            {
                                    "id" : {
                                            "$eq" : "#####ID#####"
                                    }
                            },
                            {
                                    "ts" : {
                                            "$lt" : ISODate("2016-09-30T22:00:00Z")
                                    }
                            },
                            {
                                    "ts" : {
                                            "$gte" : ISODate("2016-09-22T22:00:00Z")
                                    }
                            }
                    ]
            },
            "winningPlan" : {
                    "stage" : "PROJECTION",
                    "transformBy" : {
                            "_id" : 0,
                            "u1" : 1,
                            "u2" : 1,
                            "u3" : 1,
                            "eq1" : 1,
                            "eq2" : 1,
                            "eq3" : 1,
                            "ts" : 1
                    },
                    "inputStage" : {
                            "stage" : "FETCH",
                            "inputStage" : {
                                    "stage" : "IXSCAN",
                                    "keyPattern" : {
                                            "id" : 1,
                                            "ts" : -1
                                    },
                                    "indexName" : "id_1_ts_-1",
                                    "isMultiKey" : false,
                                    "isUnique" : false,
                                    "isSparse" : false,
                                    "isPartial" : false,
                                    "indexVersion" : 1,
                                    "direction" : "forward",
                                    "indexBounds" : {
                                            "id" : [
                                                    "[\"#####ID#####\", \"#####ID#####\"]"
                                            ],
                                            "ts" : [
                                                    "(new Date(1475272800000), new Date(1474581600000)]"
                                            ]
                                    }
                            }
                    }
            },
            "rejectedPlans" : [ ]
    },
    "executionStats" : {
            "executionSuccess" : true,
            "nReturned" : 676745,
            "executionTimeMillis" : 170508,
            "totalKeysExamined" : 676745,
            "totalDocsExamined" : 676745,
            "executionStages" : {
                    "stage" : "PROJECTION",
                    "nReturned" : 676745,
                    "executionTimeMillisEstimate" : 167820,
                    "works" : 676746,
                    "advanced" : 676745,
                    "needTime" : 0,
                    "needYield" : 0,
                    "saveState" : 8970,
                    "restoreState" : 8970,
                    "isEOF" : 1,
                    "invalidates" : 0,
                    "transformBy" : {
                            "_id" : 0,
                            "u1" : 1,
                            "u2" : 1,
                            "u3" : 1,
                            "eq1" : 1,
                            "eq2" : 1,
                            "eq3" : 1,
                            "ts" : 1
                    },
                    "inputStage" : {
                            "stage" : "FETCH",
                            "nReturned" : 676745,
                            "executionTimeMillisEstimate" : 166470,
                            "works" : 676746,
                            "advanced" : 676745,
                            "needTime" : 0,
                            "needYield" : 0,
                            "saveState" : 8970,
                            "restoreState" : 8970,
                            "isEOF" : 1,
                            "invalidates" : 0,
                            "docsExamined" : 676745,
                            "alreadyHasObj" : 0,
                            "inputStage" : {
                                    "stage" : "IXSCAN",
                                    "nReturned" : 676745,
                                    "executionTimeMillisEstimate" : 980,
                                    "works" : 676746,
                                    "advanced" : 676745,
                                    "needTime" : 0,
                                    "needYield" : 0,
                                    "saveState" : 8970,
                                    "restoreState" : 8970,
                                    "isEOF" : 1,
                                    "invalidates" : 0,
                                    "keyPattern" : {
                                            "id" : 1,
                                            "ts" : -1
                                    },
                                    "indexName" : "id_1_ts_-                                                                   1",
                                    "isMultiKey" : false,
                                    "isUnique" : false,
                                    "isSparse" : false,
                                    "isPartial" : false,
                                    "indexVersion" : 1,
                                    "direction" : "forward",
                                    "indexBounds" : {
                                            "id" : [
                                                    "[\"#####ID#####\", \"#####ID#####\"]"
                                            ],
                                            "ts" : [
                                                    "(new Date(1475272800000), new Date(1474581600000)]"
                                            ]
                                    },
                                    "keysExamined" : 676745,
                                    "dupsTested" : 0,
                                    "dupsDropped" : 0,
                                    "seenInvalidated" : 0
                            }
                    }
            },
            "allPlansExecution" : [ ]
    },
    "serverInfo" : {
            "host" : "ip #########",
            "port" : 27017,
            "version" : "3.2.10",
            "gitVersion" : "79d9b3ab5ce20f51c272b4411202710a082d0317"
    },
    "ok" : 1
Run Code Online (Sandbox Code Playgroud)

}

正如我们在上面看到的,mongoDb使用索引.IXSCAN需要980ms,FETCH 需要16,000ms.

如果我不误认为整个读取应该是676746(nReturned)*329(avgObjSize)Bytes = ~212 MB的数据.

我注意到在iostats(http://linuxcommand.org/man_pages/iostat1.html)中有以下内容(/ data/db在xvdf上):

  vg-cpu:  %user   %nice %system %iowait  %steal   %idle
           0.27    0.00    0.00   21.35    0.13   78.25
Device:         rrqm/s   wrqm/s     r/s     w/s    rMB/s    wMB/s avgrq-sz avgqu-sz   await r_await w_await  svctm  %util
xvda              0.00     0.00    0.00    0.00     0.00     0.00     0.00     0.00    0.00    0.00    0.00   0.00   0.00
xvdf              0.00     0.00 1691.00    0.00    19.83     0.00    24.02     0.95    0.56    0.56    0.00   0.56  94.40
Run Code Online (Sandbox Code Playgroud)

在整个操作(获取阶段)期间,rMB/s表示~20MB/s并且这是连续的.这意味着mongodb正在读取160 s*20MB/s = 3 200 MB,这超过了200 MB以上.

记忆:

    free -m
             total       used       free     shared    buffers     cached
   Mem:         16048      12629       3418          0         32       4071
   -/+ buffers/cache:       8525       7522
  Swap:            0          0        
Run Code Online (Sandbox Code Playgroud)

mongodb还没有使用配置的5000 iops EBS,也没有承诺带宽?仅使用~1700读/秒导致~20MB/s.

我已将预读更改为16KB.我曾尝试将日志和日志放在另一个硬盘上.

我想不出来了!帮我.请!

小智 6

我在获取大约 35000 个文档时遇到了同样的问题。为了解决这个问题,我使用了聚合函数 ( sakulstra:aggregate),在我的例子中,它极大地提高了请求。结果格式显然不一样,但它仍然很容易用来计算我需要的所有东西。

之前(7000 毫秒):

const historicalAssetAttributes = HistoricalAssetAttributes.find({
        date:{'$gte':startDate,'$lte':endDate},
        assetId: {$in: assetIds}
    }, {
        fields:{
            "date":1,
            "assetId":1,
            "close":1
        }
    }).fetch();
Run Code Online (Sandbox Code Playgroud)

之后(300 毫秒):

const historicalAssetAttributes = HistoricalAssetAttributes.aggregate([
        {
            '$match': {
                date: {'$gte': startDate, '$lte': endDate},
                assetId: {$in: assetIds}
            }
        }, {
            '$group':{
                _id: {assetId: "$assetId"},
                close: {
                    '$push': {
                        date: "$date",
                        value: "$close"
                    }
                }
            }
        }
    ]);
Run Code Online (Sandbox Code Playgroud)


kev*_*adi 5

主要事实是:

  • 该机器有 16 GB 的 RAM
  • 有问题的集合是 112 GB 未压缩(约 51 GB 压缩)
  • 集合的索引总大小约为 7 GB
  • 该集合包含 367,614,513 个文档
  • 大部分时间都花在获取用于投影的文档上。这需要 166470 毫秒(约 166 秒)。查询的索引扫描仅需要 980 毫秒(<1 秒)。

假设 WiredTiger 缓存设置为默认值,为 WiredTiger 缓存保留的 RAM 量应约为 8.6 GB。在https://docs.mongodb.com/v3.2/faq/storage/#to-what-size-should-i-set-the-wiredtiger-internal-cache 中

从 MongoDB 3.2 开始,默认情况下 WiredTiger 内部缓存将使用较大者:

  • 60% 的 RAM 减去 1 GB,或
  • 1 GB。

从上面的信息来看,你的机器似乎存在内存压力。MongoDB 尝试将索引保留在内存中以便快速访问,整个索引约为 7 GB。这将仅用索引有效地填充大约 80% 的 WiredTiger 缓存,为其他任何东西留下很少的空间。结果,MongoDB 被迫从磁盘中提取结果集中的文档。在这一点上,性能受到影响。

您可以从iostat输出中看到此效果,其中设备xvdf(数据所在的位置)的利用率超过 94%(显示在%util列中),这意味着您的操作受 I/O 限制,因为您没有足够的资源RAM 来满足您理想的工作集。

为了缓解这个问题,您可以尝试:

  • 为您的部署提供更大的 RAM
  • 如果适用,请使用游标返回文档,而不是尝试一次访问整个结果集

您还可以查看生产说明操作清单以了解推荐的设置。