This one trick will change the way you start a minecraft server forever!
Clickbait titles are fun. Video games are even more fun. And minecraft takes the cake; it provides relaxation whilst at the same time providing me with countless hours of funny footage of my two boys getting the living daylights scared out of them every time a creeper manages to sneak up on them. I'm sure their nightmares have nothing to do with it. It's fine. They're fine.
If you've never played minecraft, or modded minecraft, you're in for a treat! But running a decent home server, however, is a lot more complicated then you'd think until you "MaSTerEd tHis oNe Trick".
Minecraft is a simple java program
As such booting the minecraft server is 'just' a matter of just running java -jar -Xmx4G -Xms4G -nogui server.jar
. Provided your port 25565 is open, you now have a running, vanilla, minecraft server consuming up to 4G of RAM.
Pretty soon you notice that lagspikes rear their ugly head once there are a couple of people playing. When someone changes dimension, for example. Or when someone propels him or herself forward with mach 5 into yet-unknown territory using fireworks rockets and wings.
But being a java game that's packaged in a single jar file, we can't really optimize anything within the game itself without resorting to replacing the base jarfile with an alternative server altogether – something which we should discuss in another article.
Once you run the server jar file on a intricately monitored VM however, the reason for the lag spikes becomes painfully apparent. The entire process is extremely disk IOPS heavy when it comes to world generation. Even a normal SATA SSD can't keep up when multiple players are generating new parts of the world.
Thinking outside the box
The box, in this case, being the jar file. How can we increase the I/O throughput of our disk without resorting to buying an NVME drive just for our minecraft server?
Well, young 'un - in my days there was this book about DOS which described to my this mythical device called a RAM drive. It was something that was created by mounting a virtual floppy disk, but was actually located in one of the fastest parts of your computer – the RAM.
Lucky us, we can reproduce that quite easily with any modern linux distribution.
Create a directory to mount your ramdrive to.
sudo mkdir /mnt/ramdrive
Mount the ramdrive, specifying the size. Make sure this will fit your world and your player data. I my case I have a world that's about 530Mb in size, so I'm betting on the safe side and just assign 2 Gibibytes of memory to the drive itself.
sudo mount -t tmpfs -o size=2G tmpfs /mnt/ramdrive
Now we copy the entire minecraft server onto the drive...
cp -R ~/minecraft-server /mnt/ramdrive
And start the server. Devops-linux-guru-tmux style.
cd /mnt/ramdrive/minecraft-server
tmux new-session -d -s minecraft
tmux send-keys 'java -Xmx1024M -Xms1024M -jar server.jar nogui' C-m
And voila. Minecraft is running in a tmux session named minecraft.
The catch
Memory, or RAM, is volatile. This means it'll catch fire at the drop of a hat. And when it does, you'll lose all your precious minecraft bits and bytes forever! Now, being the shrewd devops-person you are, you've already dealt with volatility.
Right? Right! The hypetrain calls it "ephemeral". Spooky sounding word, I know, but it's not as scary as it sounds. You see, we call it ephemeral when dealing with containers because when the container stops the storage disappears – it evaporates from this existence.
If your computer, or server, were one big container and you'd turn it off – well then I guess we can say everything stored in it's RAM will evaporate from existence as well, right? So for the sake of this argument let's just say "ephemeral" and "volatile" mean the same thing. One scary-ass flaming ghost-floppy of storage.
So we need a way to make sure our precious bits don't evaporate. We need some kind of script that copies all of our bytes back to this plane of existence. Good ole tape drives. Or hard drives. Or SSD's. Whatever tickles your fancy
Putting it all together
So, to recap, here are the steps you need for a pretty dang fast minecraft server which doesn't bottleneck at the drop of a pin:
- create a ramdisk that's large enough to hold your world
- ensure that you have enough ram left to actually run the game
- copy the entire game onto the ramdisk
- start the game from the ramdisk
- copy all the bits from the ramdisk back to your harddisk at your desired backup interval.
Wait.. all the bits? Haha no, I'm just kidding. We're devops people and we know the linux. Of course we'll just use rsync
and only copy bits that have changed. Or as we the linux people like to call it "the delta: Δ".
This way, when we back our entire world up, we'll have blazingly fast reads from our memory and -even though we don't care about this as much- very fast writes because we're only copying a minimal amount of data.
So fire up your crontab and chuck this in at your desired interval:
tmux send-keys -t minecraft.0 'save-all' ENTER \
&& sleep 1 \
&& rsync -azP /mnt/ramdrive/minecraft-server/ /home/yourname/minecraft-server
The 'save-all' forces a 'dump to disk' - which in our case is a 'dump from memory to memory. After which we use rsync
to transfer the ramdrive's content - or at least the bits that differ - from the ramdrive back to our original drive.
In conclusion
Hope this helps you set up a server which provides a decent experience to you and your friends. In the next post I will be discussing scaling out a minecraft server. As you might imagine the vanilla jarfile-server benefits greatly from vertical scaling, but can't really be horizontally scaled.
There are solutions to this, however, so stay tuned and share, like, subscribe, comment, tweet, toot, recommend and do whatever it is you crazy social kids do these days.
Yours truly,
Tom Herder
P.S.
Check out github for my start.sh, stop.sh and backup.sh scripts which you can use to launch it in a truly stylish, all-be-it somewhat ghetto, way.