億級(jí)月活全民K歌Feed業(yè)務(wù)在騰訊云MongoDB中的應(yīng)用及優(yōu)化實(shí)踐

來(lái)源: 騰訊云數(shù)據(jù)庫(kù)
作者:ctychen,ianxiong
時(shí)間:2021-12-07
15478
本文主要分享K歌技術(shù)演進(jìn)過(guò)程中的一些踩坑過(guò)程、方案設(shè)計(jì)、性能優(yōu)化等,主要包括以下技術(shù)點(diǎn)。

全民K歌作為騰訊音樂(lè)集團(tuán)四大產(chǎn)品線(xiàn)之一,月活超過(guò)1.5億,并不斷推出新的音娛功能及新玩法,極大豐富了數(shù)億用戶(hù)的音樂(lè)娛樂(lè)活動(dòng)。

MongoDB天然支持高可用、分布式、高性能、高壓縮、schema free、完善的客戶(hù)端訪(fǎng)問(wèn)均衡策略等功能。作為騰訊音樂(lè)集體核心部門(mén),K歌Feed等業(yè)務(wù)采用騰訊云MongoDB作為主存儲(chǔ)服務(wù),極大的方便了K歌業(yè)務(wù)的快速迭代開(kāi)發(fā)。

本文主要分享K歌技術(shù)演進(jìn)過(guò)程中的一些踩坑過(guò)程、方案設(shè)計(jì)、性能優(yōu)化等,主要包括以下技術(shù)點(diǎn):

·全民K歌業(yè)務(wù)特性

·Feed業(yè)務(wù)讀寫(xiě)選型

·Feed數(shù)據(jù)吐出控制策略?xún)?yōu)化

·Feed核心表設(shè)計(jì)

·K歌業(yè)務(wù)層面踩坑及優(yōu)化過(guò)程

·K歌業(yè)務(wù)MongoDB使用踩坑及優(yōu)化

業(yè)務(wù)層面優(yōu)化過(guò)程

1.騰訊音樂(lè)全民K歌業(yè)務(wù)特性

每一個(gè)社交產(chǎn)品,都離不開(kāi)Feed流設(shè)計(jì),在全民K歌的場(chǎng)景,需要解決以下主要問(wèn)題:

·我們有一些千w粉絲,百萬(wàn)粉絲的用戶(hù),存在關(guān)系鏈擴(kuò)散的性能挑戰(zhàn)

·Feed業(yè)務(wù)種類(lèi)繁多,有復(fù)雜的業(yè)務(wù)策略來(lái)控制保證重要的Feed曝光

對(duì)于Feed流的數(shù)據(jù)吐出,有種類(lèi)繁多的控制策略,通過(guò)這些不同的控制策略來(lái)實(shí)現(xiàn)不通功能:

·大v曝光頻控,避免刷流量的行為

·好友共同發(fā)布了一些互動(dòng)玩法的Feed,進(jìn)行合并,避免刷屏

·支持不同分類(lèi)Feed的檢索

·安全問(wèn)題需要過(guò)濾掉的用戶(hù)Feed

·推薦實(shí)時(shí)插流/混排

·低質(zhì)量的Feed,系統(tǒng)自動(dòng)發(fā)類(lèi)型的Feed做曝光頻控

2.讀寫(xiě)選型

640.webp.jpg

Feed主流實(shí)現(xiàn)模型主要分為3種,這些模型在業(yè)界都有大型產(chǎn)品在用:

·讀擴(kuò)散(QQ空間)

·寫(xiě)擴(kuò)散(微信朋友圈)

·大v讀擴(kuò)散+普通用戶(hù)寫(xiě)擴(kuò)散(新浪微博)

沒(méi)有最好的模式,只有適合的架構(gòu),主要是權(quán)衡自己的業(yè)務(wù)模型,讀寫(xiě)比,以及歷史包袱和實(shí)現(xiàn)成本。

K歌使用的是讀擴(kuò)散模型,使用讀擴(kuò)散模型的考慮如下:

·存在不少千萬(wàn)/百萬(wàn)粉絲的大v,寫(xiě)擴(kuò)散嚴(yán)重,推送延遲高,同時(shí)存儲(chǔ)成本會(huì)高

·低活用戶(hù),流失用戶(hù)推送浪費(fèi)計(jì)算資源和存儲(chǔ)資源

·安全合規(guī)相關(guān)的審核會(huì)引發(fā)大量寫(xiě)擴(kuò)散

·寫(xiě)擴(kuò)散qps=3 x讀擴(kuò)散qps

·K歌關(guān)系鏈導(dǎo)入的歷史原因,早起寫(xiě)擴(kuò)散成本高,同時(shí)后期改成讀寫(xiě)擴(kuò)散混合的模式改造成本大

但是讀擴(kuò)散模式存在以下比較明顯的缺點(diǎn):

·翻頁(yè)把時(shí)間線(xiàn)前面的所有數(shù)據(jù)拉出來(lái),性能開(kāi)銷(xiāo)越來(lái)越大,性能越來(lái)越差

·關(guān)注+好友數(shù)量可達(dá)萬(wàn)級(jí)別,實(shí)現(xiàn)全局的過(guò)濾,插流,合并,頻控策略復(fù)雜,性能不足

3.讀擴(kuò)散優(yōu)化

讀擴(kuò)散模型的存儲(chǔ)數(shù)據(jù)主要分為3大塊:

·關(guān)系鏈

·Feed數(shù)據(jù)

·最新更新時(shí)間戳

3.1.優(yōu)化背景

未優(yōu)化前的關(guān)系鏈讀擴(kuò)散模型,每次拉取Feed數(shù)據(jù)的時(shí)候,都需要通過(guò)關(guān)系鏈,時(shí)間戳,以及Feed索引數(shù)據(jù)來(lái)讀擴(kuò)散構(gòu)建候選結(jié)果集。最后根據(jù)具體的Feedid拉取Feed詳情來(lái)構(gòu)建結(jié)果進(jìn)行返回。

對(duì)于首屏,如果一頁(yè)為10條,通過(guò)關(guān)系鏈+最新時(shí)間戳過(guò)濾出最新的20個(gè)uid(預(yù)拉多一些避免各種業(yè)務(wù)過(guò)濾合并策略把數(shù)據(jù)過(guò)濾完了),然后拉取每個(gè)uid最新的60條Feed的簡(jiǎn)單的索引信息來(lái)構(gòu)建候選集合,通過(guò)各種業(yè)務(wù)合并過(guò)濾策略來(lái)構(gòu)建最多10條最新Feedid,再拉取Feed詳細(xì)信息構(gòu)建響應(yīng)結(jié)果。

翻頁(yè)的時(shí)候把上一次返回的數(shù)據(jù)的最小時(shí)間戳basetime帶過(guò)來(lái),然后需要把basetime之前的有發(fā)布Feed的uid以及basetime之后有發(fā)布的最近20個(gè)uid過(guò)濾出來(lái),重復(fù)上面構(gòu)建候選集合的過(guò)程來(lái)輸出這一頁(yè)的數(shù)據(jù)。這種實(shí)現(xiàn)邏輯翻頁(yè)會(huì)越來(lái)越慢,延遲不穩(wěn)定。

3.2.優(yōu)化過(guò)程

針對(duì)以上問(wèn)題,所以我們?cè)谧x擴(kuò)散模型上進(jìn)行了一些優(yōu)化,優(yōu)化架構(gòu)圖如下:

640.webp (1).jpg

我們通過(guò)讀擴(kuò)散結(jié)果的Cache模式,解決翻頁(yè)越來(lái)越慢,復(fù)雜的全局過(guò)濾邏輯。

Cahce優(yōu)勢(shì)

·靈活過(guò)濾,實(shí)現(xiàn)復(fù)雜的過(guò)濾合并邏輯

·翻頁(yè)讀Cache性能高,首頁(yè)使用Cache避免重復(fù)計(jì)算

時(shí)間線(xiàn)Cache需要解決的問(wèn)題?弊端?

·關(guān)系鏈變更Cache有延遲

·臟Feed導(dǎo)致Cache體積減小

此外,我們把Cache主要分為全量生成過(guò)程,增量更新過(guò)程,以及修補(bǔ)邏輯三部分來(lái)解決這些問(wèn)題:

·全量是在首次拉取,和24小時(shí)定時(shí)更新

·增量則是在首頁(yè)刷新,無(wú)最新數(shù)據(jù)則復(fù)用Cache

·通過(guò)緩存關(guān)系鏈,如果關(guān)系鏈變更,活臟Feed太多過(guò)濾后導(dǎo)致的Cache體積過(guò)小,則觸發(fā)修補(bǔ)邏輯

最終,通過(guò)這些策略,讓我們的Feed流系統(tǒng)也具備了寫(xiě)擴(kuò)散的一些優(yōu)勢(shì),主要優(yōu)勢(shì)如下:

·減少重復(fù)計(jì)算

·有全局的Feed視圖,方便實(shí)現(xiàn)全局策略

4.主要表設(shè)計(jì)

4.1.Feed表設(shè)計(jì)

Feed這里的設(shè)計(jì)建立了2個(gè)表:

·一個(gè)是Feed詳情表

該表使用用戶(hù)userid做片健,F(xiàn)eedid做唯一健,表核心字段如下:

640.webp (2).jpg

·Feed Cache表

該表使用uid做片健和唯一健,并且做ttl,表核心字段如下:

640.webp (3).jpg

FeedCache是一個(gè)kv存儲(chǔ)的文檔,k是uid,value是CacheFeedData jce序列化后的結(jié)果。為了避免TTL刪除數(shù)據(jù)消耗線(xiàn)上業(yè)務(wù)性能:可以在寫(xiě)入數(shù)據(jù)時(shí)指定過(guò)期時(shí)間。過(guò)期時(shí)間直接配置成業(yè)務(wù)低峰期時(shí)段。

4.2.賬號(hào)關(guān)系表設(shè)計(jì)

關(guān)注關(guān)系鏈常規(guī)涉及兩個(gè)維度的數(shù)據(jù):

·一個(gè)關(guān)注,一個(gè)粉絲(一個(gè)關(guān)注動(dòng)作會(huì)產(chǎn)生兩個(gè)維度數(shù)據(jù))。

關(guān)注列表

關(guān)注一般不是很多,最多一般只有幾千,經(jīng)常會(huì)被全部拉出來(lái),這個(gè)可以存儲(chǔ)為kv的方式(高性能可以考慮內(nèi)存型數(shù)據(jù)庫(kù)或cache)。

關(guān)注是用Redis存儲(chǔ)的,一個(gè)key對(duì)應(yīng)的value是上面RightCache這個(gè)結(jié)構(gòu)的jce序列化后的結(jié)果。

640.webp (4).jpg640.webp (5).jpg

·粉絲

粉絲是一個(gè)長(zhǎng)列表(幾百萬(wàn)甚至上千萬(wàn)),一般會(huì)以列表展示,存儲(chǔ)與MongoDB中,以用戶(hù)id為片健,每個(gè)粉絲作為一個(gè)單獨(dú)的doc,使用內(nèi)存型的存儲(chǔ)內(nèi)存碎片的損耗比較高,內(nèi)存成本大。關(guān)注和粉絲數(shù)據(jù)可以使用消息隊(duì)列來(lái)實(shí)現(xiàn)最終一致性。

粉絲數(shù)據(jù)按照MongoDB文檔存儲(chǔ),主要包含以下字段:opuid,fuid,realtiontype,time。

MongoDb使用層面優(yōu)化

該業(yè)務(wù)MongoDB部署架構(gòu)圖如下:

640.webp (6).jpg

K歌業(yè)務(wù)MongoDB架構(gòu)圖:客戶(hù)端通過(guò)騰訊云VIP轉(zhuǎn)發(fā)到代理mongos層,代理mongos接受到請(qǐng)求后,從config server(存儲(chǔ)路由信息,架構(gòu)圖中未體現(xiàn))獲取路由信息,然后根據(jù)這條路由信息獲取轉(zhuǎn)發(fā)規(guī)則,最終轉(zhuǎn)發(fā)該請(qǐng)求到對(duì)應(yīng)的存儲(chǔ)層分片。

在業(yè)務(wù)上線(xiàn)開(kāi)發(fā)過(guò)程中,發(fā)現(xiàn)MongoDB使用的一些不合理,通過(guò)對(duì)這些不合理的使用方式優(yōu)化,提升了訪(fǎng)問(wèn)MongoDB的性能,最終提升了整個(gè)Feed流系統(tǒng)用戶(hù)體驗(yàn)。

K歌業(yè)務(wù)MongoDB訪(fǎng)問(wèn)主要優(yōu)化點(diǎn)如下:

1.最優(yōu)片建及分片方式選擇

前面提到信息流業(yè)務(wù)Feed詳情表、粉絲列表存儲(chǔ)在MongoDB中,兩個(gè)表都采用用戶(hù)userId來(lái)做分片片建,分片方式采用hashed分片,并且提前進(jìn)行預(yù)分片:

sh.shardCollection("xx.follower",{userId:"hashed"},false,{numInitialChunks:8192*分片數(shù)})

sh.shardCollection("xx.FeedInfo",{userId:"hashed"},false,{numInitialChunks:8192*分片數(shù)})

兩個(gè)表都userId做片建,并且采用hashed分片方式,同時(shí)提前對(duì)表做預(yù)分片操作,主要基于以下方面考慮:

·數(shù)據(jù)寫(xiě)

通過(guò)提前預(yù)分片并且采用hashed分片方式,可以保證數(shù)據(jù)均衡的寫(xiě)入到不同分片,避免數(shù)據(jù)不均引起的moveChunk操作,充分利用了每個(gè)分片的存儲(chǔ)能力,實(shí)現(xiàn)寫(xiě)入性能的最大化。

·數(shù)據(jù)讀

通過(guò)userId查詢(xún)某用戶(hù)的Feed詳情和通過(guò)userId查詢(xún)?cè)撚脩?hù)的粉絲列表信息,由于采用hashed分片方式,同一個(gè)Id值對(duì)應(yīng)的hash計(jì)算值會(huì)落在同一個(gè)shard分片,這樣可以保證整個(gè)查詢(xún)的效率最高。

說(shuō)明:由于查詢(xún)都是指定id類(lèi)型查詢(xún),因此可以保證從同一個(gè)shard讀取數(shù)據(jù),實(shí)現(xiàn)了讀取性能的最大化。但是,如果查詢(xún)是例如userId類(lèi)的范圍查詢(xún),例如db.FeedInfo.find({userId:{$gt:1000,$lt:2000}}),這種場(chǎng)景就不適合用hashed分片方式,因?yàn)闈M(mǎn)足{$gt:1000}條件的數(shù)據(jù)可能很多條,通過(guò)hash計(jì)算后,這些數(shù)據(jù)會(huì)散列到多個(gè)分片,這種場(chǎng)景范圍分片會(huì)更好,一個(gè)范圍內(nèi)的數(shù)據(jù)可能落到同一個(gè)分片。所以,分片集群片建選擇、分片方式對(duì)整個(gè)集群讀寫(xiě)性能起著非常重要的核心作用,需要根據(jù)業(yè)務(wù)的實(shí)際情況進(jìn)行選擇。

K歌feed業(yè)務(wù)都是根據(jù)feedId、userId進(jìn)行查詢(xún),不存在范圍查詢(xún),因此選用hash預(yù)分片方式進(jìn)行片建設(shè)置,這樣可以最大化提升查詢(xún)、寫(xiě)入功能。

2.查詢(xún)不帶片建如何優(yōu)化

上一節(jié)提到,查詢(xún)?nèi)绻麕掀?,可以保證數(shù)據(jù)落在同一個(gè)shard,這樣可以實(shí)現(xiàn)讀性能的最大化。但是,實(shí)際業(yè)務(wù)場(chǎng)景中,一個(gè)業(yè)務(wù)訪(fǎng)問(wèn)同一個(gè)表,有些請(qǐng)求可以帶上片建字段,有些查詢(xún)沒(méi)有片建,這部分不帶片建的查詢(xún)需要廣播到多個(gè)shard,然后mongos聚合后返回客戶(hù)端,這類(lèi)不帶片建的查詢(xún)效率相比從同一個(gè)shard獲取數(shù)據(jù)性能會(huì)差很多。

如果集群分片數(shù)比較多,某個(gè)不帶片建的查詢(xún)SQL頻率很高,為了提升查詢(xún)性能,可以通過(guò)建立輔助索引表來(lái)規(guī)避解決該問(wèn)題。以Feed詳情表為例,該表片建為用戶(hù)userId,如果用戶(hù)想看自己發(fā)表過(guò)的所有Feed,查詢(xún)條件只要帶上userId即可。

但是,如果需要FeedId獲取指定某條Feed則需要進(jìn)行查詢(xún)的廣播操作,因?yàn)镕eed詳情表片建為userId,這時(shí)候性能會(huì)受影響。不帶片建查詢(xún)不僅僅影響查詢(xún)性能,還有加重每個(gè)分片的系統(tǒng)負(fù)載,因此可以通過(guò)增加輔助索引表(假設(shè)表名:FeedId_userId_relationship)的方式來(lái)解決該問(wèn)題。輔助表中每個(gè)doc文檔主要包含2個(gè)字段:

·FeedId字段

該字段和詳情表的FeedId一致,代表具體的一條Feed詳情。

·UserId

該字段和詳情表userId一致,代表該FeedId對(duì)應(yīng)的這條Feed詳情信息由該user發(fā)起。

FeedId_userId_relationship輔助表采用FeedId做為片建,同樣采用前面提到的預(yù)分片功能,該表和Feed詳情表的隱射關(guān)系如下:

640.webp (7).jpg

如上圖,通過(guò)某個(gè)FeedId查詢(xún)具體Feed,首先根據(jù)FeedId從輔助索引表中查找該FeedId對(duì)應(yīng)的userId,然后根據(jù)查詢(xún)到的userId+FeedId的組合獲取對(duì)應(yīng)的詳情信息。整個(gè)查詢(xún)過(guò)程需要查兩個(gè)表,查詢(xún)語(yǔ)句如下:

//根據(jù)feedId獲取對(duì)應(yīng)的userId db.FeedId_userId_relationship.find({“FeedId”:“375”},{userId:1})//假設(shè)返回的userId為”3567”//根據(jù)userId+FeedId的組合獲取具體的某條feed信息db.FeedInfo.find({“userId”:“3567”,“FeedId”:“375”})

如上,通過(guò)引入輔助索引表,最終解決跨分片廣播問(wèn)題。引入輔助表會(huì)增加一定的存儲(chǔ)成本,同時(shí)會(huì)增加一次輔助查詢(xún),一般只有在分片shard比較多,并且不帶片建的查詢(xún)比較頻繁的情況使用。

3.count慢操作優(yōu)化

前面提到,粉絲關(guān)系表存在MongoDB中,每條數(shù)據(jù)主要包含幾個(gè)字段,用戶(hù)的每個(gè)粉絲對(duì)應(yīng)一條MongoDB文檔數(shù)據(jù),對(duì)應(yīng)數(shù)據(jù)內(nèi)容如下

{"_id":ObjectId("6176647d2b18266890bb7c63"),"userid":“345”,"follow_userid":“3333”,"realtiontype":3,"follow_time":ISODate("2017-06-12T11:26:26Z")}

一個(gè)用戶(hù)的每個(gè)粉絲對(duì)應(yīng)一條數(shù)據(jù),如果需要查找某個(gè)用戶(hù)下面擁有多少個(gè)粉絲,則通過(guò)下面的查詢(xún)獲取(例如查找用戶(hù)id為”345”的用戶(hù)的粉絲總數(shù)):

db.fans.count({"userid":“345”}

該查詢(xún)對(duì)應(yīng)執(zhí)行計(jì)劃如下:

 {  

           "executionSuccess" : true,  

           "nReturned" : 0,  

           "executionTimeMillis" : 0,  

           "totalKeysExamined" : 156783,  

           "totalDocsExamined" : 0,  

           "executionStages" : {  

                   "stage" : "COUNT",  

                  "nReturned" : 0,  

                  ......  

                  "nSkipped" : 0,  

                 "inputStage" : {  

                          "stage" : "COUNT_SCAN",  

                          ......  

                 }  

          },  

        "allPlansExecution" : [ ]  

  }

和其他關(guān)系型數(shù)據(jù)庫(kù)(例如mysql)類(lèi)似,從上面的執(zhí)行計(jì)劃可以看出,對(duì)某個(gè)表按照某個(gè)條件求count,走最優(yōu)索引情況下,其快慢主要和滿(mǎn)足條件的數(shù)據(jù)量多少成正比關(guān)系。例如該用戶(hù)如果粉絲數(shù)量越多,則其掃描的keys(也就是索引表)會(huì)越多,因此其查詢(xún)也會(huì)越慢。

從上面的分析可以看出,如果某個(gè)用戶(hù)粉絲很多,則其count性能會(huì)很慢。因此,我們可以使用一個(gè)冪等性計(jì)算的計(jì)數(shù)來(lái)存儲(chǔ)粉絲總數(shù)和關(guān)注總數(shù),這個(gè)數(shù)據(jù)訪(fǎng)問(wèn)量比較高,可以使用高性能的存儲(chǔ),例如Redis的來(lái)存儲(chǔ)。冪等性的計(jì)算可以使用Redis的lua腳本來(lái)保證。

優(yōu)化辦法:粉絲數(shù)量是一個(gè)Redis的key,用lua腳本執(zhí)行(計(jì)數(shù)key incrby操作與opuid_touid_op做key的setnx expire)來(lái)完成冪等性計(jì)算。

4.寫(xiě)大多數(shù)優(yōu)化

寫(xiě)入數(shù)據(jù)可以根據(jù)業(yè)務(wù)的數(shù)據(jù)可靠性來(lái)選擇不同的writeConcern策略:

{w:0}:對(duì)客戶(hù)端的寫(xiě)入不需要發(fā)送任何確認(rèn)。場(chǎng)景:性能要求高;不關(guān)注數(shù)據(jù)完整性

{w:1}:默認(rèn)的writeConcern,數(shù)據(jù)寫(xiě)入到Primary就向客戶(hù)端發(fā)送確認(rèn)。場(chǎng)景:兼顧性能與一定層度得數(shù)據(jù)可靠性。

{w:“majority”}:數(shù)據(jù)寫(xiě)入到副本集大多數(shù)成員后向客戶(hù)端發(fā)送確認(rèn)。場(chǎng)景:數(shù)據(jù)完整性要求比較高、避免數(shù)據(jù)回滾場(chǎng)景,該選項(xiàng)會(huì)降低寫(xiě)入性能。

對(duì)于可靠性要求比較高的場(chǎng)景往往還會(huì)使用{j:true}選項(xiàng)來(lái)保證寫(xiě)入時(shí)journal日志持久化之后才返回給客戶(hù)端確認(rèn)。數(shù)據(jù)可靠性高的場(chǎng)景會(huì)降低寫(xiě)的性能,在K歌Feed業(yè)務(wù)使用初期的場(chǎng)景會(huì)發(fā)現(xiàn)寫(xiě)大多數(shù)的場(chǎng)景都寫(xiě)延遲不太穩(wěn)定,核心業(yè)務(wù)都出現(xiàn)了這種情況,從5ms到1s抖動(dòng)。通過(guò)分析定位,我們發(fā)現(xiàn)是寫(xiě)時(shí)候到鏈?zhǔn)綇?fù)制到策略導(dǎo)致的。

鏈?zhǔn)綇?fù)制的概念:假設(shè)節(jié)點(diǎn)A(primary)、B節(jié)點(diǎn)(secondary)、C節(jié)點(diǎn)(secondary),如果B節(jié)點(diǎn)從A節(jié)點(diǎn)同步數(shù)據(jù),C節(jié)點(diǎn)從B節(jié)點(diǎn)同步數(shù)據(jù),這樣A->B->C之間就形成了一個(gè)鏈?zhǔn)降耐浇Y(jié)構(gòu),如下圖所示:

640.webp (8).jpg

MongoDB多節(jié)點(diǎn)副本集可以支持鏈?zhǔn)綇?fù)制,可以通過(guò)如下命令獲取當(dāng)前副本集是否支持鏈?zhǔn)綇?fù)制:

 cmgo-xx:SECONDARY> rs.conf().settings.chainingAllowed  

  true  

  cmgo-xx:SECONDARY>

此外,可以通過(guò)查看副本集中每個(gè)節(jié)點(diǎn)的同步源來(lái)判斷當(dāng)前副本集節(jié)點(diǎn)中是否存在有鏈?zhǔn)綇?fù)制情況,如果同步源為secondary從節(jié)點(diǎn),則說(shuō)明副本集中存在鏈?zhǔn)綇?fù)制,具體查看如下副本集參數(shù):

cmgo-xx:SECONDARY> rs.status().syncSourceHost  

  xx.xx.xx.xx:7021  

 cmgo-xx:SECONDARY>

由于業(yè)務(wù)配置為寫(xiě)多數(shù)派,鑒于性能考慮可以關(guān)閉鏈?zhǔn)綇?fù)制功能,MongoDB可以通過(guò)如下命令操作進(jìn)行關(guān)閉:

  cfg = rs.config()  

  cfg.settings.chainingAllowed = false

  rs.reconfig(cfg)

鏈?zhǔn)綇?fù)制好處:可以大大減輕主節(jié)點(diǎn)同步oplog的壓力。

鏈?zhǔn)綇?fù)制不足:當(dāng)寫(xiě)策略為majority時(shí),寫(xiě)請(qǐng)求的耗時(shí)變大。

當(dāng)業(yè)務(wù)采用“寫(xiě)大多數(shù)”策略時(shí),也相應(yīng)的關(guān)閉鏈?zhǔn)綇?fù)制;避免寫(xiě)請(qǐng)求耗時(shí)變大。我們關(guān)閉了鏈?zhǔn)綇?fù)制后整體寫(xiě)延遲文檔在10ms以?xún)?nèi)。

5.海量qps業(yè)務(wù)抖動(dòng)優(yōu)化

在一些核心集群,我們發(fā)現(xiàn)在高峰期偶爾會(huì)慢查詢(xún)變多,服務(wù)抖動(dòng),抖動(dòng)的表象看起來(lái)是因?yàn)閭€(gè)別CPU飆升導(dǎo)致的,通過(guò)分析具體高CPU的線(xiàn)程,以及perf性能分析具體的函數(shù),我們發(fā)現(xiàn)主要是兩個(gè)問(wèn)題:

高峰期連接數(shù)量陡漲,連接認(rèn)證開(kāi)銷(xiāo)過(guò)大,導(dǎo)致的CPU飆升。

WT存儲(chǔ)引擎cache使用率及臟數(shù)據(jù)比例太高,MongoDB的用戶(hù)線(xiàn)程阻塞進(jìn)行臟數(shù)據(jù)清理,最終業(yè)務(wù)側(cè)抖動(dòng)。

為了優(yōu)化這兩個(gè)問(wèn)題,我們通過(guò)優(yōu)化MongoDB的配置參數(shù)來(lái)解決:

·MongoDB連接池上下限一致,減少建立連接的開(kāi)銷(xiāo)

·提前觸發(fā)內(nèi)存清理eviction_target=60,用戶(hù)線(xiàn)程參與內(nèi)存清理的觸發(fā)值提高到97%:eviction_trigger=97,增加更多的清理線(xiàn)程:evict.threads_max:20,從而減少高峰期慢查詢(xún)150k/min=>20k/min,服務(wù)穩(wěn)定性也的到了提升

優(yōu)化后效果如圖:

640.webp.jpg

6.數(shù)據(jù)備份過(guò)程業(yè)務(wù)抖動(dòng)優(yōu)化

640.webp (1).jpg

騰訊云MongoDb默認(rèn)凌晨會(huì)定期對(duì)集群數(shù)據(jù)做全量備份和增量備份,并支持默認(rèn)7天內(nèi)的任意時(shí)間點(diǎn)回檔。但是,隨著集群數(shù)據(jù)量逐漸的增加,當(dāng)前該集群數(shù)據(jù)量已經(jīng)比較大,開(kāi)始出現(xiàn)凌晨集群定期抖動(dòng),主要現(xiàn)象如下:

·訪(fǎng)問(wèn)時(shí)延增加

·慢日志增加

·CPU使用率增加

通過(guò)分析,發(fā)現(xiàn)問(wèn)題和數(shù)據(jù)備份時(shí)間點(diǎn)一致,由于物理備份和邏輯備份期間需要對(duì)整實(shí)例進(jìn)行數(shù)據(jù)備份,系統(tǒng)資源負(fù)載增加,最終影響業(yè)務(wù)查詢(xún)服務(wù)。

優(yōu)化方式:數(shù)據(jù)備份期間隱藏節(jié)點(diǎn),確保該節(jié)點(diǎn)對(duì)客戶(hù)端不可見(jiàn)。

作者:ctychen,ianxiong

全民K歌后臺(tái)開(kāi)發(fā)一組/騰訊MongoDB團(tuán)隊(duì)

騰訊云MongoDB:

騰訊云MongoDB當(dāng)前服務(wù)于游戲、電商、社交、教育、新聞資訊、金融、物聯(lián)網(wǎng)、軟件服務(wù)等多個(gè)行業(yè);MongoDB團(tuán)隊(duì)(簡(jiǎn)稱(chēng)CMongo)致力于對(duì)開(kāi)源MongoDB內(nèi)核進(jìn)行深度研究及持續(xù)性?xún)?yōu)化(如百萬(wàn)庫(kù)表、物理備份、免密、審計(jì)等),為用戶(hù)提供高性能、低成本、高可用性的安全數(shù)據(jù)庫(kù)存儲(chǔ)服務(wù)。后續(xù)持續(xù)分享MongoDB在騰訊內(nèi)部及外部的典型應(yīng)用場(chǎng)景、踩坑案例、性能優(yōu)化、內(nèi)核模塊化分析。

立即登錄,閱讀全文
版權(quán)說(shuō)明:
本文內(nèi)容來(lái)自于騰訊云數(shù)據(jù)庫(kù),本站不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。文章內(nèi)容系作者個(gè)人觀(guān)點(diǎn),不代表快出海對(duì)觀(guān)點(diǎn)贊同或支持。如有侵權(quán),請(qǐng)聯(lián)系管理員(zzx@kchuhai.com)刪除!
相關(guān)文章
騰訊云數(shù)據(jù)庫(kù)PostgreSQL全面支持PG 17
騰訊云數(shù)據(jù)庫(kù)PostgreSQL全面支持PG 17
即日起,騰訊云PostgreSQL全面支持PostgreSQL 17.0。所有用戶(hù)可使用大版本升級(jí)能力升級(jí)至最新的PostgreSQL 17.0進(jìn)行體驗(yàn),也可以在產(chǎn)品購(gòu)買(mǎi)頁(yè)直接購(gòu)買(mǎi)。
騰訊云
云服務(wù)
2024-12-152024-12-15
高可用這個(gè)問(wèn)題,加機(jī)器就能解決?
高可用這個(gè)問(wèn)題,加機(jī)器就能解決?
互聯(lián)網(wǎng)服務(wù)的可用性問(wèn)題是困擾企業(yè)IT人員的達(dá)摩克利斯之劍:防于未然,體現(xiàn)不出價(jià)值。已然發(fā)生,又面臨P0危機(jī)。就更別提穩(wěn)定性建設(shè)背后顯性的IT預(yù)算問(wèn)題與隱性的人員成本問(wèn)題。
騰訊云
云服務(wù)
2024-11-252024-11-25
TDSQL TDStore引擎版替換HBase:在歷史庫(kù)場(chǎng)景中的成本與性能優(yōu)勢(shì)
TDSQL TDStore引擎版替換HBase:在歷史庫(kù)場(chǎng)景中的成本與性能優(yōu)勢(shì)
HBase憑借其高可用性、高擴(kuò)展性和強(qiáng)一致性,以及在廉價(jià)PC服務(wù)器上的低部署成本,廣泛應(yīng)用于大規(guī)模數(shù)據(jù)分析。
騰訊云
云服務(wù)
2024-11-042024-11-04
復(fù)雜查詢(xún)性能弱,只讀分析引擎來(lái)幫忙
復(fù)雜查詢(xún)性能弱,只讀分析引擎來(lái)幫忙
隨著當(dāng)今業(yè)務(wù)的高速發(fā)展,復(fù)雜多表關(guān)聯(lián)的場(chǎng)景越來(lái)越普遍。但基于行式存儲(chǔ)的數(shù)據(jù)庫(kù)在進(jìn)行復(fù)雜查詢(xún)時(shí)性能相對(duì)較弱。
騰訊云
云服務(wù)
2024-11-022024-11-02
優(yōu)質(zhì)服務(wù)商推薦
更多
掃碼登錄
打開(kāi)掃一掃, 關(guān)注公眾號(hào)后即可登錄/注冊(cè)
加載中
二維碼已失效 請(qǐng)重試
刷新
賬號(hào)登錄/注冊(cè)
小程序
快出海小程序
公眾號(hào)
快出海公眾號(hào)
商務(wù)合作
商務(wù)合作
投稿采訪(fǎng)
投稿采訪(fǎng)
出海管家
出海管家