[分享] Linux的RAM Disk(資料不消失版)

常言道:『飲水思源』,在 Open Source 的世界裡,我們常常需要別人的幫助,但是在您有所心得的時候請記得分享給大家,『幫助人是快樂的喔』。歡迎您在使用 debian 的過程中的任何心得分享給大家。

[分享] Linux的RAM Disk(資料不消失版)

文章ycfu » 週三 8月 27, 2008 11:07 pm

RAM Disk是一個非常方便的東西,尤其現在DDR2的RAM很便宜時,善用RAM Disk可以有很大的效能改善。
雖然RAM Disk已經不是什麼新鮮的東西了,但是這次我針對Linux上的RAM Disk Script加入了開/關機備份/還原的功能,應該就很少見了。

我個人認為Linux上的RAM Disk比Windows和FreeBSD來得方便好用,Linux的shm(Share Memory)實在太強大了。
在Windows上,RAM Disk的軟體不少,但多半都是切割一塊RAM當磁碟,FreeBSD上也是(FreeBSD的shm實做了嗎?有消息的回覆一下吧~),但在Linux上,因為Share Memory技術的關係,可以直接把Share Memory bind 到 /tmp,直接當作 RAM Disk 使用,這樣的優點是,系統記憶體和RAM Disk是共用的,RAM Disk不需要額外割一塊出來,舉個例子:
假設RAM有1024MB(1G),我要512MB的RAM Disk
在Windows、FreeBSD上,系統記憶體就只剩下512MB,另外512MB變成一個RAM Disk。
而在Linux上,系統記憶體還是1024MB(1G),假如我在RAM Disk上吃掉了100MB的空間,則系統記憶體會變成924MB,而RAM Disk(Share Memory)的上限是多少?1024MB嗎?
這可以自己設定,系統預設是RAM的一半,以這例子來說,Linux預設的RAM Disk(Share Memory)就是512MB。

RAM Disk速度很快,尤其是拿來compile kernel時特別明顯,可以明顯感受到,花費的時間比較短,這要歸功於Linux Kernel Source Code很大,所以感受得出來。

另一個重要的場合大概就是Eee PC這類輕巧筆電了,輕巧筆電因為「輕巧」、「價格」...等因素,往往硬碟很小,而且硬碟經常速度很慢(EeePC 900、901的第二顆Flash,Aspire one 110的8G Flash),在無法擴充或是擴充價格很誇張時,加大RAM並善用它變得很重要,因此在輕巧筆電上設定RAM Disk,幾乎是「必要的設定」(不論是XP或Linux)。

RAM Disk的致命傷就是重開機資料就消失,稍微搜尋後可以發現,Windows上已經有不少人提供備份、還原的script,搭配XP Pro的系統原則就可以在關機時備份RAM Disk的資料,那Linux呢?就在這裡啦~~

首先,我RAM Disk的建立,是使用[閒聊]有趣的 tmpfs最後的script版本,並不是寫在/etc/fstab當中。
RAM Disk(tmpfs)的詳細介紹可以參考Tsung's Blog的拿 RAM 當硬碟來用(RAM Disk),作者把所有的tmpfs建立方法全部敘述了,內容清楚明確,非常值得參考,我使用的屬於方法一。

簡單敘述建立RAM Disk的方法:

1. 把下列script內容編輯,並存檔為/etc/init.d/mounttmpfs.sh
代碼: 選擇全部
#!/bin/sh
#
# mounttmpdir Mount /tmp after mounvirtfs exec-ed
#
# Version: @(#)mounttmpdir 0.01 24-Dec-2004 antony shen
# 參考網址:http://moto.debian.org.tw/viewtopic.php?t=4100&highlight=shm
# 執行指令:update-rc.d mounttmpfs.sh start 37 S .
#

# Script needs to be robust and continue when parts fail,
# so we're not setting the "-e" flag.
#set -e

PATH=/lib/init:/bin:/sbin

if [ -d /dev/shm ]
then
if [ ! -d /dev/shm/tmp ]
then
echo -n "Mounting tmpfs(/tmp,/var/tmp) under /dev/shm..."

mkdir /dev/shm/tmp
mkdir /dev/shm/vtmp
chmod 1777 /dev/shm/tmp
chmod 1777 /dev/shm/vtmp
mount --bind /dev/shm/tmp /tmp
mount --bind /dev/shm/vtmp /var/tmp

echo "OK."
fi
else
echo "Failed to find /dev/shm, unable to link /tmp under it!"
fi


2. 執行
代碼: 選擇全部
update-rc.d mounttmpfs.sh start 37 S .


3. 重新開機

4. 複製個檔案 (cp /boot/* /tmp/) 到 /tmp 執行 df,查看 /dev/shm 的使用空間有沒有變化,有變化就是成功了。

接下來,我們進一步來玩Backup/Restore的部份,如下:

1. 把下列script存檔為/etc/init.d/backuptmpfs.sh
代碼: 選擇全部
#!/bin/sh
#
# 參考 mounttmpfs.sh 修改而成
#
# Version: @(#)backuptmpfs.sh 0.01 2008-08-26 YCFu
# 執行指令:update-rc.d backuptmpfs.sh stop 1 0 6 .
#

# Script needs to be robust and continue when parts fail,
# so we're not setting the "-e" flag.
#set -e

PATH=/lib/init:/bin:/sbin

if [ -d /dev/shm ]
then
if [ -d /dev/shm/tmp ]
then
echo -n "Backup tmpfs(/tmp) to /RAMDISK_bak.tar..."

tar -X /etc/non-list -C /tmp -cf /RAMDISK_bak.tar .
chmod 600 /RAMDISK_bak.tar

echo "OK."
fi
else
echo "Backup Fail!"
fi


2. 把下列script存檔為/etc/init.d/restoretmpfs.sh
代碼: 選擇全部
#!/bin/sh
#
# 參考 backuptmpfs.sh 修改而成
#
# Version: @(#)backuptmpfs.sh 0.01 2008-08-26 YCFu
# 執行指令:update-rc.d restoretmpfs.sh start 38 S .
#

# Script needs to be robust and continue when parts fail,
# so we're not setting the "-e" flag.
#set -e

PATH=/lib/init:/bin:/sbin

if [ -f /RAMDISK_bak.tar ]
then
echo -n "Restore tmpfs(/tmp) from /RAMDISK_bak.tar..."

tar -C /tmp -xf /RAMDISK_bak.tar
rm /RAMDISK_bak.tar

echo "OK."
fi

3. 執行下列指令:
代碼: 選擇全部
update-rc.d restoretmpfs.sh start 38 S .
update-rc.d backuptmpfs.sh stop 1 0 6 .


4. 執行下列指令建立排除檔案列表
代碼: 選擇全部
touch /etc/non-list


5.完成

上述程式說明:
簡單的說,我改了2個script,一個用在關機時備份RAM Disk,一個用在開機時還原RAM Disk。

關機時備份RAM Disk的叫做backuptmpfs.sh,它會在inittab狀態為0和6時執行(放到rc0.d和rc6.d),0和6分別是關機狀態和重新開機狀態。

開機時還原RAM Disk的叫做restoretmpfs.sh,「它必須在 mounttmpfs.sh 之後執行」,它會在開機時,建立RAM Disk之後,將RAM Disk資料還原回去。
為什麼不整合到mounttmpfs.sh之中呢?
我試過了,它似乎會和mount --bind衝突,可能需要delay一點時間吧。

由於RAM Disk中,通常會放置Firefox的暫存目錄,我們不希望所有東西都備份,因此我們要設定個排除檔案名單,將特定的目錄或檔案排除。
排除名單放在/etc/non-list,只需要把不要備份的名稱加入即可
以Firefox的暫存目錄來說,Firefox會自動建立暫存目錄/tmp/Cache,我們只需要在/etc/non-list中寫上:
代碼: 選擇全部
Cache


如果我們希望排除多個檔案或目錄,例如檔案「EEE」和目錄「Cache」,則在/etc/non-list中寫上:
代碼: 選擇全部
Cache
EEE


備份的檔案會存在哪裡?檔名是什麼呢?
備份的檔案會存為/RAMDISK_bak.tar會在還原後自動刪除
此外,為了安全性的考量,/RAMDISK_bak.tar的權限會設為600

最後,因為這是第一版,所以我並沒有將上面提到的參數設為變數,不過這幾個script並不複雜,相信稍微看一下,就能夠看懂並修改,歡迎大家修改使用,改過後記得再貼出來造福更多人。

PS: 本篇同步 po 在我的blog
ycfu
可愛的小學生
可愛的小學生
 
文章: 28
註冊時間: 週一 4月 03, 2006 1:34 am

文章tomjpsun » 週四 8月 28, 2008 12:20 pm

....可以直接把Share Memory bind 到 /tmp,直接當作 RAM Disk 使用...
不好意思,這一段想不通耶。
如果是 RAM file system ( /dev/shm ) bind 到 /tmp ( disk ) , 其實是不經過 RAM disk 的 , 又為何要寫 script 備份 RAM disk 的內容呢?
tomjpsun
可愛的小學生
可愛的小學生
 
文章: 82
註冊時間: 週一 1月 03, 2005 2:40 pm

文章wesley.tw » 週四 8月 28, 2008 6:54 pm

若我的NB suspend to disk 之後再 resume 該怎麼解決呢?
資料在 ram disk 中因為 suspend 不就也沒資料啦!
how to restore my data after resume ? :-P
Wesley@Net. - Learning by doing.
http://blog.yam.com/wesley1981
wesley.tw
可愛的小學生
可愛的小學生
 
文章: 52
註冊時間: 週五 9月 22, 2006 10:56 am
來自: 中壢

文章tomjpsun » 週五 8月 29, 2008 7:30 am

小弟的意思是---ramfs 不是經過 RAM disk的,請看
Kernel Documentation
所以認為沒有必要備份 RAM disk 。

s2disk 是把 all pages dump to disk, 當然包含了 ramfs , restore 時也還是一起回復到 RAM (沒作過實驗,只是推論....錯了不要打我)
tomjpsun
可愛的小學生
可愛的小學生
 
文章: 82
註冊時間: 週一 1月 03, 2005 2:40 pm

文章ycfu » 週五 8月 29, 2008 5:10 pm

感謝tomjpsun的回覆,
....可以直接把Share Memory bind 到 /tmp,直接當作 RAM Disk 使用...
這段文字的確有問題,當時打這段文字時,是想到了
mount --bind /dev/shm /tmp

因此就打出了這段話,如果要說,應該是改成:
在Linux上,因為tmpfs技術的關係,能夠直接使用Share Memory當成檔案系統來使用,因此能讓檔案系統上的資料能複製到Share Memory當中,和其他process共用Memory。
而在FreeBSD上,看來FreeBSD 7.0已經開始支援tmpfs了。

此外,我同意 ramfs 沒有備份的必要這樣的說法,因為解釋上,ramfs 應該是作為暫存空間。
但是當 RAM 夠大時,我會希望建個資料不會消失的 RAM disk,像是可能會把程式安裝在這樣的目錄中,或者放些經常性讀寫的檔案在裡面,但又希望開機、關機資料不會消失。
ycfu
可愛的小學生
可愛的小學生
 
文章: 28
註冊時間: 週一 4月 03, 2006 1:34 am

文章訪客 » 週五 8月 29, 2008 6:00 pm

ycfu 寫:而在FreeBSD上,看來FreeBSD 7.0已經開始支援tmpfs了。

很早之前, FreeBSD 即有 MD 可以使用
並非 7.0 才有類似功能
訪客
 

文章alex5168 » 週六 8月 30, 2008 4:09 pm

試了一下, 速度有比較快, 感謝分享!
alex5168
可愛的小學生
可愛的小學生
 
文章: 67
註冊時間: 週五 5月 11, 2007 11:06 pm

文章tomjpsun » 週一 9月 01, 2008 7:16 am

嗯,感謝開版大大的分享與解釋,多謝了!
tomjpsun
可愛的小學生
可愛的小學生
 
文章: 82
註冊時間: 週一 1月 03, 2005 2:40 pm

文章ronmi » 週二 9月 02, 2008 10:30 am

我也會把程式放進ramdisk來加速
需要加速的東西大多是主程式的部份
可能我的資料量不大所以還不需要放進ramdisk吧
(謎之音: 資料量大也放不進你的小ramdisk)

被我放進ramdisk的有
fx、eclipse主程式
eclipse plugin(不含設定)
jre/jdk
fx cache/offline cache(使用額外的script設定)
吃掉大約512M,但不論是eclipse或是fx的開啟/執行速度都讓我很滿意了

以下是我的rc.local

代碼: 選擇全部
initRamDiskCopy()
{
        mkdir -p /dev/shm/${1}
        cp -pr ${1}/. /dev/shm${1}/
        mount --rbind /dev/shm${1} ${1}
}

# init ramdisk firefox
RamDiskDir="/usr/lib/firefox /usr/lib/firefox-3.0.1 /usr/lib/firefox-addons /usr/share/firefox /usr/lib/java /usr/lib/jvm /usr/lib/jni /usr/share/java /usr/lib/flashplugin-nonfree /home/xxx/.eclipse/org.eclipse.sdk.ide"

for i in ${RamDiskDir}
do
        initRamDiskCopy ${i}
done
ronmi
懵懂的國中生
懵懂的國中生
 
文章: 103
註冊時間: 週一 12月 05, 2005 2:31 am
來自: Taiwan

文章bluesheet » 週六 4月 18, 2009 10:37 am

HAHA. 估不到大大的想法比我更完美.
我使用ramdisk來compile東西已經有幾年的情況了.但我由於是開發為主,無必要為ramdisk內的東東作備份,所以沒有restore的動作.但我會把我常用的軟件如firefox等等由開機時自動倒到ramdisk上,把home直接連到ramdisk上方便工作. 比起以前用hdd, i/o 的情況改善了很多呢?
bluesheet
可愛的小學生
可愛的小學生
 
文章: 9
註冊時間: 週五 4月 17, 2009 4:15 pm


回到 share

誰在線上

正在瀏覽這個版面的使用者:沒有註冊會員 和 1 位訪客