你可以幫助我們來翻譯此條目,但請勿使用機器翻譯。
因為這是Wiki的一個條目,可以在任何時間內被任何人編輯,因此建議你不要完全使用這個腳本,而是將其當作編寫腳本的指導手冊看待。
該教學向你大概描述什麼是虛擬硬盤,怎樣和 Minecraft 使用,以及如何設定一個虛擬硬盤伺服器。
虛擬硬盤描述
傳統上,檔案和資料夾儲存在硬盤驅動器,但以今天的標準來看,普通資料的傳輸速度(80MB/秒 到 200MB/秒之間)的提升空間還很大。虛擬硬盤是一個虛擬的檔案系統(不像硬盤那樣是硬件),會把檔案資料完全實時儲存在計算機記憶體條裡。它們的普通資料傳輸速度(3000MB/秒 到 15000MB/秒之間)非常高,但會失去穩定性(重啟電腦資料就會丟失)以及空間(受系統安裝記憶體條的數量限制,包括交換空間)。然而,有許多實用工具可以每隔一段時間備份虛擬硬盤裏面的資料,以及在關機前備份,然後在系統啟動時載入上次儲存的資料。
優點和缺點
優點
- 非常高的傳輸速度(從資料到應用)
- 非常低的尋找時間(在檔案之間搜尋)
缺點
- 在系統重啟時會清除虛擬硬盤的資料
- 如果世界尺寸大於記憶體條可用空間則很難實現
Why it makes sense for Minecraft servers
In a Minecraft server, one of the strongest bottlenecks are disk I/O related operations (e.g. chunk management). By moving the data into the RAM, access times will be near instant and data transfer rates will be significantly faster, making chunk loading and saving much faster operations. Since a Minecraft world currently consists of very many chunk files, seek time is equally, if not more, important for overall speed.
Basic Minecraft and ramdisk setup
Make sure to back up your files before starting!
GNU/Linux (Easy Way)
A simple way to load a minecraft server into a ramdisk was posted on the Aimless Bits blog [1] on March 12, 2011. It involves modifying the server startup script available on the wiki and making some minor changes to fstab. This guide fleshes out the process and makes some minor changes to Aimless Bits' script.
This quick guide assumes you have a user for loading minecraft, a minecraft directory and a server running. It also helps to be familiar with the /etc/init.d/minecraft startup script.
- Firstly, start by creating a directory for the ramdisk in your home directory, i.e. "/home/username/minecraft_ramdisk".
- To mount it as a ramdisk, simply edit your /etc/fstab/ file:
sudo nano /etc/fstab
Then add this line, making sure that the path is correct (username, dir name etc.)
tmpfs /home/username/minecraft_ramdisk tmpfs defaults,size=512m 0 0
The size of the ramdisk MUST be larger than the minecraft directory world. Make sure that you give yourself some overhead.
- Restart your computer. The ramdisk will now be loaded every time you restart. If you wish to load immediately, type
mount -t tmpfs none /home/username/minecraft_ramdisk -o size=512m
It's now a matter of simply running a modified script that loads the files on the drive onto the server, copies them back on a timely basis to prevent data loss, and does backups. Again, this is a modified version of the script found at Aimless Bits.
If you have /etc/init.d/minecraft, delete it or overwrite it with this script. If you don't, make a new text file, call it minecraft, and copy this script into it.
#!/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=http://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
- Move this script into your /etc/init.d/ directory, and make it executable:
mv /directory/wherefileis/filename /etc/init.d/minecraft chmod a+x /etc/init.d/minecraft
Note: This script misses the command option that the other minecraft init script has on this website, http://www.minecraftwiki.net/wiki/Server_startup_script Therefor I rewrote the script with the command code in it, so ramdisk servers can also use th command thing to sync things without having to get another plugin to schedule things: http://pastebin.com/4ynwL2js Hope someone can use this, if they need the command option.
You're almost done! This script behaves exactly like the standard startup script, only that it takes care of loading and maintaining the ramdisk. You can also modify the script to use rsync instead of cp
"rsync -r -t $MCSTORE/ $MCPATH/"
in case you want to do other things, such as remote copying, but performance differences are probably negligible unless you have very big worlds.
- DO NOT SKIP THIS STEP. You need to add a crontab entry to save your world. See below for specific reasons, but you run the risk of losing data if you don't do this. This script has two disk save functions, disksavehalt and disksaverun. Disksavehalt assumes the screen session is closing or backing up, and thus does not disable level saving. Do NOT call this function in crontab. Use disksave run instead. To do this
sudo crontab -e
Then add the line:
*/5 * * * * /etc/init.d/minecraft disksaverun 20 */6 * * * /etc/init.d/minecraft backup
The number represents how often in minutes should you save the world. If you feel like you have a robust setup, power supply backups and the whole shebang, run this less frequently. Otherwise, stick to 5 minutes at the least!
The other line runs minecraft backup every 6 hours, at :20. Don't skimp on backups! You've been warned!
Hope this helps all those would be admins out there. Good luck!
GNU/Linux (alternative)
On most GNU/Linux distributions there is already a ramdisk set up (usually mounted to /dev/shm (shared memory)) which defaults to using at most half of your total installed RAM. If there is not one already set up, resources on how to do it are widely available on the Internet.
It is possible to move anything into the ramdisk, but here I will focus on just moving the map into it and leaving the server files on the conventional drive.
Given the following basic server directory "minecraft_server/", inside a user's home directory, containing the world "world" and all other required files
| ~/minecraft_server/ |
|---|
| world/ |
| minecraft_server.jar |
| server.log |
| server.properties |
| ... |
We will want to move "world/" into the shared memory. Because of the volatility of ramdisks, we will also want to create a new folder into which an automated script will periodically save the current snapshot of the world, called (for example) "world_storage" by copying the current world to a new name
$ cd ~/minecraft_server/ $ cp -r world/ world_storage/
Now with the old world in a safe location, we can go ahead and move the world into the ram-disk
$ mkdir /dev/shm/minecraft $ mv world/ /dev/shm/minecraft
By now, the world is loaded into the RAM, but the Minecraft server doesn't see it in its directory anymore, causing it to recreate it when started. To stop it from doing that, we have to create a symbolic link to the world in the ramdisk by running
$ ln -s /dev/shm/minecraft/world/ .
This will create a link to "/dev/shm/minecraft/world/" called "world/" in the server's directory, which the server will use like the actual world folder, but now inside the RAM.
Now we need to take care of the volatility of the ramdisk, by periodically saving the world from the RAM into "world_storage/". I'm going to use cron for scheduling and rsync for synching here.
First, we need a script that can be called by cron (it doesn't have to be a script, you could call rsync directly from the cron command line, but this allows for easy customizing later on)
#!/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"
And then we need to make this script execute every few minutes (I'll use 5 minutes here, you can test out what works best for you)
$ crontab -e
You will be put into an editor (more precisely: the editor in your "EDITOR" environment variable) for editing your user cron table. Add the following line:
*/5 * * * * bash /home/<your_username>/minecraft_server/save_world.sh &>/dev/null
Now if your server restarts you will need to recreate the world folder (/dev/shm/minecraft) then (/dev/shm/minecraft/world) in the shared memory because the /dev/shm/ empties after restart,. You can do this by making another similar shell script.
So make a shell script file like before:
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"
Everytime you restart you need to run this script to remount the Ramdisk. Do not add this to the crontab. You can add this to the start up if you figure it out.
Windows
Use a Ramdisk utility like Dataram RAMDisk (freeware version available) to create a RAM disk and place the server files on it. Dataram RAMDisk has the option to automatically save an image every time it shuts down and also every few minutes.
Before you begin:
- At least 4G of RAM on your machine is ideal
- Enabling "Save Disk Image on Shutdown" will impact your Windows shutdown times where you leave RAMDisk running on shutdown, and similarly startup times for "Load Disk Image on Startup". This is not a problem if you manually start and stop the server only when needed.
- Search the Internet for some ways to save your RAMDisk in case it does not work.
- FAT16 is generally faster than FAT32 on RAM disks, however FAT16 formatting is not available for partitions over 2048MB
- REMEMBER: Always have a backup! If your computer crashes, any data on the RAM disk that has not been backed-up/copied to your hard drive will be lost!
- Make sure that you allocate more than enough memory for the RAM disk than that of the size of your 'Minecraft Server' folder - remember that the Minecraft world data can increase by a lot!
- ...and on the other hand, don't leave too little RAM remaining for the running of Windows and the server itself.
Setting up your RAM disk (Simple usage)
- Download and install Dataram RAMDisk
- Set your disk size (Setting the maximum is not recommended)
- If the disk size you set was 2048MB or less, choose 'FAT16 Partition', otherwise choose 'FAT32 Partition' (Advanced users may wish to select 'unformatted' and format the disk themselves)
- Go under the Load/Save tab and select all three RAMDisk saving methods ("AutoSave", "Save Disk Image on Shutdown" and "Load Disk Image on Startup")
- Start your RAMDisk - Click 'Start RAMDisk'
- Now go to 'My Computer' and you should see a new disk
- Open it and copy all your Minecraft Server files in it.
- Start your server per usual, now from the RAM disk you have just created - you are now up and running!
Your RAM disk will now automatically save upon shutdown, and will be restored (with data intact) on startup. Depending on the size you set, you will notice longer boot/shutdown times. Also, you may wish to adjust the AutoSave interval.
If you did not select "Save Disk Image on Shutdown", make sure continue reading especially!!
You need to follow these procedures every time you shutdown the computer to avoid data loss!
- Stopping the RAM disk manually (Before shutting down computer)
- Stop your Minecraft server if it is running
- Open the Dataram RAMDisk configuration Utility (again)
- Please enable "Load Disk Image on Startup" if not already under the Load/save tab
- Click 'Save disk image now'
- Click 'Stop RAMDisk'
- (When you wish to start the server next time, just start it like you did the first time. Only do this IF you ticked 'Load Disk Image at Startup')
- Alternative:
- Stop your server
- Copy all the files in the RAMDisk to a backup folder in a hard disk
- Click 'Stop RAMDisk' on the Dataram RAMDisk configuration Utility
- (To start it again, start your RAMDisk like you did the first time and copy all the server files into the RAMDisk, then start your server)
Mac OS X
Type this to create your RAM disk on Mac OS:
diskutil erasevolume HFS+ "ramdisk" `hdiutil attach -nomount ram://1165430`
It's only one command line to write, quite fast and efficient. :)
If you've followed these instructions, your RAM Disk will be available in /Volumes/ramdisk. After that, proceed as if you were on Linux, using Terminal and your favorite text editor.
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||