數(shù)據(jù)庫(kù)“炸了”,加CPU加內(nèi)存?或許還有更好的解決方法!

01?概述

之前在做業(yè)務(wù)應(yīng)用系統(tǒng)壓力測(cè)試項(xiàng)目的時(shí)候,發(fā)現(xiàn)大部分性能不達(dá)標(biāo)的應(yīng)用,問(wèn)題都出在數(shù)據(jù)庫(kù)上。數(shù)據(jù)庫(kù)壓力過(guò)大是每個(gè)業(yè)務(wù)經(jīng)理都多多少少面臨過(guò)的問(wèn)題,那么解決的辦法除了縱向提高數(shù)據(jù)庫(kù)配置之外,是否還有其他更高效的途徑呢?


02?原因分析

眾所周知,單臺(tái)數(shù)據(jù)庫(kù)實(shí)例的配置是有瓶頸的,特別是關(guān)系型數(shù)據(jù)庫(kù),當(dāng)CPU和內(nèi)存配置提高到一定程度后,性能就不再提升了,即使對(duì)數(shù)據(jù)庫(kù)的內(nèi)核進(jìn)行優(yōu)化,也只能稍微抬高這個(gè)瓶頸線。

在我經(jīng)歷過(guò)的應(yīng)用系統(tǒng)壓力測(cè)試工作中發(fā)現(xiàn),大廠提供的應(yīng)用產(chǎn)品通常服務(wù)器壓力和數(shù)據(jù)庫(kù)壓力是基本持平的,小的開(kāi)發(fā)商提供的應(yīng)用系統(tǒng)往往是服務(wù)器還沒(méi)有明顯壓力,CPU、內(nèi)存使用率都很低,數(shù)據(jù)庫(kù)卻已經(jīng)“炸了”。

所以,底層代碼邏輯上是否與數(shù)據(jù)庫(kù)合理交互是原因之一,有經(jīng)驗(yàn)的開(kāi)發(fā)工程師會(huì)思考如何盡可能地少與數(shù)據(jù)庫(kù)交互,把推拉數(shù)據(jù)庫(kù)完成的功能模塊轉(zhuǎn)化為通過(guò)服務(wù)器計(jì)算來(lái)完成,從而將數(shù)據(jù)庫(kù)壓力轉(zhuǎn)移到服務(wù)器上。

我們還可以有效利用Redis、MQ等中間件,分擔(dān)數(shù)據(jù)庫(kù)壓力。當(dāng)已經(jīng)無(wú)法通過(guò)上面方案降低數(shù)據(jù)庫(kù)壓力后,還可以采用分布式數(shù)據(jù)庫(kù)、主從讀寫分離數(shù)據(jù)庫(kù)來(lái)橫向擴(kuò)展數(shù)據(jù)庫(kù)性能。從原理上分析,橫向擴(kuò)展數(shù)據(jù)庫(kù)性能是可以無(wú)限提高數(shù)據(jù)庫(kù)承壓能力的。

所以,我準(zhǔn)備從產(chǎn)品代碼、中間件、讀寫分離三塊來(lái)講解如何優(yōu)化應(yīng)用對(duì)數(shù)據(jù)庫(kù)的使用,提升應(yīng)用系統(tǒng)性能。


03?在代碼層面消化數(shù)據(jù)庫(kù)壓力

在代碼層面可以通過(guò)創(chuàng)建索引轉(zhuǎn)移壓力兩種方式給數(shù)據(jù)庫(kù)減壓。

索引是MySQL和Oracle數(shù)據(jù)庫(kù)本身提供的功能,合理創(chuàng)建索引可以提高數(shù)據(jù)檢索效率,降低數(shù)據(jù)庫(kù)IO和CPU的消耗。

在開(kāi)發(fā)初期,我們就應(yīng)該根據(jù)數(shù)據(jù)庫(kù)模型表和字段的作用來(lái)決定是否為該表建立索引,因?yàn)樗饕矔?huì)降低更新表的速度,所以我們可以為數(shù)據(jù)記錄較多的表中,頻繁作為查詢條件的字段建立索引,而經(jīng)常增刪改的表或字段則不適合創(chuàng)建索引。

轉(zhuǎn)移壓力則要求我們?cè)诰帉懘a的時(shí)候,時(shí)刻留意代碼中是否過(guò)多的與數(shù)據(jù)庫(kù)進(jìn)行交互,這些交互是否可以減少或者甚至可以不交互,以其他方式就能夠達(dá)到相同的輸入輸出。

例如一個(gè)功能模塊的代碼寫下來(lái),發(fā)現(xiàn)多次調(diào)用了同一條數(shù)據(jù),就可以將數(shù)據(jù)存為參數(shù),供函數(shù)多次使用。


04?給數(shù)據(jù)庫(kù)請(qǐng)個(gè)保姆——中間件

能否合理利用中間件是考驗(yàn)一個(gè)開(kāi)發(fā)技術(shù)經(jīng)理的標(biāo)準(zhǔn)之一,合理利用各種中間件的優(yōu)勢(shì),可以有效提高產(chǎn)品性能。在數(shù)據(jù)讀取壓力大的場(chǎng)景中,往往會(huì)引入RedisMQ中間件


Redis緩存數(shù)據(jù)庫(kù)是將數(shù)據(jù)以鍵值對(duì)的形式緩存在內(nèi)存中的高效數(shù)據(jù)庫(kù)。

在開(kāi)發(fā)中,我們可以將一些頻繁讀取的數(shù)據(jù)放到Redis中,例如中簽公告、人員名單、產(chǎn)品清單等,用戶在訪問(wèn)這些數(shù)據(jù)的時(shí)候,如果發(fā)現(xiàn)緩存中有數(shù)據(jù),直接取用,不僅減輕了數(shù)據(jù)庫(kù)的壓力,讀取速度還特別快,因?yàn)閮?nèi)存的讀寫速率是普通機(jī)械硬盤的幾百倍。

MQ消息隊(duì)列中間件常用于流量消峰和消息分發(fā)。

利用MQ將同一時(shí)刻的大量請(qǐng)求分散成一段時(shí)間來(lái)處理,可以有效減輕數(shù)據(jù)庫(kù)負(fù)擔(dān);另外把消息發(fā)布到MQ中供多個(gè)服務(wù)監(jiān)聽(tīng),也能達(dá)到減少數(shù)據(jù)查詢的次數(shù)的效果。


05?忍法——數(shù)據(jù)庫(kù)分身術(shù)

上面幾種方法只是在應(yīng)用系統(tǒng)的軟實(shí)力上做文章,為數(shù)據(jù)庫(kù)減壓,但面對(duì)真正龐大的流量襲來(lái)時(shí),還是得下硬功夫——提升數(shù)據(jù)庫(kù)自身的讀寫性能。


縱向提高數(shù)據(jù)庫(kù)配置

加CPU、加內(nèi)存,性能提升也是有限的,幸運(yùn)的是,目前大部分?jǐn)?shù)據(jù)庫(kù)都支持分布式架構(gòu),或主從讀寫分離架構(gòu)。


分布式架構(gòu)

分布式架構(gòu)可以讓多個(gè)計(jì)算機(jī)系統(tǒng)設(shè)備共同組成一個(gè)數(shù)據(jù)庫(kù),提供完整的數(shù)據(jù)庫(kù)服務(wù),例如Oracle、MongoDB、TDSQL等,增加計(jì)算機(jī)系統(tǒng)的數(shù)量,就能提高數(shù)據(jù)庫(kù)性能,理論上可以無(wú)限提高,這也是天貓雙十一能承受幾十億并發(fā)壓力的秘訣之一。


主從讀寫分離架構(gòu)

是一個(gè)主數(shù)據(jù)庫(kù)用來(lái)寫入數(shù)據(jù),另外搭建幾個(gè)從數(shù)據(jù)庫(kù)用來(lái)讀取數(shù)據(jù),主數(shù)據(jù)庫(kù)會(huì)把數(shù)據(jù)同步到幾個(gè)從數(shù)據(jù)庫(kù)中,這樣就能將數(shù)據(jù)庫(kù)的讀取壓力分散到從數(shù)據(jù)庫(kù)中,從而實(shí)現(xiàn)數(shù)據(jù)庫(kù)的減壓。


06?總結(jié)

由于用戶體量較小,我們目前開(kāi)發(fā)的應(yīng)用還未在數(shù)據(jù)庫(kù)壓力上出現(xiàn)過(guò)問(wèn)題,但是經(jīng)過(guò)幾次壓力測(cè)試項(xiàng)目工作,能夠提前對(duì)大體量的業(yè)務(wù)應(yīng)用性能障礙有一定的了解。為避免出現(xiàn)業(yè)務(wù)數(shù)據(jù)庫(kù)壓力過(guò)大等問(wèn)題,筆者通過(guò)思考以及結(jié)合自身的技術(shù)經(jīng)驗(yàn),分享上述解決方法,供各位同行參考。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容