每當我們想要緩解讀,一般會想到什麼?
預讀取,快取
快取
快取,其實就是將高頻訪問的資料放到記憶體裡面,減少讀盤的次數。
為了提高記憶體的利用率,MySQL還建立了快取池,也就是buffer pool,儲存最熱的資料頁和索引頁。
預讀取(read-ahead)
從Linux的檔案系統我們就知道,計算機的讀取是按頁來的。那麼,我們是不是可以將下一頁提前取出來,反正是一次磁碟IO。
LRU(Least recently used)
提到快取和預讀取,LRU是跑不了的,簡單地說,就是將池子裡面待的最久的記憶體淘汰掉,放入新的資料。
- 裡面是個連結串列結構,首部新增,尾部淘汰。
- 訪問的時候,如果在池子裡,就移動到首部,如果不在,就放到首部並把尾部淘汰。
那麼,缺點有沒有?
預讀失效:你放了我不讀。不就浪費了記憶體麼。
優化
凡是要區別對待,就將他們隔離開來。
我們想要的就是真正讀取的資料快取起來,預讀的資料級別低一點,稍微快取一下就好了。
那麼,很簡單,把記憶體池分段,一段存真正讀的,一段存預讀的。
這就是新生代(new sublist)和老生代(old sublist),新的尾就是老的頭。
邏輯不變,但是可以配置長度,比如新的站70%,老的佔30%,老的由於比較短,就會更快淘汰。
那麼, 完美了麼?
快取池汙染:如果SQL需要掃描大量的行,則可能將所有資料替換出去,這樣就等於快取直接失效了。
優化2.0
凡是要防止區別對待的事務強行混合,就新增閾值,讓低一級的過不來。
將所有的資料都先丟到老的裡面,停留時間大於T,才能進入新生代,這樣老的就在不斷被重新整理,而真正需要的會逐漸進入新生代。
相關引數
- 快取池大小
- 老生代比例
- 老生代停留時間
結語
- 如果有不對的地方歡迎指正。
- 如果有不理解的地方歡迎指出我來加栗子。
- 如果感覺OK可以點贊讓更多人看到它。