通過(guò)緩存+SQL修改優(yōu)雅地優(yōu)化慢查詢(xún)
問(wèn)題描述
單例數(shù)據(jù)庫(kù)模式中,后端高并發(fā)請(qǐng)求多(讀多寫(xiě)少),導(dǎo)致數(shù)據(jù)庫(kù)壓力過(guò)大,關(guān)鍵接口響應(yīng)變慢,嚴(yán)重影響體驗(yàn)。
需求
減少接口的響應(yīng)時(shí)間。
尋找解決方案
由于問(wèn)題主要處在數(shù)據(jù)庫(kù)壓力過(guò)大的情況,采用兩種優(yōu)化思路優(yōu)化查詢(xún)過(guò)程:
- 使用緩存分擔(dān)數(shù)據(jù)庫(kù)壓力
- 對(duì)查詢(xún)數(shù)據(jù)庫(kù)過(guò)程做優(yōu)化
緩存方案
更新策略
使用Redis,雖然可以很好地減少數(shù)據(jù)庫(kù)的壓力,但是同時(shí)在高并發(fā)的情況下,容易出現(xiàn)數(shù)據(jù)不一致的情況,尤其是在更新數(shù)據(jù)的時(shí)候。
最常見(jiàn)的導(dǎo)致不一致的原因是雙寫(xiě)操作,即高并發(fā)情況下短時(shí)間內(nèi)對(duì)數(shù)據(jù)庫(kù)進(jìn)行兩次寫(xiě)操作。為了最小程度地出現(xiàn)這種情況,緩存在更新策略上采用先更新數(shù)據(jù)庫(kù)后刪除緩存的方式。
對(duì)于雙寫(xiě)問(wèn)題,在最壞情況下,寫(xiě)請(qǐng)求A在更新數(shù)據(jù)庫(kù)后,被寫(xiě)請(qǐng)求B先一步更新數(shù)據(jù)庫(kù)+刪除緩存,然后A請(qǐng)求才刪除緩存,也不會(huì)導(dǎo)致后續(xù)請(qǐng)求讀取到錯(cuò)誤的值。
對(duì)于先寫(xiě)后讀,在最壞情況下,寫(xiě)請(qǐng)求A在更新數(shù)據(jù)庫(kù)后,被讀請(qǐng)求C先一步在緩存讀取到舊值,然后A請(qǐng)求才刪除緩存,也只會(huì)影響這段時(shí)間的讀請(qǐng)求,刪除后的讀請(qǐng)求不影響。
對(duì)比其他方案(先更新緩存后更新數(shù)據(jù)庫(kù)、先刪除緩存后更新數(shù)據(jù)庫(kù)、先更新數(shù)據(jù)庫(kù)后更新緩存)在最壞情況下會(huì)導(dǎo)致的錯(cuò)誤(更新數(shù)據(jù)庫(kù)失敗導(dǎo)致緩存是未知值、雙寫(xiě)后數(shù)據(jù)庫(kù)變成舊值、更新緩存失敗導(dǎo)致緩存保存舊值)要好得多。
但是先更新數(shù)據(jù)庫(kù)后刪除緩存也不是完全安全的,除了上文提到的高并發(fā)下先寫(xiě)后讀可能讀到舊值外,若刪除緩存失敗,也有可能導(dǎo)致讀到舊值。處理方法見(jiàn)下文。
緩存架構(gòu)
添加緩存,勢(shì)必要修改業(yè)務(wù)代碼,如何配置架構(gòu)才能把對(duì)代碼的入侵性講到最低,這里使用監(jiān)聽(tīng)數(shù)據(jù)庫(kù)binlog的方法,使用中間件監(jiān)聽(tīng)mysql的日志,當(dāng)出現(xiàn)操作時(shí),通知專(zhuān)門(mén)的模塊來(lái)修改緩存,做到修改緩存和業(yè)務(wù)邏輯解耦。
同時(shí)為了解決緩存刪除失敗的問(wèn)題,當(dāng)發(fā)生失敗時(shí),發(fā)送消息至消息隊(duì)列傳遞給專(zhuān)門(mén)的模塊進(jìn)行重試刪除。
中間件選擇:
- 緩存使用Redis
- 監(jiān)聽(tīng)binlog使用canal
- 消息隊(duì)列使用RocketMQ
架構(gòu)如下所示:
SQL優(yōu)化
查詢(xún)優(yōu)化可以從兩個(gè)方面進(jìn)行:
- 根據(jù)高頻的查詢(xún)case,遵循最左匹配原則,設(shè)置對(duì)應(yīng)的索引或聯(lián)合索引
- 通過(guò)了解業(yè)務(wù)場(chǎng)景,看看能否將一些小SQL合并成大SQL
通過(guò)本文的介紹,我們可以看到,優(yōu)化慢查詢(xún)并不一定需要對(duì)程序代碼進(jìn)行復(fù)雜的修改。通過(guò)巧妙地運(yùn)用緩存和SQL優(yōu)化手段,我們可以達(dá)到相同或者更好的效果。在實(shí)際的開(kāi)發(fā)中,我們應(yīng)該繼續(xù)探索和研究這些優(yōu)化方法,以提高程序的效率和穩(wěn)定性。
到此這篇關(guān)于通過(guò)緩存+SQL修改優(yōu)雅地優(yōu)化慢查詢(xún)的文章就介紹到這了,更多相關(guān)優(yōu)化慢查詢(xún)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- MySQL慢查詢(xún)優(yōu)化解決問(wèn)題
- 一個(gè) 20 秒 SQL 慢查詢(xún)優(yōu)化處理方案
- Mysql慢查詢(xún)優(yōu)化方法及優(yōu)化原則
- mysql慢查詢(xún)優(yōu)化之從理論和實(shí)踐說(shuō)明limit的優(yōu)點(diǎn)
- 通過(guò)MySQL慢查詢(xún)優(yōu)化MySQL性能的方法講解
- MySQL慢查詢(xún)優(yōu)化之慢查詢(xún)?nèi)罩痉治龅膶?shí)例教程
- 美團(tuán)網(wǎng)技術(shù)團(tuán)隊(duì)分享的MySQL索引及慢查詢(xún)優(yōu)化教程
相關(guān)文章
mysql隨機(jī)查詢(xún)10條數(shù)據(jù)的三種方法
本文主要介紹了mysql隨機(jī)查詢(xún)10條數(shù)據(jù)的三種方法,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-09-09mysql8.0 JSON_CONTAINS的使用說(shuō)明
這篇文章主要介紹了mysql8.0 JSON_CONTAINS的使用說(shuō)明,具有很好的參考價(jià)值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-075個(gè)MySQL GUI工具推薦,幫助你進(jìn)行數(shù)據(jù)庫(kù)管理
這篇文章主要介紹了5個(gè)MySQL GUI工具推薦,幫助大家更好的進(jìn)行MySQL數(shù)據(jù)庫(kù)管理,感興趣的朋友可以了解下2020-08-08如何將Excel文件導(dǎo)入MySQL數(shù)據(jù)庫(kù)
這篇文章主要為大家詳細(xì)介紹了Excel文件導(dǎo)入MySQL數(shù)據(jù)庫(kù)的具體方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-07-07MySQL 存儲(chǔ)過(guò)程和"Cursor"的使用方法
本文中介紹了一個(gè)MySQL的存儲(chǔ)過(guò)程,其中涉及Cursor的使用2008-12-12