mysql快取機制 讀快取篇

2021-09-29 21:52:47 字數 2377 閱讀 3443

最近進行了一系列mysql相關的研究,了解了一遍mysql的快取機制,在這裡集中總結一下。

本文是基於mysql-innodb的快取機制解析

快取機制是一種常用的機制,在作業系統中,因為不同儲存介質的讀寫效率天差地別,所以採取快取機制來加快系統的讀寫效率,將一些常用的資料放在讀寫效率較高的快取裡,避免每次讀寫都直接對磁碟進行操作

作為專門儲存資料的mysql系統,也有他自己的快取策略,對於mysql這樣的資料庫,磁碟io通常是它的最大瓶頸,mysql做了讀快取和寫快取這兩個機制來有效減少磁碟io,提高資料庫的執行效率

這裡來解析一下innodb的緩衝池機制

緩衝池有什麼作用?

最終目的是為了加速訪問,將磁碟上的資料載入到緩衝池(也就是記憶體)當中,由於系統訪問記憶體比訪問磁碟要快速很多倍,所以當一條資料庫請求抵達的時候,若是能夠在快取中命中,就不需要去訪問磁碟讀取資料,當資料庫請求很頻繁很密集的時候,這種快取策略能夠極大地增強資料庫的響應速度,從而更高效地承載業務

緩衝池有什麼侷限?

緩衝池因為是建立在記憶體當中的,所以並不可以非常大,讀取速度快的代價是容量小,比如一台計算機的磁碟可以有500g,但是記憶體可能只有8個g。它只能將資料庫的一部分表資料和索引資料快取起來,並不能將所有資料都載入到快取裡,所以需要合理分配快取,使盡量多的資料庫請求能夠在緩衝池當中得到命中,從而最大限度地降低磁碟io

innodb的緩衝池如何保證緩衝命中率的?

因為我所從事的遊戲行業,資料的讀取遠遠大於資料的寫入,所以這裡先從讀快取介紹起

1.mysql中的資料並不是你想讀哪一條就直接去磁碟裡讀取單單一條的資訊,而是整頁讀取的,一次讀取一頁的資料(具體大小可以由引數控制,一般是4k),當某條sql請求涉及到某一頁的某一條資料時,整乙個資料頁都會從磁碟被載入到快取裡,後續的請求如果存在於這個頁內,那麼就不需要訪問磁碟了

2.為何是按頁讀取?因為大部分的mysql讀取操作都是遵循「區域性性原理」的,也就是當某一條資料被系統請求了,那麼與其相鄰的資料在不久的未來也有很大的概率會被請求,利用這種「區域性性原理」可以十分有效地提公升資料庫請求的快取命中率

3.那麼快取頁的置換淘汰規則是怎麼樣的呢?記憶體有限,隨著sql請求的增加,快取池總會被填滿,那麼新的頁想要載入加來,就必然會置換掉已有的列。

a.通常容易想到的方法就是lru演算法:用佇列管理快取頁,若快取不命中,則從磁碟上載入乙個資料頁進來,放置在佇列頭,將佇列末尾的資料頁淘汰掉,若快取命中,則將該頁資料移動到佇列頭,不進行淘汰

b.但是lru演算法也有它的侷限性,因為資料庫有預讀機制,還有一些批量掃瞄資料的操作,預讀操作會將一些資料頁載入到記憶體中,但是並不會使用它,導致沒有被使用的資料頁平白被放置在了佇列頭,占用了緩衝池的空間,而批量掃瞄的操作會大量地將資料頁載入進來,如果用單純的lru演算法,一次大量掃瞄的操作,就會將緩衝池內的全部資料頁都置換一遍

c.解決預讀失效的問題:將緩衝池分成新生代老生代,新生代的末尾連線老生代的頭部,被預讀的頁被讀入快取時,只放在老生代的頭部,只有資料真正被讀取了,該頁才會從老生代的頭部被移動到新生代的頭部,如果沒有被讀取,那麼因為老生代在新生代的後面,所以會更快地被淘汰出快取

d.新生代和老生代的長度佔比是可以通過mysql引數調節的

e.解決資料批量掃瞄的問題:大量熱資料被刷出緩衝,造成緩衝汙染。這裡可以在上面的新生代與老生代基礎上做進一步的細化優化,提出乙個老生代視窗期的機制,預讀的資料頁,即使在老生代中被真正訪問,也不會立即插入到新生代的頭部,只有在滿足「被訪問」and「在老生代停留時間大於t」的情況下,才會被放入新生代的頭部,於是,在批量掃瞄的時候,只會有大量的資料頁被置入到老生代當中,如果這些資料頁只被訪問一次,那麼它們將會很快被淘汰出緩衝池

f.總而言之,可以總結為乙個策略:提高新生代緩衝池的准入門檻,確保只有真正的「熱資料」才會被置入進來,將一些「有可能熱的資料」放在老生代里按照某種策略觀察,可以理解為,新生代的快取是關乎資料庫效能的極其重要的資料,不能隨意被某些操作汙染

g.相關引數:

innodb_buffer_pool_size:緩衝池大小,在記憶體足夠的情況下,往往會選擇調大這個引數,緩衝池越大,資料庫訪問的快取命中率也就會越高,資料庫效能也會越好

innodb_old_blocks_pct:老生代佔整個緩衝池鍊錶的長度比例,預設是63:37,老生代37

innodb_old_blocks_time:老生代停留視窗時間,老生代中的資料頁只有在被讀取,並在老生代中存在超過這個引數指明的時間後,才會被置入到新生代的頭部

mysql寫快取 mysql快取機制 寫快取篇

前一篇的部落格對innodb的讀快取做了解讀。那麼innodb是否只有對讀取做了優化呢?對於我所從事的網路遊戲業務而言,的確是乙個讀多寫少的場景,但是並不意味著所有場景都是如此。首先的一點,資料庫需要保證安全性,所以每一次寫入資料庫的時候,都會產生redo log,用來在資料庫崩潰的時候進行回滾,同...

mysql 快取 mysql 快取機制解讀

首先講解一下,快取的原理 快取存在乙個hash表中,通過查詢sql,查詢資料庫,客戶端協議等作為key,在判斷命中前,命中條件 1 mysql不會解析sql,而是使用sql去查詢快取,2 sql上的任何字元的不同,如空格,注釋,都會導致快取不命中。3 如果查詢有不確定的資料like now curr...

mysql 快取機制

mysql快取機制就是快取sql 文字及快取結果,用kv形式儲存再伺服器記憶體中,如果執行相同的sql,伺服器直接從快取中去獲取結果,不需要在再去解析 優化 執行sql。如果這個表修改了,那麼使用這個表中的所有快取將不再有效,查詢快取值得相關條目將被清空。表中得任何改變是值表中任何資料或者是結構的改...