緩沖池
存放表數(shù)據(jù)和索引數(shù)據(jù)沦辙,把磁盤上的數(shù)據(jù)加載到緩沖池司浪,避免每次訪問都進(jìn)行磁盤I/O消痛,加速訪問
緩沖池的數(shù)據(jù)管理
最常用的就是LRU算法且叁,redis、memcache秩伞、OS都會用逞带,但是MySQL不一樣
傳統(tǒng)的LRU算法
最常見的玩法是:有一個(gè)列表,新訪問的數(shù)據(jù)放在頭部纱新,空間不足時(shí)展氓,淘汰末尾元素。
例如:
假設(shè)我們訪問的數(shù)據(jù)脸爱,在編號為3的頁中:
編號3的頁在隊(duì)列中遇汞,移動到隊(duì)列頭,沒有頁被淘汰
接下來簿废,假設(shè)我們要訪問編號15的頁
因?yàn)榫幪枮?5的頁不在隊(duì)列中空入,在隊(duì)列頭插入,編號9的頁被淘汰
傳統(tǒng)的LRU簡單直觀族檬,為什么MySQL沒有直接使用呢歪赢?
因?yàn)椋琈ySQL有兩類操作會出現(xiàn)問題:
- 預(yù)讀
預(yù)讀是一種將多個(gè)頁讀取到緩沖池的I/O請求导梆,預(yù)測這些頁很快會被訪問轨淌。實(shí)際應(yīng)用中,這些頁可能并不會訪問 - 全表掃描
mysqldump或者全表查詢會導(dǎo)致加載大量數(shù)據(jù)看尼,大量的熱點(diǎn)數(shù)據(jù)被驅(qū)逐递鹉,導(dǎo)致性能急劇下降
該如何優(yōu)化呢?
- 讓非熱點(diǎn)數(shù)據(jù)頁停留時(shí)間盡可能短
- 讓真正需要的頁才移動到頭部
MySQL的中點(diǎn)插入LRU
針對預(yù)讀的問題藏斩,解決思路是:
- 將LRU列表分成兩部分躏结,新頁列表和舊頁列表
- 新頁列表尾部與舊頁列表頭部相連
- 新訪問的頁會在舊頁列表頭部插入
這樣,預(yù)讀的頁如果不被訪問狰域,就不會進(jìn)入新頁列表媳拴,并且很快老化而被驅(qū)逐
例如:
假設(shè)黄橘,我們通過預(yù)讀加載了編號37的頁:
編號為37的頁插入到舊頁列表頭部,同時(shí)淘汰了編號23的頁
接下來屈溉,假設(shè)我們讀操作需要訪問的數(shù)據(jù)在編號37的頁中:
編號為37的頁移動到新頁列表頭部塞关,編號為7的頁從新頁列表尾部移動到舊頁列表頭部
對于全表掃描,這些措施還不夠子巾,因?yàn)橐粋€(gè)數(shù)據(jù)也可能被連續(xù)訪問幾次帆赢,該怎么改進(jìn)呢?
MySQL增加停留時(shí)間窗機(jī)制线梗,即在時(shí)間T內(nèi)椰于,不論訪問多少次,都不會移動到新頁列表
上述算法仪搔,對應(yīng)哪些參數(shù)呢瘾婿?
-
innodb_old_blocks_pct
舊頁列表的比例,默認(rèn)是37烤咧,即占3/8偏陪。取值范圍是5~95,如果設(shè)置成95髓削,算法就近似于傳統(tǒng)的LRU -
innodb_old_blocks_time
舊頁列表停留時(shí)間竹挡,單位ms,默認(rèn)1000立膛。數(shù)據(jù)首次訪問并且停留時(shí)間超過配置揪罕,才能進(jìn)入新頁列表
變更緩沖
對于讀請求,緩沖區(qū)能夠減少I/O次數(shù)宝泵,從而提升性能好啰,那么對于寫請求呢?
對于寫請求存在兩種場景:
- 情況一:修改的頁恰好在緩沖區(qū)
- 直接修改頁儿奶,一次內(nèi)存操作
- 請求寫入重做日志框往,一次順序?qū)?/li>
- 情況二: 修改的數(shù)據(jù)還沒有加載到緩沖池
- 讀取磁盤,將索引數(shù)據(jù)加載到緩沖區(qū)闯捎,一次隨機(jī)讀
- 修改頁椰弊,一次內(nèi)存操作
- 請求寫入重做日志,一次順序?qū)?/li>
因此瓤鼻,如果沒有命中緩沖區(qū)秉版,那么會出現(xiàn)一次隨機(jī)I/O,對于寫多讀少的場景茬祷,是否還有優(yōu)化的空間呢清焕?
答案就是變更緩沖。
什么是變更緩沖呢?
變更緩沖區(qū)是緩沖池的一部分秸妥,存儲對未加載到緩沖池的輔助索引的修改滚停。等到數(shù)據(jù)被讀取時(shí),在將數(shù)據(jù)合并到緩沖池粥惧。如圖:
因此上述的第二種情況修改成:
- 數(shù)據(jù)寫入變更緩沖键畴,一次內(nèi)存操作
- 請求寫入重做日志,一次順序?qū)?/li>
雖然首次加載數(shù)據(jù)時(shí)影晓,會多一次內(nèi)存操作镰吵,即合并變更緩沖內(nèi)的變更記錄檩禾,但是相比于一次磁盤I/O挂签,開銷可以忽略不計(jì)
如何保證數(shù)據(jù)一致性?
- 變更緩沖不僅僅是內(nèi)存的一塊區(qū)域盼产,也會定期寫入系統(tǒng)表空間
- 在加載索引時(shí)饵婆,會有合并機(jī)制,保證緩沖池中的索引數(shù)據(jù)是最新的
配置參數(shù)
-
innodb_change_buffering
變更緩沖的開關(guān)戏售,默認(rèn)支持全部類型操作侨核。none、inserts灌灾、deletes搓译、changes、purges锋喜、all -
innodb_change_buffer_max_size
變更緩沖占緩沖池的百分比些己。默認(rèn)是25,最大50