問題背景:近期在重構(gòu)公司內(nèi)部一個(gè)重要的任務(wù)系統(tǒng),由于原來的任務(wù)系統(tǒng)使用了MongoDB來保存任務(wù),客戶端從MongoDB來取,至于為什么用MongoDB,是一個(gè)歷史問題,也是因?yàn)槿绻褂玫組ongoDB的數(shù)組查詢可以減少任務(wù)數(shù)量很多次,假設(shè)這樣的情況,一個(gè)md5需要針對(duì)N種情況做任務(wù)處理,如果用到MongoDB的數(shù)組,只需要將一個(gè)md5作為一條任務(wù),其中包含一個(gè)長(zhǎng)度為N的待處理任務(wù)列表(只有N個(gè)子任務(wù)都處理完后整個(gè)任務(wù)才算處理完畢),這樣整個(gè)任務(wù)系統(tǒng)的數(shù)量級(jí)就變?yōu)樵瓉淼?/N。細(xì)節(jié)描述:1.當(dāng)MongoDB的任務(wù)數(shù)量增多的時(shí)候,數(shù)組查詢相當(dāng)?shù)穆?,任?wù)數(shù)達(dá)到5K就已經(jīng)不能容忍了。2.任務(wù)處理每個(gè)md5對(duì)應(yīng)的N個(gè)子任務(wù)必須要全部完成才從MongoDB中刪除3.任務(wù)在超時(shí)后可以重置改進(jìn)方案如下:由于原有代碼的耦合,不能完全拋棄MongoDB,所以決定加一個(gè)Redis緩存。一個(gè)md5對(duì)應(yīng)的N個(gè)子任務(wù)分發(fā)到N個(gè)Redis隊(duì)列中(拆分子任務(wù))。一個(gè)單獨(dú)的進(jìn)程從MongoDB中向Redis中將任務(wù)同步,客戶端不再?gòu)腗ongoDB取任務(wù)。這樣做的好處是拋棄了原有的MongoDB的數(shù)組查詢,同步進(jìn)程從MongoDB中取任務(wù)是按照任務(wù)的優(yōu)先級(jí)偏移(已做索引)來取,所以速度比數(shù)組查詢要快。這樣客戶端向Redis的N個(gè)隊(duì)列中取子任務(wù),把任務(wù)結(jié)果返回原來的MongoDB任務(wù)記錄中(根據(jù)md5返回子任務(wù))。改進(jìn)過程遇到的問題:由于客戶端向MongoDB返回時(shí)候會(huì)有一個(gè)update操作,如果N個(gè)子任務(wù)都完成,就將任務(wù)從MongoDB中刪除。這樣的一個(gè)問題就是,經(jīng)過測(cè)試后發(fā)現(xiàn)MongoDB在高并發(fā)寫的情況下性能很低下,整個(gè)任務(wù)系統(tǒng)任務(wù)處理速度最大為200/s(16核,16G,CentOS,內(nèi)核2.6.32-358.6.3.el6.x86_64),原因大致為在頻繁寫情況下,MongoDB的性能會(huì)由于鎖表操作急劇下降。具體問題:(ThinkoutoftheBox)能否提出一個(gè)好的解決方案,能夠保存任務(wù)狀態(tài)(子任務(wù)狀態(tài)),速度至少超過MongoDB的?
MongoDB + Redis 任務(wù)隊(duì)列性能瓶頸
千萬里不及你
2019-04-08 11:16:51