求大神指点(有奖):MongoDB表有7000多万条数据,现在更新速度异常的慢!

西安鲲之鹏 发布于 2014/04/22 20:09
阅读 7K+
收藏 3
MongoDB表(items集合)有7000多万条数据,现在更新异常的慢。感觉差不多1秒钟只能更新1-5次,异常的慢! (我的实际需求是每天要更新5000万次左右!)

> db.items.count()
70866908

> db.items.stats()
{
        "ns" : "shops_items.items",
        "count" : 70866908,
        "size" : 23675466304,
        "avgObjSize" : 334.083523215095,
        "storageSize" : 26476834672,
        "numExtents" : 33,
        "nindexes" : 4,
        "lastExtentSize" : 2146426864,
        "paddingFactor" : 1.9960000003695433,
        "systemFlags" : 1,
        "userFlags" : 0,
        "totalIndexSize" : 14688412928,
        "indexSizes" : {
                "_id_" : 2299410064,
                "item_id_1" : 2570787856,
                "shop_id_1" : 3433290448,
                "sales_url_1" : 6384924560
        },
        "ok" : 1
}

每天需要更新数据,插入新增数据。程序执行的操作是update(采用upsert=true模式)。

求助大神,如何破解?

问题解决有报酬!

赛钛客(Saitek)美加狮 Mad Catz R.A.T.3 游戏鼠标一只,市场价350元。(不限于此)


PS:之前测试过如果只Insert不Update速度可以达到1000-2000次/秒。


2014-04-23补充:

下面几行是MongoDB的日志,可以看出更新一条记录差不多就要花0.4秒的时间啊!

Mon Apr 21 05:00:01.526 [conn8] update shops_items.items query: { item_id: 38143873013 } update: { $set: { shop_id: 61043531, update_time: new Date(1398038400000), ... item_id: 38143873013 } } nscanned:1 nupdated:1 keyUpdates:0 locks(micros) w:418 478ms


Mon Apr 21 05:00:01.832 [conn8] update shops_items.items query: { item_id: 26097404556 } update: { $set: { shop_id: 104973686, update_time: new Date(1398038400000), ... item_id: 26097404556 } } nscanned:1 nupdated:1 keyUpdates:1 locks(micros) w:627 214ms

Mon Apr 21 05:00:03.298 [conn8] update shops_items.items query: { item_id: 18141302220 } update: { $set: { shop_id: 67539387, update_time: new Date(1398038400000)... item_id: 18141302220 } } nscanned:1 nupdated:1 keyUpdates:0 locks(micros) w:294 702ms

加载中
1
周明岐
周明岐

首先呢,你的mongo的这个db光索引的大小就是十几个G,再加上热数据,你们跑mongo的机器的内存是多少呢,内存的大小应该是大于索引+热数据的,另外你们跑mongo的机器的磁盘是什么呢?如果只是普通磁盘的话,大量数据要到穿透到磁盘的话,会造成很多的随机寻址,这个性能本身就是很差的,再加上磁盘频繁的随机读写,达到你们现在的情况,一点也不稀罕,给的建议就是加大内存,关闭机器Numa,换成ssd或者是flash卡

周明岐
周明岐
回复 @鲲鹏Web数据采集 : 你们用的是物理机跑的嘛?如果是物理机的话,一定要关闭机器的numa,否则也会影响mongo的性能,虽说是放在内存,但是本身也是有持久化的,这个跟mysql其实很像的,重启不太会影响这个
西安鲲之鹏
西安鲲之鹏
回复 @周明岐 : 我采用的是MongoDB的默认配置。怎么配置才能把索引都放到内存中呢?另外,如果真的都放到内存中,没有持久化的话,机器重启了索引不是没有了?
周明岐
周明岐
回复 @鲲鹏Web数据采集 : 剩余18G绝对的不正常,正常情况下mongo的内存占用应该是索引大小+热数据大小,否则性能肯定会受影响,会频繁的穿透到磁盘随机读写,严重影响性能
西安鲲之鹏
西安鲲之鹏
机器物理内存是24GB,目前看剩余18GB左右。 是普通硬盘,用iostat查看,我的%util才22%。
0
IncRediblE
IncRediblE

没接触过这么多数据啊,mark一下

0
NealFeng
NealFeng

没接触过这么多数据,也没接触过MongoDB。。。

搜到个问题,不知道管用不:http://stackoverflow.com/questions/16103193/mongodb-findandmodify-extremely-slow

上面这个帖子的最后一行回复。

西安鲲之鹏
西安鲲之鹏
多谢,我试试 db.runCommand( {collMod: "items", usePowerOf2Sizes : true })
0
仪山湖
仪山湖

如果没有使用ObjectId作为检索条件,这么多数据的表更新必须使用索引,ps;insert只是追加,不检索数据,大部分情况下不影响性能

西安鲲之鹏
西安鲲之鹏
更新时候用的就是索引item_id(在indexSizes中可看到)。
0
Arrowing
Arrowing

去除不必要的索引,不要采用安全模式更新,不要使用upsert呢?

菜鸟一枚,飘过...

爱暴力
我了个去
0
jQer
jQer

explain()看看

0
penngo
penngo

检查下是不是查询条件慢造成的。

0
oscuser
oscuser

stackoverflow.com/questions/15160392/mongodb-update-causes-extremly-slow-reads http://docs.mongodb.org/manual/reference/command/collMod/#usePowerOf2Sizes

0
西安鲲之鹏
西安鲲之鹏

引用来自“jQer”的评论

explain()看看

> db.items.find({'item_id': 21089495147}).explain()
{
        "cursor" : "BtreeCursor item_id_1",
        "isMultiKey" : false,
        "n" : 1,
        "nscannedObjects" : 1,
        "nscanned" : 1,
        "nscannedObjectsAllPlans" : 1,
        "nscannedAllPlans" : 1,
        "scanAndOrder" : false,
        "indexOnly" : false,
        "nYields" : 0,
        "nChunkSkips" : 0,
        "millis" : 0,
        "indexBounds" : {
                "item_id" : [
                        [
                                21089495147,
                                21089495147
                        ]
                ]
        },
        "server" : "ubuntu:27017"
}
似乎没有什么有用的信息。
0
f
fullpanic

有mongodb的监控么(mms),看看update的时候负载情况

西安鲲之鹏
西安鲲之鹏
回复 @fullpanic : 物理内存24GB,剩余大概18GB
f
fullpanic
回复 @鲲鹏Web数据采集 : 内存富余?机器内存多大啊
西安鲲之鹏
西安鲲之鹏
没有安装这个东西。不过我查看了系统内存和CPU都很富余。
返回顶部
顶部