傳統LRU連結串列 vs MySQL的LRU連結串列,孰優孰劣?
推薦閱讀:
一、簡述傳統的LRU連結串列
LRU:Least Recently Used
相信大家對LRU連結串列是不陌生的,它算是一種基礎的資料結構吧,而且想必面試時也被問到過什麼是LRU連結串列,甚至是讓你手寫一個LRU連結串列。
其實所謂的LRU連結串列本質上就是一個雙向迴圈連結串列,如下圖:
下面我們結合LRU連結串列和資料頁機制描述一下MySQL載入資料的機制:
我們將從磁碟中讀取的資料頁稱為young page,young page會被直接放在連結串列的頭部。已經存在於LRU連結串列中資料頁如果被使用到了,那麼該資料頁也被認為是young page而被移動到連結串列頭部。這樣連結串列尾部的資料就是最近最少使用的資料了,當Buffer Pool容量不足,或者後臺執行緒主動重新整理資料頁時,就會優先重新整理連結串列尾部的資料頁。
二、傳統LRU連結串列的不足
相信你之前肯定聽說過作業系統級別的空間區域性性原理:
spatial locality(空間區域性性):也就是說讀取一個資料,在它周圍記憶體地址儲存的資料也很有可能被讀取到,於是作業系統會幫你預讀一部分資料。
MySQL也是存在存在預讀機制的!
- 當Buffer Pool中儲存著一個區中13個連續的資料頁時,你再去這個區裡面讀取,MySQL就會將這個區裡面所有的資料頁都載入進Buffer Pool中的LRU連結串列中。(然後可能你根本不會使用這些被預讀的資料頁)
- 當你順序的訪問了一個區中大於
innndb_read_ahead_threshold=56
個資料頁時,MySQL會自動幫你將下一個相鄰區中的資料頁讀入LRU連結串列中。(這個機制預設是被關閉的) - 當你執行
select * from xxx;
時,如果表中的資料頁非常多,那這些資料頁就會一一將Buffer Pool中的經常使用的快取頁擠下去,可能留在LRU連結串列中的全部是你不經常使用的資料。
綜上你可以看到,所謂的預讀機制的優勢,實際上違背了LRU去實現將最近最少使用的資料頁刷入磁碟的設計初衷。
三、MySQL的LRU連結串列
接下來我們看下MySQL的Buffer Pool是如何定製LRU連結串列的,已經LRU幫InnoDB解決了什麼問題。
當業務進行大量的CRUD時,需要不斷的將資料頁讀取到buffer pool中的LRU連結串列中。
MySQL的LRU連結串列長下面這樣。
LRU連結串列被MidPoint分成了New Sublist和Old Sublist兩部分。
其中New Sublist大概佔比5/8,Old Sublist佔比3/8。
New Sublist儲存著young page,而Old Sublist儲存著Old Page。
我們可以通過如下的方式檢視MidPoint的預設值。
使用者可以根據自己的業務動態的調整這個引數!
這其實是一種冷熱資料分離設計思想。他相對於傳統的LRU連結串列有很大的優勢
四、MySQL定製LRU連結串列的優勢
而對於MySQLLRU連結串列來說,通過MidPoint將連結串列分成兩部分。
從磁碟中新讀出的資料會放在Old Sublist的頭部。這樣即使你真的使用select * from t;
也不會導致New Sublist中的經常被訪問的資料頁被刷入磁碟中。
正常情況下,訪問Old Sublist中的快取頁,那麼該快取頁會被提升到New Sublist中成為熱資料。
但是當你通過 select * from t
將一大批資料載入到Old Sublist時,然後在不到1s內你又訪問了它,那在這段時間內被訪問的快取頁並不會被提升為熱資料。 這個1s由引數innodb_old_blocks_time
控制。
另外:New SubList也是經過優化的,如果你訪問的是New SubList的前1/4的資料,他是不會被移動到LRU連結串列頭部去的。
相關文章
- 你知道MySQL的LRU連結串列嗎?MySql
- MySQL對決:MySQL與MariaDB孰優孰劣?MySql
- LRU快取-實現雜湊連結串列結合快取
- Angular 2對 React:究竟孰優孰劣?AngularReact
- 連結串列-雙向連結串列
- 連結串列-迴圈連結串列
- 連結串列面試題(二)---連結串列逆序(連結串列反轉)面試題
- 看動畫理解「連結串列」實現LRU快取淘汰演算法動畫快取演算法
- (連結串列)連結串列的排序問題排序
- 連結串列4: 迴圈連結串列
- 連結串列-單連結串列實現
- 連結串列入門與插入連結串列
- javascript中的連結串列結構—雙向連結串列JavaScript
- 連結串列
- ORACLE buffer cache 原理 --LRU連結串列(參照學習:oracle核心技術揭秘)Oracle
- 連結串列以及golang介入式連結串列的實現Golang
- Linux核心連結串列-通用連結串列的實現Linux
- 資料結構系列之單連結串列實現一個簡單的LRU演算法資料結構演算法
- 反轉連結串列、合併連結串列、樹的子結構
- Leetcode_86_分割連結串列_連結串列LeetCode
- 【LeetCode】->連結串列->通向連結串列自由之路LeetCode
- 孰優孰劣:行業中一對一視訊直播的主要特徵定位行業特徵
- php連結串列PHP
- 連結串列操作
- 連結串列逆序
- 2、連結串列
- 連結串列專題——面試中常見的連結串列問題面試
- 【圖解連結串列類面試題】移除連結串列元素圖解面試題
- 【圖解連結串列類面試題】環形連結串列圖解面試題
- 資料結構-單連結串列、雙連結串列資料結構
- 資料結構與演算法——連結串列 Linked List(單連結串列、雙向連結串列、單向環形連結串列-Josephu 問題)資料結構演算法
- 資料結構實驗之連結串列三:連結串列的逆置資料結構
- 資料結構實驗之連結串列五:單連結串列的拆分資料結構
- 資料結構實驗之連結串列六:有序連結串列的建立資料結構
- 資料結構之連結串列篇(單連結串列的常見操作)資料結構
- 【LeetCode-連結串列】面試題-反轉連結串列LeetCode面試題
- LeetCode-Python-86. 分隔連結串列(連結串列)LeetCodePython
- 連結串列面試題(七)---合併兩個有序連結串列面試題