如何利用磁碟順序讀寫快於內存隨機讀寫這一現象?
今天看了kafka官網的介紹,談了設計理念,其中有提到相對於內存的隨機讀寫,使用硬碟的順序讀寫會更好更快,所以kafka使用磁碟而不是內存。但是從JAVA的角度來說,什麼是內存的隨機讀寫和硬碟的順序讀寫?比如我需要緩存一個10GB的queue,是否寫入一個大文件,然後全部讀取會比全部寫入linkedlist然後讀取快?可是我認為硬碟上也不一定有非常大的連續空間,所以實際不一定是連續讀寫。這樣的話,作為一名程序猿,在寫代碼的時候如何才能利用這一個點?
既然邀請我回答,我勉為其難說一點我知道的。
首先說概念:
物理內存和虛擬內存。
物理內存就是我們常說的ddr(早期叫sdram翻譯成中文叫做隨機訪問存儲器),ddr就是Double Data Rate隨機訪問存儲器,也就是說這個東西就是為隨機訪問設計的,每次訪問的數據位寬通常由匯流排寬度決定。(下圖來自網路侵刪)
上面一張圖可以看出對於普遍使用的ddr4內存在不考慮匯流排影響的情況下的速度未17GB每秒,這個速度是磁碟不論如何都達不到的。
相反的,磁碟的讀寫速度受到磁頭調度,轉速等物理條件的影響相對較慢,為什麼順序讀/寫速度較隨機訪問快,就是省去了磁頭調度時間,一般情況下磁頭調度幾毫秒到幾十毫秒不等,即使是順序讀/寫目前主流的磁碟速度大概100~200 MB/s之間(畢竟是機械部件)。
實際上,磁碟為了提高io性能,基本上都會內置一塊內存作為緩存(持續讀寫速度超過150MB/s的希捷新酷魚1TB硬碟採用64MB緩存,下圖來自網路侵刪),
現代操作系統並不直接提供物理內存給程序訪問,而是使用虛擬內存機制,讓每個應用程序認為自己獨佔內存空間,虛擬內存並不一定能映射到實際的物理內存,當程序訪問到這段地址的時候,操作系統會產生缺頁異常,將不常使用的數據刷寫到磁碟,以便騰出內存讓程序訪問,這個操作會大量的消耗io操作,導致性能低下。
java本身不提供實際內存的訪問,虛擬機會預留虛擬內存使用,在少量使用內存的情況下,並且沒有產生垃圾回收的情況下,我傾向於認為此時速度和物理內存一致;但是在大量內存的情況下,當操作系統偵測到缺頁異常的時候,這個時候隨機訪問速度會低於磁碟的順序訪問速度。
綜上,如果不是出現大量內存隨機訪問,導致頻繁出現缺頁或者頁面調入調出的情況,內存隨機讀寫速度是遠遠快於磁碟順序訪問速度的。
推薦閱讀:
※怎麼把系統跑在內存里?
※多核系統下內存一致性如何保證?
※目前這個這個時代,swap space還有什麼意義?
※內存有必要清理嗎?
※矢量化操作系統界面,為什麼很難實現?