首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MongoDb聚合性能分析

MongoDb聚合性能分析
EN

Stack Overflow用户
提问于 2014-12-02 05:36:35
回答 1查看 1.6K关注 0票数 6

我试图从集合中获得毫秒(<秒)的聚合响应时间。然而,即使对于一个小数据大小(~200 it ),它现在也要花费3-5秒。我预计这个集合的生产数据大约是每片100 in。我已经查过了

  • 当我在每个碎片上单独尝试查询时,响应时间是相同的。-检查了分析输出,我所能看到的只有高timeLockedMicros和numYield。-在MMS图表中也找不到任何不寻常的东西。我觉得我想在这里监视一些愚蠢的东西。任何进一步分析这一点的帮助都是非常感谢的。下面提供了我的集群和集合详细信息

集群-6节点,34 GB,4台核心计算机(AWSm2.2xLarge)数据大小 1,285 MB (每片213 MB )记录编号=550万(每片~1 M)

记录示例

代码语言:javascript
复制
{
    "_id" : {
        "ItemID" : 105182,
        "DeviceType" : 16,
        "ItemVersionID" : 117971,
        "Timestamp" : ISODate("2014-11-14T00:00:00Z"),
        "RecordType" : 1
    },
    "Dim1ID" : 102260,
    "Dim2ID" : 313,
    "Dim3ID" : 1,
    "actionType" : {
        "1" : 66,
        "47" : 66,
        "42" : 72,
        "46" : 130
    }
}

查询

代码语言:javascript
复制
db.AggregateCollection.aggregate({ "$group" : { "_id" : { } , "type1" : { "$sum" : "$actionType.1"} , "type2" : { "$sum" : "$actionType.2"}}})

配置文件统计数据(来自一个碎片)

代码语言:javascript
复制
"keyUpdates" : 0,
    "numYield" : 79,
    "lockStats" : {
        "timeLockedMicros" : {
            "r" : NumberLong(2981456),
            "w" : NumberLong(0)
        },
        "timeAcquiringMicros" : {
            "r" : NumberLong(3756),
            "w" : NumberLong(4)
        }
    },
    "responseLength" : 157,
    "millis" : 3268,
    "execStats" : {

    },

更新感谢您的及时响应。接受它。我喜欢你的新数据模型和索引。但是,恐怕这不适合我当前的数据,因为- 99%的记录对于actionType.1和- 99%的查询将选择actionType.1,因此在actiionType.K上索引不会有多大帮助。

正如您在#2和#3中所建议的那样,我们已经在使用支持MongoDb的星火集群进行预聚合。

关于我的查询,我之前共享的查询只是一个示例,只用于测试性能。我的实际查询将包含时间戳上的$match和一个或多个文件上的$group。一个典型的生产查询是30天的数据。目前我的收集只有15天的数据。我的目标是获得30天数据的亚秒响应时间。

顺便说一句,我今天做了一些更多的分析--我在我的MacBook上安装了一个本地的芒果,然后把碎片堆在垃圾堆里。相同的查询只需2秒( AWS中的4s )就没有意义了,因为AWS实例的功能至少是MacBook ( CPU和内存) MacBook Air - http://www.cpubenchmark.net/cpu.php?cpu=Intel+Core+i5-4250U+%40+1.30GHz m2.2xLargeInstance- http://www.cpubenchmark.net/cpu.php?cpu=Intel+Xeon+E5-2665+%40+2.40GHz的4倍

我怀疑分散是因为AWS mongo实例中的数据是在过去15天中通过应用程序填充的。因此,作为一个单独的集合,我重新导入了AWS mongo上的转储。对这个新集合的查询采用了2s,这与MAcBook的速度相当。因此,分裂无疑是一个原因。我计划以后做更多关于碎裂的研究。虽然碎片整理改进了perfromace,但与我的MacBook时间相同的事实并没有意义,因为AWS是AWS的4倍强。然后,我们查看了cpu利用率,发现mongod实例只使用一个CPU (4个中的一个)来执行查询。我们现在计划在每台机器上安装4个碎片来解决这个问题。如果你看到更好的方法,请告诉我。

还有一件事,我知道我的查询必须扫描整个集合,但是2秒才能扫描200 me的数据对我来说似乎很高。是期待还是我错过了什么?

EN

回答 1

Stack Overflow用户

发布于 2014-12-02 06:55:44

我会尝试的事情:

1)你组织数据的方式使分组变得非常困难。如果像这样组织文档,您可能会得到更好的结果:

代码语言:javascript
复制
{
    ...
    "actionType" : [{k:1, v:66}, {k:47, v:66}, {k:42, v:72}, {k:46, v:130}]
}

这将允许您在'actionType.k‘上创建一个索引。然后,您可以在该索引上进行匹配,以将整个数据集简化为此聚合所需的确切actionTypes,其中查询如下:

代码语言:javascript
复制
db.action.aggregate([{$unwind: '$actionType'}, 
        {$group:{_id:'$actionType.k', t:{$sum:'$actionType.v'} } }]);
//output
{ "_id" : 46, "t" : 130 }
{ "_id" : 42, "t" : 72 }
{ "_id" : 47, "t" : 66 }
{ "_id" : 1, "t" : 66 }

然后在'actionType.k‘上使用ensureIndex。如果您没有计划对所有不同的键值进行筛选,那么根据文档中键的密度,索引将有很大的帮助。如果您计划对每个键进行求和,索引在这里不会有帮助。

2)映射-在cron作业/setTimeout计划中减少和/或添加这些内容。同样,根据您的更新周期和您在任何时候需要数据的精确程度,设置如下内容:

  • 每小时都要处理所有的“肮脏”结果
  • 将当前值添加到正在运行的总数中。
  • 标记为“干净”

如果您只对此数据库执行插入操作,则可以执行此操作。

3)如果键值有规律地变化(更新而不是插入),那么在对主集合进行更新的同时执行变更列表插入可能会更幸运。

代码语言:javascript
复制
db.changes.insert({key:44, change:2});
db.changes.insert({key:34, change:-2});

然后常规地清空“更改”集合,将值加到不同的集合中。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27242566

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档