您好,登錄后才能下訂單哦!
今天小編給大家分享的是關(guān)于MongoDB aggregate的性能優(yōu)化經(jīng)歷,一起來(lái)看看吧。
在一臺(tái)配置為2核4G的阿里云服務(wù)器上,硬盤(pán)是普通的云盤(pán)(即SATA盤(pán)),除mongoDB外,運(yùn)行了若干個(gè)java應(yīng)用,單節(jié)點(diǎn)mysql和redis,mongo的實(shí)際可用內(nèi)存在1.5G左右。單表數(shù)據(jù)200萬(wàn)條的時(shí)候,一個(gè)聚合函數(shù)響應(yīng)時(shí)間約為6秒,頁(yè)面端每秒請(qǐng)求一次,由于響應(yīng)不夠及時(shí),頁(yè)面刷新不及時(shí),服務(wù)端堆積了大量的mongo aggregate請(qǐng)求,系統(tǒng)可用內(nèi)存不足,直接導(dǎo)致了溢出,mongo服務(wù)被動(dòng)shutdown。
mongod(ZN5mongo15printStackTraceERSo+0x41) [0x55bd3a2dd321]
mongod(ZN5mongo29reportOutOfMemoryErrorAndExitEv+0x84) [0x55bd3a2dc954]
mongod(ZN5mongo12mongoReallocEPvm+0x21) [0x55bd3a2d22b1]
mongod(ZN5mongo11BufBuilderINS21SharedBufferAllocatorEE15growreallocateEi+0x83) [0x55bd38981833]
mongod(ZN5mongo3rpc17OpMsgReplyBuilder22getInPlaceReplyBuilderEm+0x80) [0x55bd39d4b740]
mongod(+0xAB9609) [0x55bd389be609]
mongod(+0xABBA59) [0x55bd389c0a59]
下面是聚合的腳本,很簡(jiǎn)單,就是統(tǒng)計(jì)某輛車(chē)多個(gè)狀態(tài)碼的最新值(通過(guò)$first實(shí)現(xiàn))。
db.getCollection("vinMsgOut").aggregate([
{"$match": {"vinCode": "LSGKR53L3HA149563"}},
{"$sort": {"postTime" : -1}},
{"$group": {
"_id": "$messageType",
"resultValue": {"$first": "$resultValue"}
}
}
],{ allowDiskUse: true })
第一反應(yīng)是增加過(guò)濾條件及增加索引。
結(jié)合業(yè)務(wù),增加時(shí)間條件過(guò)濾,將$match改為:
{"$match": {"vinCode": "LSGKR53L3HA149563", "createTime": {$gt: ISODate("2020-03-01T06:30:12.038Z")}}}
再分別為vinCode和createTime創(chuàng)建索引,執(zhí)行,依舊是6秒多。。。
將$sort的字段改成索引字段createTime,{"$sort": {"createTime" : -1}}
再次執(zhí)行,時(shí)間依舊是6秒多。。。
由于系統(tǒng)可分配內(nèi)存有限,存儲(chǔ)引擎已經(jīng)默認(rèn)是最快的wiredTiger,磁盤(pán)也沒(méi)法更給力,只能從業(yè)務(wù)上再著手。考慮到這些最新?tīng)顟B(tài)的出現(xiàn),一般都是同一個(gè)時(shí)間段,狀態(tài)碼只有幾百個(gè),如果sort之后,只從pipe取其中一部分進(jìn)行g(shù)roup,會(huì)不會(huì)更快些?帶著這個(gè)疑問(wèn),我加了一條limit。
db.getCollection("vinMsgOut").aggregate([
{"$match": {"vinCode": "LSGKR53L3HA149563", "createTime": {$gt: ISODate("2020-03-01T06:30:12.038Z")}}},
{"$sort": {"createTime" : -1}},
{"$limit": 1000},
{"$group": {
"_id": "$messageType",
"resultValue": {"$first": "$resultValue"}
}
}
],{ allowDiskUse: true })
結(jié)果是秒回!
去掉$match中的createTime條件,依舊秒回!這是否意味著createTime索引并沒(méi)有起作用?帶著疑問(wèn),將createTime索引刪掉,返現(xiàn)時(shí)間變成5秒,所以createTime的索引是有用的,用在$sort而已。綜上,完成了整個(gè)查詢(xún)的優(yōu)化,總結(jié)下來(lái)就是:
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。