內存還是硬盤? 數(shù)據(jù)庫IO瓶頸時的抉擇
很多DBA在進行數(shù)據(jù)庫管理時通常都會遇到數(shù)據(jù)庫IO瓶頸,在硬件成本預算有限的情況下,解決這一瓶頸有兩個方法:一是增加內存;二是增加磁盤(假設不增加機器的情況下)。到底是加內存合算,還是加磁盤實惠呢,這是個頭疼的問題。
已經(jīng)神秘消失的數(shù)據(jù)庫大師Jim Gray早在20年前就為我們考慮過這個問題了,并且得出一個結論叫“五分鐘規(guī)則”(Five Minutes Rule),就是說如果一個頁面每五分鐘就會被訪問一次的話,就應該把它放到內存中去,否則就應該把它存儲在磁盤上。這樣,數(shù)據(jù)庫只要統(tǒng)計一下有多少頁面的訪問頻率超過五分鐘一次,就知道需要多少內存了。
當然五分鐘是個典型值,或者表示一個數(shù)量級,具體的值要看硬件條件。Jim Gray給出的公式是:
RI = 每M數(shù)據(jù)頁數(shù) * 一塊磁盤的價格 / 磁盤每秒能進行的隨機IO次數(shù) / 每M內存的價格
其中RI即為要放到內存的頁面訪問時間周期閾值。
這個一公式可以這么理解。假設你拿到一個頁面,它的訪問周期是I。你要決定是買內存來存儲這個頁面還是買磁盤來存儲它。假設買內存來存儲,開銷很容易算出來是"每M內存價格/每M數(shù)據(jù)頁數(shù)"。如果買磁盤來存,則開銷是"一塊磁盤的價格 / 磁盤每秒能進行的隨機IO次數(shù) / I",意思是說,我買個磁盤花的錢是“一塊磁盤的價格”這么多,再我這個頁一秒只會訪問"1/I"次,因此我只占用了磁盤帶寬的"1/I/磁盤每秒能進行的隨機IO次數(shù)",因此為這個頁花的開銷就是“一塊磁盤的價格 / 磁盤每秒能進行的隨機IO次數(shù) / I"。
這樣,導致內存開銷"每M內存價格/每M數(shù)據(jù)頁數(shù)"與磁盤開銷"一塊磁盤的價格 / 磁盤每秒能進行的隨機IO次數(shù) / I"相等的I值即為訪問時間周期閾值,計算出來就是公式中的RI。
在數(shù)據(jù)庫IO瓶頸時,針對當前常用硬件來計算一下。設頁面大小為16K(InnoDB默認頁面大?。?,也就是每M數(shù)據(jù)頁數(shù)64,一塊SAS盤算3000塊,每秒能進行200次隨機IO,4G的內存算3000塊一條,也就是每M內存0.75元。這樣算出來RI是1280秒,也就是20分鐘左右。
可惜的是MySQL并不提供頁面的訪問頻率統(tǒng)計功能??梢杂靡粋€方法來代替,就是把數(shù)據(jù)庫關掉,起來后看20分鐘內數(shù)據(jù)庫的緩存有沒有滿,若沒有滿,表示內存太大,否則表示內存太小。只是在熱門時間段肯定是不會去做這個實驗的,非熱門時間段倒是可以把數(shù)據(jù)庫重起下,但這時負載輕又不準了。即使是哪天MySQL crash了,在熱門時間段crash后要做很多redo,又不準了。
實際上這一功能是可以實現(xiàn)的,統(tǒng)計有多少個20分鐘訪問一次的頁面可以近似的轉化為統(tǒng)計20分鐘內有多少個不同的頁面被訪問。假設系統(tǒng)中內存大小與理想值相差不太大,則只需要多用不到1/1000的內存就可以統(tǒng)計出來,當然每次頁面訪問時要多搜索一個哈希表。嗯,在NTSE里準備實現(xiàn)吧,哈哈。
當然這一計算已經(jīng)忽略了很多實際因素,比如如果你機器上的RAID卡已經(jīng)滿了不能加硬盤,那就只好加內存了,如果內存槽插滿了,那就只好加硬盤了。如果硬盤和內存都加不了,那就加機器吧。另外上述計算假設頁面訪問是完全隨機的,如果是順序訪問,那就大不相同了,這時的RI會小很多,因為這時磁盤每秒能讀入的頁面數(shù)增加了。
【編輯推薦】