Tutorials/Ramdisk enabled server

This tutorial is intended to give you a basic understanding of what a ramdisk is, what use it is for Minecraft and how to make a Minecraft server use a ramdisk.

Ramdisk Introduction
Conventionally, files and directories are stored on hard disk drives which, by today's standards, offer a lot of space at mediocre data transfer rates (between 8MB/s and 20MB/s). Ramdisks are virtual file systems (unlike HDDs which are hardware) that live completely inside the computer's RAM. They offer significantly higher data transfer rates (between 30,000MB/s and 150,000MB/s) at the cost of volatility (data will be lost after restarting the computer) and space (limited by the amount of RAM installed on the system, including swap space). Many utilities however make it possible to backup Ramdisk data at set intervals, and before the system is shut down, then load the last data when the system starts up.

Advantages

 * Very high transfer speed (data to application)
 * Very low seek time (searching between and in files)

Disadvantages

 * Ramdisks will be cleared when a system restarts
 * Unfeasible if the world size exceeds the available RAM

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 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.

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. mount -t tmpfs none /home/username/minecraft_ramdisk -o size=512m
 * 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:
 * Restart your computer. The ramdisk will now be loaded every time you restart. If you wish to load immediately, type

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.


 * 1) !/bin/bash
 * 2) /etc/init.d/minecraft
 * 3) version 0.6 2012-02-25 (YYYY-MM-DD)


 * 1) BEGIN INIT INFO
 * 2) Provides:   minecraft
 * 3) Required-Start: $local_fs $remote_fs
 * 4) Required-Stop:  $local_fs $remote_fs
 * 5) Should-Start:   $network
 * 6) Should-Stop:    $network
 * 7) Default-Start:  2 3 4 5
 * 8) Default-Stop:   0 1 6
 * 9) Short-Description:    Minecraft server
 * 10) Description:    Starts the minecraft server
 * 11) END INIT INFO

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
 * 1) Settings

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\ | 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 }

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
 * 1) Start-Stop here

mv /directory/wherefileis/filename /etc/init.d/minecraft chmod a+x /etc/init.d/minecraft
 * Move this script into your /etc/init.d/ directory, and make it executable:

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 $MCPATH/ $MCSTORE/"

in case you want to do other things, such as remote copying, but performance differences are probably negligible unless you have very big worlds.

sudo crontab -e Then add the line: 20 */6 * * * /etc/init.d/minecraft backup
 * 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
 * /5 * * * * /etc/init.d/minecraft disksaverun

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

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)


 * 1) !/bin/sh

VOLATILE="/home/$USER/minecraft_server/world/" PERMANENT="/home/$USER/minecraft_server/world_storage/"

rsync -r -t -v "$VOLATILE" "$PERMANENT"
 * 1) TODO: Check if both directories actually exist, skipped here for clearness

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//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 mkdir /dev/shm/minecraft mkdir /dev/shm/minecraft/world
 * 1) !/bin/sh
 * 2) remake the paths

VOLATILE="/home/$USER/minecraft_server/world/" PERMANENT="/home/$USER/minecraft_server/world_storage/"

rsync -r -t -v "$PERMANENT" "$VOLATILE"
 * 1) TODO: Check if both directories actually exist, skipped here for clearness
 * 2) reversed the order

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 tool like Dataram RAMDisk to create a RAM disk and place the server files on it. It has the option to automatically save an image every time it shuts down and also every few minutes. Remember to format your new Ramdisk once it's created! Search the Internet for some ways to save your RAMDisk in case it does not work. REMEMBER: Always have a backup! Also remember to allocate enough RAM for your RAMDisk, make sure to have more memory in your RAMDisk than those in your Minecraft Server folder (Or whatever you call it)!

'''Here are the steps: '''

1.Download and install Dataram RAMDisk (Obviously)

2.Set the type of RAMDisk to unformatted

3.Set your disk size (Not recommended to set max)

4.Go under the Load/Save tab and tick all three RAMDisk saving method (If you have enough memory in C Drive)

5.Start your RAMDisk - Click 'Start RAMDisk'

6.Go to your 'Start' window and search for 'Create and format hard disk partitions'

7.You should see a disk that is unallocated (Black)

8.Select it by right clicking it

9.Now right click it and click New simple volume

10.Finish the wizard (Configure it yourself!)

11.Now go to your 'Computer' and you should see a new disk

12.Open it and copy all your Minecraft Server files in it.

13.Start your server as normal and you are done!

'''To shut down RAMDisk/Computer: '''

1.Open Dataram RAMDisk configuration Utility again (After stopping your server)

2.Click 'Save disk image now' under the Load/save tab

3.Click stop RAMDisk

(If you want to enable it again,just start it like you did the first time. Only do this IF you ticked 'Load disk image at startup')

Alternative to shutdown:

1.Stop your server

2.Copy all the files in the RAMDisk and paste them on a backup file in a hard disk

3.Click 'Stop RAMDisk' on the Dataram RAMDisk configuration Utility

4.Done!

(To start it again,start your RAMDisk like you did the first time and copy all the server files into the RAMDisk and start your server)

You need to have at least 4G of RAM to make a RAMDisk properly!

(If you have at least 4G of RAM, the server should be like around this)

Happy RAMDisking!

Mac OS X
Type this 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.

Tutoriels/Sauvegarder vos donnés de cartes sur un RAM-disque