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