電動自行車在城市生活中扮演著重要的角色,但佩戴頭盔對于保護頭部安全
09月01日 07:39
面試中的兩個問題:
操作系統(tǒng)在讀磁盤的時候會額外多讀一些數(shù)據(jù)到內(nèi)存中,最后也沒有用到,如何改善?
批量讀取數(shù)據(jù)的時候,可能會熱點數(shù)據(jù)擠出去,如何改善?
(相關(guān)資料圖)
Linux 和 MySQL 的緩存Linux 操作系統(tǒng)的緩存在應(yīng)用程序讀取文件的數(shù)據(jù)的時候,Linux 操作系統(tǒng)是會對讀取的文件數(shù)據(jù)進行緩存的,會緩存在文件系統(tǒng)中的Page Cache(如下圖中的頁緩存)。
Page Cache 屬于內(nèi)存空間里的數(shù)據(jù),由于內(nèi)存訪問比磁盤訪問快很多,在下一次訪問相同的數(shù)據(jù)就不需要通過磁盤 I/O 了,命中緩存就直接返回數(shù)據(jù)即可。
因此,Page Cache 起到了加速訪問數(shù)據(jù)的作用。
MySQL 的緩存MySQL 的數(shù)據(jù)是存儲在磁盤里的,為了提升數(shù)據(jù)庫的讀寫性能,Innodb 存儲引擎設(shè)計了一個緩沖池(Buffer Pool),Buffer Pool 屬于內(nèi)存空間里的數(shù)據(jù)。
有了緩沖池后:
當(dāng)讀取數(shù)據(jù)時,如果數(shù)據(jù)存在于 Buffer Pool 中,客戶端就會直接讀取 Buffer Pool 中的數(shù)據(jù),否則再去磁盤中讀取。當(dāng)修改數(shù)據(jù)時,首先是修改 Buffer Pool 中數(shù)據(jù)所在的頁,然后將其頁設(shè)置為臟頁,最后由后臺線程將臟頁寫入到磁盤。傳統(tǒng) LRU 是如何管理內(nèi)存數(shù)據(jù)的?Linux 的 Page Cache 和 MySQL 的 Buffer Pool 的大小是有限的,并不能無限的緩存數(shù)據(jù),對于一些頻繁訪問的數(shù)據(jù)我們希望可以一直留在內(nèi)存中,而一些很少訪問的數(shù)據(jù)希望可以在某些時機可以淘汰掉,從而保證內(nèi)存不會因為滿了而導(dǎo)致無法再緩存新的數(shù)據(jù),同時還能保證常用數(shù)據(jù)留在內(nèi)存中。
要實現(xiàn)這個,最容易想到的就是 LRU(Least recently used)算法。
LRU 算法一般是用「鏈表」作為數(shù)據(jù)結(jié)構(gòu)來實現(xiàn)的,鏈表頭部的數(shù)據(jù)是最近使用的,而鏈表末尾的數(shù)據(jù)是最久沒被使用的。那么,當(dāng)空間不夠了,就淘汰最久沒被使用的節(jié)點,也就是鏈表末尾的數(shù)據(jù),從而騰出內(nèi)存空間。
因為 Linux 的 Page Cache 和 MySQL 的 Buffer Pool 緩存的基本數(shù)據(jù)單位都是頁(Page)單位,所以后續(xù)以「頁」名稱代替「數(shù)據(jù)」。
傳統(tǒng)的 LRU 算法的實現(xiàn)思路是這樣的:
當(dāng)訪問的頁在內(nèi)存里,就直接把該頁對應(yīng)的 LRU 鏈表節(jié)點移動到鏈表的頭部。當(dāng)訪問的頁不在內(nèi)存里,除了要把該頁放入到 LRU 鏈表的頭部,還要淘汰 LRU 鏈表末尾的頁。存在的問題:
如果一條數(shù)據(jù)僅僅是突然被訪問(有可能后續(xù)將不再訪問),在 LRU 算法下,此數(shù)據(jù)將被定義為熱數(shù)據(jù),最晚被淘汰。但實際生產(chǎn)環(huán)境下,我們很多時候需要計算的是一段時間下key的訪問頻率,淘汰此時間段內(nèi)的冷數(shù)據(jù)。
預(yù)讀失效,怎么辦?什么是預(yù)讀機制?Linux 操作系統(tǒng)為基于 Page Cache 的讀緩存機制提供預(yù)讀機制,一個例子是:
應(yīng)用程序只想讀取磁盤上文件 A 的 offset 為 0-3KB 范圍內(nèi)的數(shù)據(jù),由于磁盤的基本讀寫單位為 block(4KB),于是操作系統(tǒng)至少會讀 0-4KB 的內(nèi)容,這恰好可以在一個 page 中裝下。但是操作系統(tǒng)出于空間局部性原理(靠近當(dāng)前被訪問數(shù)據(jù)的數(shù)據(jù),在未來很大概率會被訪問到),會選擇將磁盤塊 offset [4KB,8KB)、[8KB,12KB) 以及 [12KB,16KB) 都加載到內(nèi)存,于是額外在內(nèi)存中申請了 3 個 page;下圖代表了操作系統(tǒng)的預(yù)讀機制:
上圖中,應(yīng)用程序利用 read 系統(tǒng)調(diào)動讀取 4KB 數(shù)據(jù),實際上內(nèi)核使用預(yù)讀機制(ReadaHead) 機制完成了 16KB 數(shù)據(jù)的讀取,也就是通過一次磁盤順序讀將多個 Page 數(shù)據(jù)裝入 Page Cache。
這樣下次讀取 4KB 數(shù)據(jù)后面的數(shù)據(jù)的時候,就不用從磁盤讀取了,直接在 Page Cache 即可命中數(shù)據(jù)。因此,預(yù)讀機制帶來的好處就是減少了 磁盤 I/O 次數(shù),提高系統(tǒng)磁盤 I/O 吞吐量。
MySQL Innodb 存儲引擎的 Buffer Pool 也有類似的預(yù)讀機制,MySQL 從磁盤加載頁時,會提前把它相鄰的頁一并加載進來,目的是為了減少磁盤 IO。
預(yù)讀失效會帶來什么問題?如果這些被提前加載進來的頁,并沒有被訪問,相當(dāng)于這個預(yù)讀工作是白做了,這個就是預(yù)讀失效。
如果把「預(yù)讀頁」放到了 LRU 鏈表頭部,而當(dāng)內(nèi)存空間不夠的時候,還需要把末尾的頁淘汰掉。而末尾淘汰的頁,可能是熱點數(shù)據(jù),這樣就大大降低了緩存命中率。
如何避免預(yù)讀失效造成的影響?我們不能因為害怕預(yù)讀失效,而將預(yù)讀機制去掉,大部分情況下,空間局部性原理還是成立的。要避免預(yù)讀失效帶來影響,可以從兩個方面考慮
讓預(yù)讀頁停留在內(nèi)存里的時間要盡可能的短,讓真正被訪問的頁移動到 LRU 鏈表的頭部,從而保證熱數(shù)據(jù)留在內(nèi)存里的時間盡可能長。那到底怎么才能避免呢?
Linux 操作系統(tǒng)和 MySQL Innodb 通過改進傳統(tǒng) LRU 鏈表來避免預(yù)讀失效帶來的影響,具體的改進分別如下:
Linux 操作系統(tǒng)實現(xiàn)兩個了 LRU 鏈表:活躍 LRU 鏈表(active_list)和非活躍 LRU 鏈表(inactive_list);MySQL 的 Innodb 存儲引擎是在一個 LRU 鏈表上劃分來 2 個區(qū)域:young 區(qū)域 和 old 區(qū)域。這兩個改進方式,設(shè)計思想都是類似的,都是將數(shù)據(jù)分為了冷數(shù)據(jù)和熱數(shù)據(jù),然后分別進行 LRU 算法。不再像傳統(tǒng)的 LRU 算法那樣,所有數(shù)據(jù)都只用一個 LRU 算法管理。
接下來,具體聊聊 Linux 和 MySQL 是如何避免預(yù)讀失效帶來的影響?
Linux 是如何避免預(yù)讀失效帶來的影響?
Linux 操作系統(tǒng)實現(xiàn)兩個了 LRU 鏈表:活躍 LRU 鏈表(active_list)和非活躍 LRU 鏈表(inactive_list)。
active list活躍內(nèi)存頁鏈表,這里存放的是最近被訪問過(活躍)的內(nèi)存頁;inactive list不活躍內(nèi)存頁鏈表,這里存放的是很少被訪問(非活躍)的內(nèi)存頁;有了這兩個 LRU 鏈表后,預(yù)讀頁就只需要加入到 inactive list 區(qū)域的頭部,當(dāng)頁被真正訪問的時候,才將頁插入 active list 的頭部。如果預(yù)讀的頁一直沒有被訪問,就會從 inactive list 移除,這樣就不會影響 active list 中的熱點數(shù)據(jù)。
MySQL 是如何避免預(yù)讀失效帶來的影響?
MySQL 的 Innodb 存儲引擎是在一個 LRU 鏈表上劃分來 2 個區(qū)域,young 區(qū)域 和 old 區(qū)域。
young 區(qū)域在 LRU 鏈表的前半部分,old 區(qū)域則是在后半部分,這兩個區(qū)域都有各自的頭和尾節(jié)點,如下圖:
young 區(qū)域與 old 區(qū)域在 LRU 鏈表中的占比關(guān)系并不是一比一的關(guān)系,而是 63:37(默認比例)的關(guān)系。劃分這兩個區(qū)域后,預(yù)讀的頁就只需要加入到 old 區(qū)域的頭部,當(dāng)頁被真正訪問的時候,才將頁插入 young 區(qū)域的頭部。如果預(yù)讀的頁一直沒有被訪問,就會從 old 區(qū)域移除,這樣就不會影響 young 區(qū)域中的熱點數(shù)據(jù)。
緩存污染,怎么辦?什么是緩存污染?雖然 Linux (實現(xiàn)兩個 LRU 鏈表)和 MySQL (劃分兩個區(qū)域)通過改進傳統(tǒng)的 LRU 數(shù)據(jù)結(jié)構(gòu),避免了預(yù)讀失效帶來的影響。
但是如果還是使用「只要數(shù)據(jù)被訪問一次,就將數(shù)據(jù)加入到活躍 LRU 鏈表頭部(或者 young 區(qū)域)」這種方式的話,那么還存在緩存污染的問題。
當(dāng)我們在批量讀取數(shù)據(jù)的時候,由于數(shù)據(jù)被訪問了一次,這些大量數(shù)據(jù)都會被加入到「活躍 LRU 鏈表」里,然后之前緩存在活躍 LRU 鏈表(或者 young 區(qū)域)里的熱點數(shù)據(jù)全部都被淘汰了,如果這些大量的數(shù)據(jù)在很長一段時間都不會被訪問的話,那么整個活躍 LRU 鏈表(或者 young 區(qū)域)就被污染了。
緩存污染帶來的問題緩存污染帶來的影響就是很致命的,等這些熱數(shù)據(jù)又被再次訪問的時候,由于緩存未命中,就會產(chǎn)生大量的磁盤 I/O,系統(tǒng)性能就會急劇下降。
怎么避免緩存污染造成的影響?前面的 LRU 算法只要數(shù)據(jù)被訪問一次,就將數(shù)據(jù)加入活躍 LRU 鏈表(或者 young 區(qū)域),這種 LRU 算法進入活躍 LRU 鏈表的門檻太低了!正式因為門檻太低,才導(dǎo)致在發(fā)生緩存污染的時候,很容就將原本在活躍 LRU 鏈表里的熱點數(shù)據(jù)淘汰了。
所以,只要我們提高進入到活躍 LRU 鏈表(或者 young 區(qū)域)的門檻,就能有效地保證活躍 LRU 鏈表(或者 young 區(qū)域)里的熱點數(shù)據(jù)不會被輕易替換掉。
Linux 操作系統(tǒng)和 MySQL Innodb 存儲引擎分別是這樣提高門檻的:
Linux 操作系統(tǒng):在內(nèi)存頁被訪問第二次的時候,才將頁從 inactive list 升級到 active list 里。MySQL Innodb:在內(nèi)存頁被訪問第二次的時候,并不會馬上將該頁從 old 區(qū)域升級到 young 區(qū)域,因為還要進行停留在 old 區(qū)域的時間判斷:如果第二次的訪問時間與第一次訪問的時間在 1 秒內(nèi)(默認值),那么該頁就不會被從 old 區(qū)域升級到 young 區(qū)域;如果第二次的訪問時間與第一次訪問的時間超過 1 秒,那么該頁就會從 old 區(qū)域升級到 young 區(qū)域;關(guān)鍵詞:
電動自行車在城市生活中扮演著重要的角色,但佩戴頭盔對于保護頭部安全
09月01日 07:39
1、哪里用求別人,自己下個紅雪0 9 15B2就可以制作了:運行紅雪,點Ext
09月01日 07:44
新華社北京8月31日電國家統(tǒng)計局服務(wù)業(yè)調(diào)查中心、中國物流與采購聯(lián)合會8
09月01日 07:47
退休第二天背上行囊走進云南大山深處支教央視今晚播出南師附中退休教師
09月01日 07:43
我市昨集中發(fā)布一批先進典型包括今年二季度“南京好人”、南京市2022年
09月01日 07:38
昨天,旅客在南京火車站準備乘車。當(dāng)天,為期62天的全國鐵路暑運結(jié)束。
09月01日 07:49
8月31日,中國科學(xué)院、中國工程院分別公布2023年院士增選有效候選人名
09月01日 07:38
說到現(xiàn)在的車市,那真的是內(nèi)卷到了極致,很多合資品牌真的直接掀了桌子
09月01日 07:40
美最高法院大法官托馬斯申報去年曾接受富豪資助旅行
09月01日 07:40
南非約堡一樓房突發(fā)重大火災(zāi)已致73人遇難
09月01日 07:40
緩和中美關(guān)系“解鈴還須系鈴人”
09月01日 07:48
0471房產(chǎn)來為大家解答以上的問題。cad多重引線快捷命令,cad多重引線快
09月01日 07:42
,你們好,今天0471房產(chǎn)來聊聊一篇包狀腹袋吸蟲,包狀腹袋吸蟲簡述的文
09月01日 07:41
國聯(lián)證券08月30日發(fā)布研報稱,給予上海鋼聯(lián)(300226 SZ,最新價:35 37
09月01日 07:34
1、絕口不提(絕字)【G】絡(luò)繹不絕(絕字)【A】斬盡殺絕(絕字)【B】
09月01日 07:38
“Citywalk”是當(dāng)下旅游新選擇。然而,烈日炎炎與持續(xù)高溫讓不少人望而
09月01日 07:32
智通財經(jīng)APP獲悉,德國科技集團博世高管周三表示,該公司需要美國政府
09月01日 07:37
據(jù)新西蘭中文先驅(qū)網(wǎng)消息,8月31日上午,奧克蘭整個城市籠罩在寒冷的大
09月01日 07:31
這款A(yù)ppleiPhone13系列手機在京東平臺售價為5699元,但現(xiàn)在購買可以使
09月01日 07:43
因冷鏈基礎(chǔ)設(shè)施較差、數(shù)字化業(yè)態(tài)不夠完善等問題,我省農(nóng)產(chǎn)品上行一直存
09月01日 07:38
紅網(wǎng)時刻婁底8月31日訊(通訊員曾黎)8月29日,新化縣桑梓鎮(zhèn)開展特護期
09月01日 07:33
1、裝袋存放:在放土豆的袋子內(nèi)放上一兩個蘋果,蘋果所釋放出來的乙烯
09月01日 07:37
1、他們不可能打倒我,除非殺了我,而任何不能殺了我的人就只會令我更
09月01日 07:35
導(dǎo)讀1、車前子木通蕎麥匾蓄滑石梔子仁大黃甘草。本文到此講解完畢了,
09月01日 07:37
在信陽,如果自己的健康碼發(fā)生了變化,需要第一時間主動向所在社(村)
09月01日 07:38
KimcoRealty(KIM US)當(dāng)?shù)貢r間周一表示,該公司同意以約價值20億美元的
09月01日 07:33
味知香上半年凈利潤增長約6%,李嚴,味知香,公司凈利潤
09月01日 07:37
一、山西省晉中市天氣預(yù)報1、昔陽縣氣象臺2023年08月31日22時15分發(fā)布
09月01日 07:37
對于業(yè)績變動原因,輝煌科技表示,主要原因系報告期內(nèi)完工項目減少致營
09月01日 07:34
2023年8月28日華人健康301408發(fā)布公告稱公司于2023年8月25日接受機構(gòu)調(diào)
09月01日 07:26
國聯(lián)證券08月30日發(fā)布研報稱,給予上海鋼聯(lián)(300226 ......更多>