真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程-創(chuàng)新互聯(lián)

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程,很多新手對此不是很清楚,為了幫助大家解決這個難題,下面小編將為大家詳細(xì)講解,有這方面需求的人可以來學(xué)習(xí)下,希望你能有所收獲。

目前創(chuàng)新互聯(lián)建站已為近千家的企業(yè)提供了網(wǎng)站建設(shè)、域名、虛擬空間、網(wǎng)站托管、服務(wù)器托管、企業(yè)網(wǎng)站設(shè)計、龍巖網(wǎng)站維護(hù)等服務(wù),公司將堅持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。


背景

線上某集群峰值TPS超過100萬/秒左右(主要為寫流量,讀流量很低),峰值tps幾乎已經(jīng)到達(dá)集群上限,同時平均時延也超過100ms,隨著讀寫流量的進(jìn)一步增加,時延抖動嚴(yán)重影響業(yè)務(wù)可用性。該集群采用mongodb天然的分片模式架構(gòu),數(shù)據(jù)均衡的分布于各個分片中,添加片鍵啟用分片功能后實現(xiàn)完美的負(fù)載均衡。集群每個節(jié)點流量監(jiān)控如下圖所示:

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

從上圖可以看出集群流量比較大,峰值已經(jīng)突破120萬/秒,其中delete過期刪除的流量不算在總流量里面(delete由主觸發(fā)刪除,但是主上面不會顯示,只會在從節(jié)點拉取oplog的時候顯示)。如果算上主節(jié)點的delete流量,總tps超過150萬/秒。

軟件優(yōu)化

在不增加服務(wù)器資源的情況下,首先做了如下軟件層面的優(yōu)化,并取得了理想的數(shù)倍性能提升:

業(yè)務(wù)層面優(yōu)化

Mongodb配置優(yōu)化

存儲引擎優(yōu)化

業(yè)務(wù)層面優(yōu)化

該集群總文檔近百億條,每條文檔記錄默認(rèn)保存三天,業(yè)務(wù)隨機(jī)散列數(shù)據(jù)到三天后任意時間點隨機(jī)過期淘汰。由于文檔數(shù)目很多,白天平峰監(jiān)控可以發(fā)現(xiàn)從節(jié)點經(jīng)常有大量delete操作,甚至部分時間點delete刪除操作數(shù)已經(jīng)超過了業(yè)務(wù)方讀寫流量,因此考慮把delete過期操作放入夜間進(jìn)行,過期索引添加方法如下:

Db.collection.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )

上面的過期索引中expireAfterSeconds=0,代表collection集合中的文檔的過期時間點在expireAt時間點過期,例如:

    db.collection.insert( {  //表示該文檔在夜間凌晨1點這個時間點將會被過期刪除  "expireAt": new Date('July 22, 2019 01:00:00'),      "logEvent": 2,  "logMessage": "Success!" } )

通過隨機(jī)散列expireAt在三天后的凌晨任意時間點,即可規(guī)避白天高峰期觸發(fā)過期索引引入的集群大量delete,從而降低了高峰期集群負(fù)載,最終減少業(yè)務(wù)平均時延及抖動。

Delete過期Tips1: expireAfterSeconds含義

在expireAt指定的絕對時間點過期,也就是12.22日凌晨2:01過期

Db.collection.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 0 } )db.log_events.insert( { "expireAt": new Date(Dec 22, 2019 02:01:00'),"logEvent": 2,"logMessage": "Success!"})

在expireAt指定的時間往后推遲expireAfterSeconds秒過期,也就是當(dāng)前時間往后推遲60秒過期

    db.log_events.insert( {"createdAt": new Date(),"logEvent": 2,"logMessage": "Success!"} )Db.collection.createIndex( { "expireAt": 1 }, { expireAfterSeconds: 60 } )

Delete過期Tips2: 為何mongostat只能監(jiān)控到從節(jié)點有delete操作,主節(jié)點沒有?

原因是過期索引只在master主節(jié)點觸發(fā),觸發(fā)后主節(jié)點會直接刪除調(diào)用對應(yīng)wiredtiger存儲引擎接口做刪除操作,不會走正常的客戶端鏈接處理流程,因此主節(jié)點上看不到delete統(tǒng)計。

主節(jié)點過期delete后會生存對于的delete oplog信息,從節(jié)點通過拉取主節(jié)點oplog然后模擬對于client回放,這樣就保證了主數(shù)據(jù)刪除的同時從數(shù)據(jù)也得以刪除,保證數(shù)據(jù)最終一致性。從節(jié)點模擬client回放過程將會走正常的client鏈接過程,因此會記錄delete count統(tǒng)計,詳見如下代碼:

官方參考如下:https://docs.mongodb.com/manual/tutorial/expire-data/

Mongodb配置優(yōu)化(網(wǎng)絡(luò)IO復(fù)用,網(wǎng)絡(luò)IO和磁盤IO做分離)

由于集群tps高,同時整點有大量推送,因此整點并發(fā)會更高,mongodb默認(rèn)的一個請求一個線程這種模式將會嚴(yán)重影響系統(tǒng)負(fù)載,該默認(rèn)配置不適合高并發(fā)的讀寫應(yīng)用場景。官方介紹如下:

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

Mongodb內(nèi)部網(wǎng)絡(luò)線程模型實現(xiàn)原理

mongodb默認(rèn)網(wǎng)絡(luò)模型架構(gòu)是一個客戶端鏈接,mongodb會創(chuàng)建一個線程處理該鏈接fd的所有讀寫請求及磁盤IO操作。

Mongodb默認(rèn)網(wǎng)絡(luò)線程模型不適合高并發(fā)讀寫原因如下:

在高并發(fā)的情況下,瞬間就會創(chuàng)建大量的線程,例如線上的這個集群,連接數(shù)會瞬間增加到1萬左右,也就是操作系統(tǒng)需要瞬間創(chuàng)建1萬個線程,這樣系統(tǒng)load負(fù)載就會很高。

此外,當(dāng)鏈接請求處理完,進(jìn)入流量低峰期的時候,客戶端連接池回收鏈接,這時候mongodb服務(wù)端就需要銷毀線程,這樣進(jìn)一步加劇了系統(tǒng)負(fù)載,同時進(jìn)一步增加了數(shù)據(jù)庫的抖動,特別是在PHP這種短鏈接業(yè)務(wù)中更加明顯,頻繁的創(chuàng)建線程銷毀線程造成系統(tǒng)高負(fù)債。 一個鏈接一個線程,該線程除了負(fù)責(zé)網(wǎng)絡(luò)收發(fā)外,還負(fù)責(zé)寫數(shù)據(jù)到存儲引擎,整個網(wǎng)絡(luò)I/O處理和磁盤I/O處理都由同一個線程負(fù)責(zé),本身架構(gòu)設(shè)計就是一個缺陷。

網(wǎng)絡(luò)線程模型優(yōu)化方法

為了適應(yīng)高并發(fā)的讀寫場景,mongodb-3.6開始引入serviceExecutor: adaptive配置,該配置根據(jù)請求數(shù)動態(tài)調(diào)整網(wǎng)絡(luò)線程數(shù),并盡量做到網(wǎng)絡(luò)IO復(fù)用來降低線程創(chuàng)建消耗引起的系統(tǒng)高負(fù)載問題。此外,加上serviceExecutor: adaptive配置后,借助boost:asio網(wǎng)絡(luò)模塊實現(xiàn)網(wǎng)絡(luò)IO復(fù)用,同時實現(xiàn)網(wǎng)絡(luò)IO和磁盤IO分離。這樣高并發(fā)情況下,通過網(wǎng)絡(luò)鏈接IO復(fù)用和mongodb的鎖操作來控制磁盤IO訪問線程數(shù),最終降低了大量線程創(chuàng)建和消耗帶來的高系統(tǒng)負(fù)載,最終通過該方式提升高并發(fā)讀寫性能。

網(wǎng)絡(luò)線程模型優(yōu)化前后性能對比

在該大流量集群中增加serviceExecutor: adaptive配置實現(xiàn)網(wǎng)絡(luò)IO復(fù)用及網(wǎng)絡(luò)IO與磁盤IO做分離后,該大流量集群時延大幅度降低,同時系統(tǒng)負(fù)載和慢日志也減少很多,具體如下:

優(yōu)化前后系統(tǒng)負(fù)載對比

驗證方式:

該集群有多個分片,其中一個分片配置優(yōu)化后的主節(jié)點和同一時刻未優(yōu)化配置的主節(jié)點load負(fù)載比較:

未優(yōu)化配置的load

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

優(yōu)化配置的load

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

優(yōu)化前后慢日志對比

驗證方式:

該集群有多個分片,其中一個分片配置優(yōu)化后的主節(jié)點和同一時刻未優(yōu)化配置的主節(jié)點慢日志數(shù)比較:

同一時間的慢日志數(shù)統(tǒng)計:

未優(yōu)化配置的慢日志數(shù)(19621):

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

優(yōu)化配置后的慢日志數(shù)(5222):

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

優(yōu)化前后平均時延對比

驗證方式:

該集群所有節(jié)點加上網(wǎng)絡(luò)IO復(fù)用配置后與默認(rèn)配置的平均時延對比如下:

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

從上圖可以看出,網(wǎng)絡(luò)IO復(fù)用后時延降低了1-2倍。

wiredtiger存儲引擎優(yōu)化

從上一節(jié)可以看出平均時延從200ms降低到了平均80ms左右,很顯然平均時延還是很高,如何進(jìn)一步提升性能降低時延?繼續(xù)分析集群,我們發(fā)現(xiàn)磁盤IO一會兒為0,一會兒持續(xù)性100%,并且有跌0現(xiàn)象,現(xiàn)象如下:

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

從圖中可以看出,I/O寫入一次性到2G,后面幾秒鐘內(nèi)I/O會持續(xù)性阻塞,讀寫I/O完全跌0,avgqu-sz、awit巨大,util次序性100%,在這個I/O跌0的過程中,業(yè)務(wù)方反應(yīng)的TPS同時跌0。

此外,在大量寫入IO后很長一段時間util又持續(xù)為0%,現(xiàn)象如下:

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

總體IO負(fù)載曲線如下:

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

從圖中可以看出IO很長一段時間持續(xù)為0%,然后又飆漲到100%持續(xù)很長時間,當(dāng)IO util達(dá)到100%后,分析日志發(fā)現(xiàn)又大量滿日志,同時mongostat監(jiān)控流量發(fā)現(xiàn)如下現(xiàn)象:

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

從上可以看出我們定時通過mongostat獲取某個節(jié)點的狀態(tài)的時候,經(jīng)常超時,超時的時候剛好是io util=100%的時候,這時候IO跟不上客戶端寫入速度造成阻塞。

有了以上現(xiàn)象,我們可以確定問題是由于IO跟不上客戶端寫入速度引起,第2章我們已經(jīng)做了mongodb服務(wù)層的優(yōu)化,現(xiàn)在我們開始著手wiredtiger存儲引擎層面的優(yōu)化,主要通過以下幾個方面:

cachesize調(diào)整

臟數(shù)據(jù)淘汰比例調(diào)整

checkpoint優(yōu)化

cachesize調(diào)整優(yōu)化(為何cacheSize越大性能越差)

于是查看mongod.conf配置文件,發(fā)現(xiàn)配置文件中配置的cacheSizeGB: 110G,可以看出,存儲引擎中KV總量幾乎已經(jīng)達(dá)到110G,按照5%臟頁開始刷盤的比例,峰值情況下cachesSize設(shè)置得越大,里面得臟數(shù)據(jù)就會越多,而磁盤IO能力跟不上臟數(shù)據(jù)得產(chǎn)生速度,這種情況很可能就是造成磁盤I/O瓶頸寫滿,并引起I/O跌0的原因。

此外,查看該機(jī)器的內(nèi)存,可以看到內(nèi)存總大小為190G,其中已經(jīng)使用110G左右,幾乎是mongod的存儲引起占用,這樣會造成內(nèi)核態(tài)的page cache減少,大量寫入的時候內(nèi)核cache不足就會引起磁盤缺頁中斷,引起大量的寫盤。

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

解決辦法:通過上面的分析問題可能是大量寫入的場景,臟數(shù)據(jù)太多容易造成一次性大量I/O寫入,于是我們可以考慮把存儲引起cacheSize調(diào)小到50G,來減少同一時刻I/O寫入的量,從而規(guī)避峰值情況下一次性大量寫入的磁盤I/O打滿阻塞問題。

存儲引擎dirty臟數(shù)據(jù)淘汰優(yōu)化

調(diào)整cachesize大小解決了5s請求超時問題,對應(yīng)告警也消失了,但是問題還是存在,5S超時消失了,1s超時問題還是偶爾會出現(xiàn)。

因此如何在調(diào)整cacheSize的情況下進(jìn)一步規(guī)避I/O大量寫的問題成為了問題解決的關(guān)鍵,進(jìn)一步分析存儲引擎原理,如何解決內(nèi)存和I/O的平衡關(guān)系成為了問題解決的關(guān)鍵,mongodb默認(rèn)存儲因為wiredtiger的cache淘汰策略相關(guān)的幾個配置如下:

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

調(diào)整cacheSize從120G到50G后,如果臟數(shù)據(jù)比例達(dá)到5%,則極端情況下如果淘汰速度跟不上客戶端寫入速度,這樣還是容易引起I/O瓶頸,最終造成阻塞。

解決辦法: 如何進(jìn)一步減少持續(xù)性I/O寫入,也就是如何平衡cache內(nèi)存和磁盤I/O的關(guān)系成為問題關(guān)鍵所在。從上表中可以看出,如果臟數(shù)據(jù)及總內(nèi)占用存達(dá)到一定比例,后臺線程開始選擇page進(jìn)行淘汰寫盤,如果臟數(shù)據(jù)及內(nèi)存占用比例進(jìn)一步增加,那么用戶線程就會開始做page淘汰,這是個非常危險的阻塞過程,造成用戶請求驗證阻塞。平衡cache和I/O的方法: 調(diào)整淘汰策略,讓后臺線程盡早淘汰數(shù)據(jù),避免大量刷盤,同時降低用戶線程閥值,避免用戶線程進(jìn)行page淘汰引起阻塞。優(yōu)化調(diào)整存儲引起配置如下:

eviction_target: 75%

eviction_trigger:97%

eviction_dirty_target: %3

eviction_dirty_trigger:25%

evict.threads_min:8

evict.threads_min:12

總體思想是讓后臺evict盡量早點淘汰臟頁page到磁盤,同時調(diào)整evict淘汰線程數(shù)來加快臟數(shù)據(jù)淘汰,調(diào)整后mongostat及客戶端超時現(xiàn)象進(jìn)一步緩解。

存儲引擎checkpoint優(yōu)化調(diào)整

存儲引擎得checkpoint檢測點,實際上就是做快照,把當(dāng)前存儲引擎的臟數(shù)據(jù)全部記錄到磁盤。觸發(fā)checkpoint的條件默認(rèn)又兩個,觸發(fā)條件如下:

固定周期做一次checkpoint快照,默認(rèn)60s

增量的redo log(也就是journal日志)達(dá)到2G

當(dāng)journal日志達(dá)到2G或者redo log沒有達(dá)到2G并且距離上一次時間間隔達(dá)到60s,wiredtiger將會觸發(fā)checkpoint,如果在兩次checkpoint的時間間隔類evict淘汰線程淘汰的dirty page越少,那么積壓的臟數(shù)據(jù)就會越多,也就是checkpoint的時候臟數(shù)據(jù)就會越多,造成checkpoint的時候大量的IO寫盤操作。如果我們把checkpoint的周期縮短,那么兩個checkpoint期間的臟數(shù)據(jù)相應(yīng)的也就會減少,磁盤IO 100%持續(xù)的時間也就會縮短。

checkpoint調(diào)整后的值如下:

checkpoint=(wait=25,log_size=1GB)

存儲引擎優(yōu)化前后IO對比

通過上面三個方面的存儲引擎優(yōu)化后,磁盤IO開始平均到各個不同的時間點,iostat監(jiān)控優(yōu)化后的IO負(fù)載如下:

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

從上面的io負(fù)載圖可以看出,之前的IO一會兒為0%,一會兒100%現(xiàn)象有所緩解,總結(jié)如下圖所示:

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

存儲引擎優(yōu)化前后時延對比

優(yōu)化前后時延對比如下(注: 該集群有幾個業(yè)務(wù)同時使用,優(yōu)化前后時延對比如下):

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

從上圖可以看出,存儲引擎優(yōu)化后時間延遲進(jìn)一步降低并趨于平穩(wěn),從平均80ms到平均20ms左右,但是還是不完美,有抖動。

服務(wù)器系統(tǒng)磁盤IO問題解決

服務(wù)器IO硬件問題背景

如第3節(jié)所述,當(dāng)wiredtiger大量淘汰數(shù)據(jù)后,發(fā)現(xiàn)只要每秒磁盤寫入量超過500M/s,接下來的幾秒鐘內(nèi)util就會持續(xù)100%,w/s幾乎跌0,于是開始懷疑磁盤硬件存在缺陷。

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

從上圖可以看出磁盤為nvMe的ssd盤,查看相關(guān)數(shù)據(jù)可以看出該盤IO性能很好,支持每秒2G寫入,iops能達(dá)到2.5W/S,而我們線上的盤只能每秒寫入最多500M。

服務(wù)器IO硬件問題解決后性能對比

于是考慮把該分片集群的主節(jié)點全部遷移到另一款服務(wù)器,該服務(wù)器也是ssd盤,io性能達(dá)到2G/s寫入(注意:只遷移了主節(jié)點,從節(jié)點還是在之前的IO-500M/s的服務(wù)器)。 遷移完成后,發(fā)現(xiàn)性能得到了進(jìn)一步提升,時延遲降低到2-4ms/s,三個不同業(yè)務(wù)層面看到的時延監(jiān)控如下圖所示:

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程

從上圖時延可以看出,遷移主節(jié)點到IO能力更好的機(jī)器后,時延進(jìn)一步降低到平均2-4ms。

雖然時延降低到了平均2-4ms,但是還是有很多幾十ms的尖刺,鑒于篇幅將在下一期分享大家原因,最終保存所有時延控制在5ms以內(nèi),并消除幾十ms的尖刺。

此外,nvme的ssd io瓶頸問題原因,經(jīng)過和廠商確認(rèn)分析,最終定位到是linux內(nèi)核版本不匹配引起,如果大家nvme ssd盤有同樣問題,記得升級linux版本到3.10.0-957.27.2.el7.x86_64版本,升級后nvme ssd的IO能力達(dá)到2G/s以上寫入。

總結(jié)及遺留問題

通過mongodb服務(wù)層配置優(yōu)化、存儲引擎優(yōu)化、硬件IO提升三方面的優(yōu)化后,該大流量寫入集群的平均時延從之前的平均數(shù)百ms降低到了平均2-4ms,整體性能提升數(shù)十倍,效果明顯。

但是,從4.2章節(jié)優(yōu)化后的時延可以看出,集群偶爾還是會有抖動,鑒于篇幅,下期會分享如果消除4.2章節(jié)中的時延抖動,最終保持時間完全延遲控制在2-4ms,并且無任何超過10ms的抖動,敬請期待,下篇會更加精彩。

此外,在集群優(yōu)化過程中采了一些坑,下期會繼續(xù)分析大流量集群采坑記。

注意: 文章中的一些優(yōu)化方法并不是一定適用于所有mongodb場景,請根據(jù)實際業(yè)務(wù)場景和硬件資源能力進(jìn)行優(yōu)化,而不是按部就班。

看完上述內(nèi)容是否對您有幫助呢?如果還想對相關(guān)知識有進(jìn)一步的了解或閱讀更多相關(guān)文章,請關(guān)注創(chuàng)新互聯(lián)-成都網(wǎng)站建設(shè)公司行業(yè)資訊頻道,感謝您對創(chuàng)新互聯(lián)的支持。


文章名稱:百萬級高并發(fā)mongodb集群性能數(shù)十倍提升優(yōu)化的實踐過程-創(chuàng)新互聯(lián)
鏈接分享:http://weahome.cn/article/csseog.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部