當(dāng)前位置:首頁 > 公眾號精選 > 架構(gòu)師社區(qū)
[導(dǎo)讀]今天來聊一聊 Mysql 緩存池原理。

今天來聊一聊 Mysql 緩存池原理。

提綱附上,話不多說,直接干貨。

面試官:能說一說Mysql緩存池嗎?

前言

面試官:同學(xué),你能說說Mysql 緩存池嗎?

狂聊君:啊,這么難嗎,容我組織一下語言。(內(nèi)心OS:這TM還不簡單?我能給你扯半小時!

面試官:可以,給你一分鐘時間想一想吧。

....一分鐘后....

狂聊君:我準備好了,你可聽好,我要開始表演了。

為什么要有緩存池?

Mysql 的 innodb 存儲引擎是基于磁盤存儲的,并且是按照頁的方式進行管理的。

在數(shù)據(jù)庫系統(tǒng)中,CPU 速度與磁盤速度之間的差距是非常大的,為了最大可能的彌補之間的差距,提出了緩存池的概念。

所以緩存池,簡單來說就是一塊「內(nèi)存區(qū)域」,通過內(nèi)存的速度來彌補磁盤速度較慢,導(dǎo)致對數(shù)據(jù)庫造成性能的影響。

緩存池的基本原理

「讀操作」:

在數(shù)據(jù)庫中進行讀取頁的操作,首先把從磁盤讀到的頁存放在緩存池中,下一次讀取相同的頁時,首先判斷該頁是不是在緩存池中。

若在,稱該頁在緩存池中被命中,則直接讀取該頁,否則,還是去讀取磁盤上的頁。

「寫操作」:

對于數(shù)據(jù)庫中頁的修改操作,首先修改在緩存池中的頁,然后在以一定的頻率刷新到磁盤,并不是每次頁發(fā)生改變就刷新回磁盤,而是通過 checkpoint 的機制把頁刷新回磁盤。

可以看到,無論是讀操作還是寫操縱,都是對緩存池進行操作,而不是直接對磁盤進行操縱。

緩存池結(jié)構(gòu)

Buffer Pool 是一片連續(xù)的內(nèi)存空間,innodb 存儲引擎是通過頁的方式對這塊內(nèi)存進行管理的。

緩存池的結(jié)構(gòu)如下圖:

面試官:能說一說Mysql緩存池嗎?

可以看到緩存池中包括數(shù)據(jù)頁、索引頁、插入緩存、自適應(yīng)哈希索引、鎖信息、數(shù)據(jù)字段。

其中數(shù)據(jù)頁和索引頁會用掉多數(shù)內(nèi)存。

「但是,innodb 是如何管理緩存池中的這么多頁呢?」

為了更好的管理這些緩存的頁,innodb 為每一個緩存頁都創(chuàng)建了一些所謂的控制信息,這些控制信息包括該頁所屬的:

  • 表空間編號(sapce id)
  • 頁號(page numeber)
  • 頁在 buffer Pool 的地址
  • 一些鎖信息以及 LSN 信息日志序列號
  • 其他控制信息

每個緩存頁對應(yīng)的控制信息占用的內(nèi)存大小是相同的,我們把每個頁對應(yīng)的控制信息占用的一塊內(nèi)存稱為一個「控制塊」。

「控制塊」和緩存頁是一一對應(yīng)的,它們都被存放到 Buffer Pool 中,其中控制塊被存放到 Buffer Pool 的前邊,緩存頁被存放到 Buffer Pool 的后邊。

Buffer Pool 對應(yīng)的內(nèi)存空間示意圖:

面試官:能說一說Mysql緩存池嗎?

緩存池參數(shù)設(shè)置

  • innodb_buffer_pool_size:緩存池的大小最多應(yīng)設(shè)置為物理內(nèi)存的 80%
  • innodb_buffer_pool_instance:設(shè)置有多少個緩存池,通常建議把緩存池個數(shù)設(shè)置為 CPU 的個數(shù),多個緩存池可以減少數(shù)據(jù)庫內(nèi)部的資源競爭,增加數(shù)據(jù)庫并發(fā)訪問的能力
  • innodb_old_blocks_pct:老生代占整個 LRU 的鏈長比例,默認是 3:7
  • innodb_old_blocks_time:老生代停留時間窗口,單位是毫秒,默認是 1000,即同時滿足“被訪問”與“在老生代停留時間超過 1 秒”兩個條件,才會被插入到新生代頭部

緩存池管理

「管理緩存池依賴的鏈表結(jié)構(gòu)」:

Free 鏈表

當(dāng)啟動 Mysql 服務(wù)器的時候,需要完成對 Buffer Pool 的初始化過程,即分配 Buffer Pool 的內(nèi)存空間,把它劃分為若干對控制塊和緩存頁,但是此時并沒有真正的磁盤頁被緩存到 Buffer Pool 中,之后隨著程序的運行,會不斷的有磁盤上的頁被緩存到 Buffer Pool 中。

在使用過程中,為了記錄哪些緩存頁是可用的,我們把所有空閑的頁包裝成一個節(jié)點組成一個鏈表,這個鏈表可以稱作為 Free 鏈表(空閑鏈表)。因為剛剛完成初始化的 Buffer Pool 中所有的緩存頁都是空閑的,所以每一個緩存頁都會被加入到 Free 鏈表中。

為了方便管理 Free 鏈表,特意為這個鏈表定義了一些「控制信息」,里面包含鏈表的頭節(jié)點地址,尾節(jié)點地址,以及當(dāng)前鏈表中節(jié)點的數(shù)量等信息。

另外會在每個 Free 鏈表的節(jié)點中都記錄了某個「緩存頁控制塊」的地址,而每個「緩存頁控制塊」都記錄著對應(yīng)的「緩存頁地址」,所以相當(dāng)于每個 Free 鏈表節(jié)點都對應(yīng)一個空閑的緩存頁。

給大家畫了個結(jié)構(gòu)圖:

面試官:能說一說Mysql緩存池嗎?

這圖怎么樣,這下能看的懂了吧!

2、Lru 鏈表

Lru 鏈表用來管理已經(jīng)讀取的頁,當(dāng)數(shù)據(jù)庫剛啟動時,Lru 鏈表是空的,此時頁也都放在 Free 列表中,當(dāng)需要讀取數(shù)據(jù)時,會從 Free 鏈表中申請一個頁,把從放入到磁盤讀取的數(shù)據(jù)放入到申請的頁中,這個頁的集合叫做 Lru 鏈表。

3、Flush 鏈表

Flush 鏈表用來管理被修改的頁,Buffer Pool 中被修改的頁也被稱之為「臟頁」,臟頁既存在于 Lru 鏈表中,也存在于 Flush 鏈表中,F(xiàn)lush 鏈表中存的是一個指向 Lru 鏈表中具體數(shù)據(jù)的指針。

因此只有 Lru 鏈表中的頁第一次被修改時,對應(yīng)的指針才會存入到 Flush 中,若之后再修改這個頁,則是直接更新 Lru 鏈表中的頁對應(yīng)的數(shù)據(jù)。

這三者之間是這么個關(guān)系:

面試官:能說一說Mysql緩存池嗎?

讀操作

Buffer Pool 一個最主要的功能是「加速讀」。加速讀是當(dāng)需要訪問一個數(shù)據(jù)頁面的時候,如果這個頁面已經(jīng)在緩存池中,那么就不再需要訪問磁盤,直接從緩沖池中就能獲取這個頁面的內(nèi)容。當(dāng)我們需要訪問某個頁中的數(shù)據(jù)時,就會把該頁加載到 Buffer Pool 中,如果該頁已經(jīng)在 Buffer Pool 中的話直接使用就可以了。

問題:那么如何快速查找在 Buffer Pool 中的頁呢?

為了避免查詢數(shù)據(jù)頁時掃描 Lru,其實是根據(jù)表空間號 + 頁號來定位一個頁的,也就相當(dāng)于表空間號 + 頁號是一個 key,緩存頁就是對應(yīng)的 value。用表空間號 + 頁號作為 key,緩存頁作為 value 創(chuàng)建一個哈希表,在需要訪問某個頁的數(shù)據(jù)時,先從哈希表中根據(jù)表空間號 + 頁號看看有沒有對應(yīng)的緩存頁。

如果有,直接使用該緩存頁就好。

如果沒有,那就從 Free 鏈表中選一個空閑的緩存頁,然后把磁盤中對應(yīng)的頁加載到該緩存頁的位置。每當(dāng)需要從磁盤中加載一個頁到 Buffer Pool 中時,就從 Free 鏈表中取一個空閑的緩存頁,并且把該緩存頁對應(yīng)的控制塊的信息填上,然后把該緩存頁對應(yīng)的 Free 鏈表節(jié)點從鏈表中移除,表示該緩存頁已經(jīng)被使用了,并且把該頁寫入 Lru 鏈表。

在初始化的時候,Buffer pool 中所有的頁都是空閑頁,需要讀數(shù)據(jù)時,就會從 Free 鏈表中申請頁,但是物理內(nèi)存不可能無限增大,數(shù)據(jù)庫的數(shù)據(jù)卻是在不停增大的,所以 Free 鏈表的頁是會用完的。

因此需要考慮把已經(jīng)緩存的頁從 Buffer pool 中刪除一部分,進而需要考慮如何刪除及刪除哪些已經(jīng)緩存的頁。假設(shè)一共訪問了 n 次頁,那么被訪問的頁在緩存中的次數(shù)除以 n 就是緩存命中率,緩存命中率越高,和磁盤的 IO 交互也就越少 。

為了提高緩存命中率,InnoDB 在傳統(tǒng) Lru 算法的基礎(chǔ)上做了優(yōu)化,解決了兩個問題:1、預(yù)讀失效 2、緩存池污染

寫操作

Buffer pool 另一個主要的功能是「加速寫」,即當(dāng)需要修改一個頁面的時候,先將這個頁面在緩沖池中進行修改,記下相關(guān)的重做日志,這個頁面的修改就算已經(jīng)完成了。

被修改的頁面真正刷新到磁盤,這個是后臺刷新線程來完成的。前面頁面更新是在緩存池中先進行的,那它就和磁盤上的頁不一致了,這樣的緩存頁被稱為臟頁(dirty page)。

問題:這些被修改的頁面什么時候刷新到磁盤?以什么樣的順序刷新到磁盤?

最簡單的做法就是每發(fā)生一次修改就立即同步到磁盤上對應(yīng)的頁上,但是頻繁的往磁盤中寫數(shù)據(jù)會嚴重的影響程序的性能。所以每次修改緩存頁后,不能立即把修改同步到磁盤上,而是在未來的某個時間點進行同步,由后臺刷新線程依次刷新到磁盤,實現(xiàn)修改落地到磁盤。

但是如果不立即同步到磁盤的話,那之后再同步的時候如何判斷 Buffer Pool 中哪些頁是臟頁,哪些頁從來沒被修改過呢?

InnoDB 并沒有一次性把所有的緩存頁都同步到磁盤上,InnoDB 創(chuàng)建一個存儲臟頁的鏈表,凡是在 Lru 鏈表中被修改過的頁都需要加入這個鏈表中,因為這個鏈表中的頁都是需要被刷新到磁盤上的,所以這個鏈表也叫 Flush 鏈表,鏈表的構(gòu)造和 Free 鏈表一致。

這里的臟頁修改指的此頁被加載進 Buffer Pool 后第一次被修改,只有第一次被修改時才需要加入 Flush 鏈表,對于已經(jīng)存在在 Flush 鏈表中的頁,如果這個頁被再次修改就不會再放到 Flush 鏈表。

需要注意,臟頁數(shù)據(jù)實際還在 Lru 鏈表中,而 Flush 鏈表中的臟頁記錄只是通過指針指向 Lru 鏈表中的臟頁。并且在 Flush 鏈表中的臟頁是根據(jù) oldest_lsn(這個值表示這個頁第一次被更改時的 lsn 號,對應(yīng)值 oldest_modification,每個頁頭部記錄)進行排序刷新到磁盤的,值越小表示要最先被刷新,避免數(shù)據(jù)不一致。

免責(zé)聲明:本文內(nèi)容由21ic獲得授權(quán)后發(fā)布,版權(quán)歸原作者所有,本平臺僅提供信息存儲服務(wù)。文章僅代表作者個人觀點,不代表本平臺立場,如有問題,請聯(lián)系我們,謝謝!

本站聲明: 本文章由作者或相關(guān)機構(gòu)授權(quán)發(fā)布,目的在于傳遞更多信息,并不代表本站贊同其觀點,本站亦不保證或承諾內(nèi)容真實性等。需要轉(zhuǎn)載請聯(lián)系該專欄作者,如若文章內(nèi)容侵犯您的權(quán)益,請及時聯(lián)系本站刪除。
換一批
延伸閱讀

9月2日消息,不造車的華為或?qū)⒋呱龈蟮莫毥谦F公司,隨著阿維塔和賽力斯的入局,華為引望愈發(fā)顯得引人矚目。

關(guān)鍵字: 阿維塔 塞力斯 華為

加利福尼亞州圣克拉拉縣2024年8月30日 /美通社/ -- 數(shù)字化轉(zhuǎn)型技術(shù)解決方案公司Trianz今天宣布,該公司與Amazon Web Services (AWS)簽訂了...

關(guān)鍵字: AWS AN BSP 數(shù)字化

倫敦2024年8月29日 /美通社/ -- 英國汽車技術(shù)公司SODA.Auto推出其旗艦產(chǎn)品SODA V,這是全球首款涵蓋汽車工程師從創(chuàng)意到認證的所有需求的工具,可用于創(chuàng)建軟件定義汽車。 SODA V工具的開發(fā)耗時1.5...

關(guān)鍵字: 汽車 人工智能 智能驅(qū)動 BSP

北京2024年8月28日 /美通社/ -- 越來越多用戶希望企業(yè)業(yè)務(wù)能7×24不間斷運行,同時企業(yè)卻面臨越來越多業(yè)務(wù)中斷的風(fēng)險,如企業(yè)系統(tǒng)復(fù)雜性的增加,頻繁的功能更新和發(fā)布等。如何確保業(yè)務(wù)連續(xù)性,提升韌性,成...

關(guān)鍵字: 亞馬遜 解密 控制平面 BSP

8月30日消息,據(jù)媒體報道,騰訊和網(wǎng)易近期正在縮減他們對日本游戲市場的投資。

關(guān)鍵字: 騰訊 編碼器 CPU

8月28日消息,今天上午,2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會開幕式在貴陽舉行,華為董事、質(zhì)量流程IT總裁陶景文發(fā)表了演講。

關(guān)鍵字: 華為 12nm EDA 半導(dǎo)體

8月28日消息,在2024中國國際大數(shù)據(jù)產(chǎn)業(yè)博覽會上,華為常務(wù)董事、華為云CEO張平安發(fā)表演講稱,數(shù)字世界的話語權(quán)最終是由生態(tài)的繁榮決定的。

關(guān)鍵字: 華為 12nm 手機 衛(wèi)星通信

要點: 有效應(yīng)對環(huán)境變化,經(jīng)營業(yè)績穩(wěn)中有升 落實提質(zhì)增效舉措,毛利潤率延續(xù)升勢 戰(zhàn)略布局成效顯著,戰(zhàn)新業(yè)務(wù)引領(lǐng)增長 以科技創(chuàng)新為引領(lǐng),提升企業(yè)核心競爭力 堅持高質(zhì)量發(fā)展策略,塑強核心競爭優(yōu)勢...

關(guān)鍵字: 通信 BSP 電信運營商 數(shù)字經(jīng)濟

北京2024年8月27日 /美通社/ -- 8月21日,由中央廣播電視總臺與中國電影電視技術(shù)學(xué)會聯(lián)合牽頭組建的NVI技術(shù)創(chuàng)新聯(lián)盟在BIRTV2024超高清全產(chǎn)業(yè)鏈發(fā)展研討會上宣布正式成立。 活動現(xiàn)場 NVI技術(shù)創(chuàng)新聯(lián)...

關(guān)鍵字: VI 傳輸協(xié)議 音頻 BSP

北京2024年8月27日 /美通社/ -- 在8月23日舉辦的2024年長三角生態(tài)綠色一體化發(fā)展示范區(qū)聯(lián)合招商會上,軟通動力信息技術(shù)(集團)股份有限公司(以下簡稱"軟通動力")與長三角投資(上海)有限...

關(guān)鍵字: BSP 信息技術(shù)
關(guān)閉
關(guān)閉