因為這是Wiki的一個條目,可以在任何時間內被任何人編輯,因此建議你不要完全使用這個腳本,而是將其當作編寫腳本的指導手冊看待。
該教學向你大概描述什麼是虛擬硬盤,怎樣和 Minecraft 使用,以及如何設定一個虛擬硬盤伺服器。
虛擬硬盤描述
傳統上,檔案和資料夾儲存在硬盤驅動器,但以今天的標準來看,普通數據的傳輸速度(80MB/秒 到 200MB/秒之間)的提升空間還很大。虛擬硬盤是一個虛擬的檔案系統(不像硬盤那樣是硬件),會把檔案數據完全實時儲存在計算機記憶體條裡。它們的普通數據傳輸速度(3000MB/秒 到 15000MB/秒之間)非常高,但會失去穩定性(重啟電腦數據就會丟失)以及空間(受系統安裝記憶體條的數量限制,包括交換空間)。然而,有許多實用工具可以每隔一段時間備份虛擬硬盤裏面的數據,以及在關機前備份,然後在系統啟動時載入上次儲存的數據。
優點和缺點
優點
- 非常高的傳輸速度(從數據到應用)
- 非常低的尋道時間(在檔案之間搜尋)
缺點
- 在系統重啟時會清除虛擬硬盤的數據
- 如果世界尺寸大於記憶體條可用空間則很難實現
為什麼它對 Minecraft 伺服器有意義
在一個 Minecraft 伺服器,最大的一個瓶頸是相關的磁盤 I/O 操作(如區塊管理)。透過向記憶體流動資料,訪問時間會被大大縮減,數據傳輸速度也會大大提高,讓區塊載入和儲存區塊操作變得更快。因為一個 Minecraft 世界包含了許多區塊檔案,尋道時間沒多大變化,因為重要的是整體速度。
基礎 Minecraft 和虛擬硬盤安裝
確保在開始前備份了你的檔案!
GNU/Linux(簡單方法)
2011年3月12日,在 Aimless Bits 的網誌裡,發佈了把一個 Minecraft 伺服器載入到虛擬硬盤的簡單方法。它包含了修改過的 Wiki 腳本,以及一些小變更。本指南充實了這一過程,並在 Aimless Bits 的腳本裡做了一些小變更。
這個快速指南假設你已為載入 Minecraft 設定了一個用户、Minecraft 目錄和執行中的伺服器。它還有助於熟悉 /etc/init.d/minecraft 啟動腳本。
- 第一步,在根目錄裡為虛擬硬盤建立一個目錄。如「/home/username/minecraft_ramdisk」。
- 要將其掛載為一個虛擬硬盤,只需要簡單編輯你的 /etc/fstab/ 檔案:
sudo nano /etc/fstab
然後加入這行,確保路徑(使用者名稱、目錄名稱等)是正確的。
tmpfs /home/username/minecraft_ramdisk tmpfs defaults,size=512m 0 0
虛擬硬盤的尺寸必須比 Minecraft 的世界目錄還要大。確保你已經預留多了一些空間。
- 重啟你的計算機。虛擬硬盤現在會在你重啟時載入,如果你希望立刻載入,輸入
mount -t tmpfs none /home/username/minecraft_ramdisk -o size=512m
現在要做的是簡單執行簡單修改過的腳本,該腳本會載入硬盤上的檔案到伺服器裡,將它們複製幾次作為副本,以防止數據丟失。再次提醒,這個腳本是 Aimless Bits 腳本的修改版本。
如果你擁有 /etc/init.d/minecraft,刪除它或者將其覆蓋到這個腳本裡。如果沒有,新建一個文字文件,命名為「minecraft」,然後向它複製下列腳本內容。
#!/bin/bash
# /etc/init.d/minecraft
# version 0.6 2012-02-25 (YYYY-MM-DD)
### BEGIN INIT INFO
# Provides: minecraft
# Required-Start: $local_fs $remote_fs
# Required-Stop: $local_fs $remote_fs
# Should-Start: $network
# Should-Stop: $network
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Minecraft server
# Description: Starts the minecraft server
### END INIT INFO
#Settings
JARFILE='craftbukkit-beta_1.4.6-R0.3.jar'
USERNAME="minecraft"
MCSTORE="/home/$USERNAME/minecraft"
MCPATH="/home/$USERNAME/minecraft_ramdisk"
CPU_COUNT=1
INVOCATION="java -Xmx2048M -Xms2048M -server -jar $JARFILE -o false"
BACKUPPATH="/home/$USERNAME/minecraft_backups/"
WORLD=Asgarde
as_user() {
if [ "`whoami`" == "$USERNAME" ] ; then
bash -c "$1"
else
su - $USERNAME -c "$1"
fi
}
mc_status() {
ps aux |grep -F -v grep|grep -F -v SCREEN|grep -F --quiet $JARFILE
return $?
}
mc_start() {
if mc_status; then
echo "Tried to start but $JARFILE was already running!"
else
echo "$JARFILE was not running... starting."
if [ -d $MCSTORE/$WORLD.bak ]; then
echo "last $WORLD.bak still exist, crashed warning! manual check required!!!"
exit 1
fi
cd $MCPATH
if [ ! -f "$MCPATH/$JARFILE" ]; then
echo "Ram drive empty... prepping."
as_user "cp -R $MCSTORE/* $MCPATH/"
fi
as_user "cd $MCPATH && screen -dmS minecraft $INVOCATION"
sleep 7
if mc_status; then
echo "$JARFILE is now running."
else
echo "Could not start $JARFILE."
fi
fi
}
mc_saveoff() {
if mc_status; then
echo "$JARFILE is running... suspending saves"
TO_SCREEN="screen -p 0 -S minecraft -X eval 'stuff "
as_user "$TO_SCREEN \"say SERVER BACKUP STARTING. Server going readonly...\"\015'"
as_user "$TO_SCREEN \"save-off\"\015'"
as_user "$TO_SCREEN \"save-all\"\015'"
sync
sleep 10
else
echo "$JARFILE was not running. Not suspending saves."
fi
}
mc_saveon() {
if mc_status; then
echo "$JARFILE is running... re-enabling saves"
TO_SCREEN="screen -p 0 -S minecraft -X eval 'stuff "
as_user "$TO_SCREEN \"save-on\"\015'"
as_user "$TO_SCREEN \"say SERVER BACKUP ENDED. Server going read-write...\"\015'"
else
echo "$JARFILE was not running. Not resuming saves."
fi
}
mc_stop() {
if mc_status; then
echo "$JARFILE is running... stopping."
TO_SCREEN="screen -p 0 -S minecraft -X eval 'stuff "
as_user "$TO_SCREEN \"say SERVER SHUTTING DOWN IN 5 SECONDS. Saving map...\"\015'"
as_user "$TO_SCREEN \"save-all\"\015'"
sleep 5
as_user "$TO_SCREEN \"stop\"\015'"
sleep 5
else
echo "$JARFILE was not running."
fi
if mc_status; then
echo "$JARFILE could not be shut down... still running."
else
echo "$JARFILE is shut down."
fi
}
mc_update() {
if mc_status; then
echo "$JARFILE is running! Will not start update."
else
MC_SERVER_URL=https://minecraft.net/`wget -q -O - http://www.minecraft.net/download.jsp | grep minecraft_server.jar\</a\> | cut -d \" -f 2`
as_user "cd $MCPATH && wget -q -O $MCPATH/minecraft_server.jar.update $MC_SERVER_URL"
if [ -f $MCPATH/minecraft_server.jar.update ]; then
if `diff $MCPATH/$JARFILE $MCPATH/minecraft_server.jar.update >/dev/null`
then
echo "You are already running the latest version of $JARFILE."
else
as_user "mv $MCPATH/minecraft_server.jar.update $MCPATH/$JARFILE"
echo "Minecraft successfully updated."
fi
else
echo "Minecraft update could not be downloaded."
fi
fi
}
mc_backup() {
echo "Backing up minecraft files"
as_user "tar zcf $BACKUPPATH/MCBKUP_`date "+%Y.%m.%d-%H"`.tar.gz $MCSTORE"
echo "Backup complete"
}
mc_disksaverun() {
if mc_status; then
echo "Saving ramdrive to disk."
if [ ! -f $MCPATH/$JARFILE ]; then
echo "Error.. Minecraft not in ram"
else
if [ -d $MCSTORE/$WORLD.bak ]; then
echo "last $WORLD.bak still exist, crashed warning! manual check required!!!"
exit 1
fi
if [ -d $MCSTORE/$WORLD ]; then
as_user "mv $MCSTORE/$WORLD $MCSTORE/$WORLD.bak"
fi
TO_SCREEN="screen -p 0 -S minecraft -X eval 'stuff "
as_user "$TO_SCREEN \"save-off\"\015'"
as_user "$TO_SCREEN \"save-all\"\015'"
as_user "cp -R $MCPATH/* $MCSTORE/"
as_user "$TO_SCREEN \"save-on\"\015'"
if [ -d $MCSTORE/$WORLD.bak ]; then
as_user "rm -r $MCSTORE/$WORLD.bak"
fi
fi
else
echo "Service is not running"
fi
}
mc_disksavehalt() {
echo "Saving ramdrive to disk."
if [ ! -f $MCPATH/$JARFILE ]; then
echo "Error.. Minecraft not in ram"
else
if [ -d $MCSTORE/$WORLD.bak ]; then
echo "last $WORLD.bak still exist, crashed warning! manual check required!!!"
exit 1
fi
if [ -d $MCSTORE/$WORLD ]; then
as_user "mv $MCSTORE/$WORLD $MCSTORE/$WORLD.bak"
fi
echo "Saving, screen session closed"
as_user "cp -R $MCPATH/* $MCSTORE/"
if [ -d $MCSTORE/$WORLD.bak ]; then
as_user "rm -r $MCSTORE/$WORLD.bak"
fi
fi
}
#Start-Stop here
case "$1" in
start)
mc_start
;;
stop)
mc_stop
mc_disksavehalt
;;
restart)
mc_stop
mc_disksavehalt
mc_start
;;
update)
mc_stop
mc_backup
mc_update
mc_start
;;
backup)
mc_disksaverun
mc_saveoff
mc_backup
mc_saveon
;;
disksavehalt)
mc_disksavehalt
;;
disksaverun)
mc_disksaverun
;;
status)
if mc_status; then
echo "$JARFILE is running."
else
echo "$JARFILE is not running."
fi
;;
*)
echo "Usage: /etc/init.d/minecraft {start|stop|update|backup|status|restart|disksaverun}"
exit 1
;;
esac
- 把該腳本移動到你的 /etc/init.d/ directory,然後設定它為可執行:
mv /directory/wherefileis/filename /etc/init.d/minecraft chmod a+x /etc/init.d/minecraft
註: 該腳本沒有寫上在該網站的其他 minecraft 初始化腳本的命令列選項! 因此重寫了該腳本,加入了一些命令代碼,因此虛擬硬盤伺服器也可以使用命令之類去同步而不用使用其他外掛來進行計劃:http://pastebin.com/4ynwL2js 。如果需要命令列選項,可以使用這個。
你就快完成了!這個腳本表現的和原始的啟動腳本差不多,只有一點不同的就是它把數據載入到虛擬硬盤裏。你也可以修改腳本來使用 rsync 而不是 cp。
"rsync -r -t $MCSTORE/ $MCPATH/"
如果你想做其他東西,例如遠程複製,但這對效能沒什麼影響,除非你的世界很大。
- 請勿跳過這個步驟!你需呀加入一個 crontab 條目來儲存你的世界。因為某些原因,你要接着往下看,但是如果你不完成這個步驟,那麼你在虛擬硬盤裏的數據就會丟失。該腳本有2個磁盤儲存函數,disksavehalt 和 disksaverun。 Disksavehalt 指定 screen 對談正在關閉還是正在備份,不會關閉地圖儲存。不要在 crontab 裡調用這個函數,而是使用 disksave。做這個:
sudo crontab -e
然後加入下面2行:
*/5 * * * * /etc/init.d/minecraft disksaverun 20 */6 * * * /etc/init.d/minecraft backup
數字代表每隔多少分鐘就儲存世界,如果你喜歡一個強健的安裝、有力的供給備份以及工作,就減少這個數字。這個間隔最低只能為5分鐘。
其他行執行 Minecraft 會每隔6小時備份一次,並且固定在:20時進行備份。不要跳過備份!這是最後一次警吿!
但願這能夠對管理員有幫助,祝你好運!
GNU/Linux(備選方法)
在多數的 GNU/Linux 發行版,虛擬硬盤已經設定好了(通常掛載在 /dev/shm (shared memory(共享的記憶體))),預設最多使用已安裝記憶體的一半) 如果未設定,互聯網上有許多資源教你如何設定。
可以把任何東西移到虛擬硬盤,但本教學只專注於把地圖移動到虛擬硬盤裏,並將伺服器檔案留在傳統驅動器上。
在用户根目錄裡的「minecraft_server/」伺服器目錄裡分成下面幾個基本檔案,含有世界「world」和其他所需要的檔案。
| ~/minecraft_server/ |
|---|
| world/ |
| minecraft_server.jar |
| server.log |
| server.properties |
| ... |
接下來的目標是把「world/」移動到共享記憶體裡。由於虛擬硬盤的不穩定性,我們要建立一個新資料夾,在裏面放上一個自動備份的腳本,透過複製目前目錄到一個新名稱目錄來定期儲存目前世界的名為(例如)「world_storage」的快照。
$ cd ~/minecraft_server/ $ cp -r world/ world_storage/
現在舊世界在一個安全位置裡,我們現在可以進行下一步並將世界移動到虛擬硬盤。
$ mkdir /dev/shm/minecraft $ mv world/ /dev/shm/minecraft
現在,世界以及載入到記憶體裡,但是 Minecraft 伺服器還是沒有在它的目錄裡看見這個世界,導致在啟動時會重新生成它。為了阻止伺服器生成它,我們要在虛擬硬盤裏創造一個符號連結到那個世界。執行下列命令:
$ ln -s /dev/shm/minecraft/world/
這將會建立一個名為「world/」的連結,其連結到伺服器目錄「/dev/shm/minecraft/world/」,伺服器會把它當作實際的世界資料夾使用,但是這個資料夾在記憶體裡。
現在我們需要注意虛擬硬盤的不穩定性,要定期儲存記憶體「world_storage/」裏面的世界。下面將使用 cron 進行計劃任務和 rsync 進行同步。
首先,建立一個叫作 cron 的腳本(它不能是一個腳本,因為你可以直接從 cron 命令列直接調用 rsync,但這樣允許在晚些時候更容易的進行自訂)
#!/bin/sh VOLATILE="/home/$USER/minecraft_server/world/" PERMANENT="/home/$USER/minecraft_server/world_storage/" #TODO: Check if both directories actually exist, skipped here for clearness rsync -r -t -v "$VOLATILE" "$PERMANENT"
然後每隔幾分鐘執行該腳本(這裏將會隔5分鐘,你可以測試一下隔多長時間對你是最合適的)
$ crontab -e
你將會被帶到一個編輯器(更精確的説:你的「EDITOR」環境變數編輯器)來編輯你的用户 cron 表。加入下列行:
*/5 * * * * bash /home/<your_username>/minecraft_server/save_world.sh &>/dev/null
現在你的伺服器將會重啟,你將會在晚些時候在共享記憶體裡(/dev/shm/minecraft/world)重新建立世界資料夾(/dev/shm/minecraft),因為重啟後 /dev/shm/ 是空的。你可以寫一個簡單的可執行腳本來做到這點。
因此製作一個簡單的可執行腳本:
exec 1>/tmp/backup_world.log 2>&1 #sends the output to this file #!/bin/sh #remake the paths mkdir /dev/shm/minecraft mkdir /dev/shm/minecraft/world VOLATILE="/home/$USER/minecraft_server/world/" PERMANENT="/home/$USER/minecraft_server/world_storage/" #TODO: Check if both directories actually exist, skipped here for clearness #reversed the order rsync -r -t -v "$PERMANENT" "$VOLATILE"
每次你重啟時,你都要執行這個腳本來重新掛載虛擬硬盤。不要把這個加入到 crontab 裡。如果你找出了答案,那麼你可以加入這個到 start up。
Windows
使用一個像 Dataram RAMDisk(下載免費的版本)之類的虛擬硬盤實用工具來在記憶體中建立一個磁盤,並將伺服器檔案放進裏面。 Dataram RAMDisk 提供了在其關閉的時候或隔幾分鐘自動儲存圖像的選項。
開始之前:
- 至少要4G記憶體
- 開啟「關機時儲存磁盤映像」,在關機時停止虛擬硬盤的執行會對 Windows 關機時間造成影響,同時也會對開機時間造成影響,因為要「在啟動時載入磁盤映像」。如果你僅在需要時手動啟動或停止伺服器,那麼這就不成問題了。
- 在網路上進行搜尋儲存虛擬硬盤數據的方法,以防你的虛擬硬盤不能工作時丟失數據。
- FAT16 格式的虛擬硬盤通常比 FAT32 的要快,然而 FAT16 格式不允許單個磁盤容量超過 2048 MB。
- 記住:經常備份!如果你的電腦崩掉了,任何未儲存的虛擬硬盤數據都會丟失!
- 確保你為虛擬硬盤分配了足夠的空間,可以裝得下「Minecraft Server」資料夾 - 記得 Minecraft 世界數據可以增加很多!
- ...最後,確保剩餘的記憶體空間足夠讓 Windows 和伺服器本身執行
設定你的虛擬硬盤(簡單用法)
- 下載並安裝 Dataram RAMDisk
- 設定硬盤尺寸(不推薦設定到最大)
- 如果硬盤尺寸少於等於 2048 MB,選擇「FAT16 Partition」否則就選「FAT32 Partition」(高級用户可能會選擇「unformatted」並手動格式化硬盤)
- 前往 Load/Save 頁籤,並選擇所有3種虛擬硬盤儲存方法(「AutoSave」、「Save Disk Image on Shutdown」和「Load Disk Image on Startup」)
- 要啟動你的虛擬硬盤 - 點擊「Start RAMDisk」
- 現在前往「計算機」(Win XP 為我的電腦、Win 7、Win 10 為計算機、Win 8 為此計算機),你應該會看見新的硬盤
- 打開它並複製所有的 Minecraft 伺服器到這個硬盤裏。
- 像平常一樣啟動你的伺服器,只不過現在是從剛剛建立的虛擬硬盤啟動 - 你現在就能啟動和執行了!
你的虛擬硬盤現在會在關機時自動儲存,並在開機時自動載入。你會注意到開機/關機的時間更長了,而增加的時間取決於你設定的尺寸。
同時,你可能希望調整 AutoSave (自動儲存)間隔。
如果你沒有選擇「Save Disk Image on Shutdown」,繼續看下去!
你需要在'每次'關閉計算機時完成下列步驟,否則數據就會丟失!
- 手動停止虛擬硬盤(在關閉計算機之前)
- 如果你的 Minecraft 伺服器正在執行,停止它
- 打開 Dataram RAMDisk configuration Utility(再次)
- 在 Load/save 頁籤開啟「Load Disk Image on Startup」
- 點擊「Save disk image now」
- 點擊「Stop RAMDisk」
- (如果你希望再次啟動伺服器,按照你第一次啟動伺服器的操作去做。如果你勾選了「Load Disk Image at Startup」才能做這個)
- 備選方法:
- 停止你的伺服器
- 複製虛擬硬盤裏的所有檔案到硬盤驅動器的一個備份資料夾
- 在 Dataram RAMDisk configuration Utility 點擊「Stop RAMDisk」
- (要再次啟動它,按照你第一次啟動虛擬硬盤的操作去做,然後把所有檔案複製到虛擬硬盤裏,然後啟動你的伺服器。)
Mac OS X
在 Mac OS 裡鍵入下列命令來建立你的虛擬硬盤:
diskutil erasevolume HFS+ "ramdisk" `hdiutil attach -nomount ram://1165430`
這隻有一條命令列,而且還很快,很有效果。 :)
如果你跟隨這些操作去做了,你的虛擬硬盤將會出現在 /Volumes/ramdisk。在此之後,按照你在 Linux 那樣做,使用 Terminal 和你喜愛的文字編輯器。
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||