警告

成都服务器托管,创新互联提供包括服务器租用、达州电信机房、带宽租用、云主机、机柜租用、主机租用托管、CDN网站加速、域名申请等业务的一体化完整服务。电话咨询:028-86922220
因为这是Wiki的一个条目,可以在任何时间内被任何人编辑,因此建议你不要完全使用这个脚本,而是将其当作编写脚本的指导手册看待。
该教程向你大概描述什么是虚拟硬盘,怎样和 Minecraft 使用,以及如何设置一个虚拟硬盘服务器。
传统上,文件和文件夹储存在硬盘驱动器,但以今天的标准来看,普通数据的传输速度(80MB/秒 到 200MB/秒之间)的提升空间还很大。虚拟硬盘是一个虚拟的文件系统(不像硬盘那样是硬件),会把文件数据完全实时储存在计算机内存条里。它们的普通数据传输速度(3000MB/秒 到 15000MB/秒之间)非常高,但会失去稳定性(重启电脑数据就会丢失)以及空间(受系统安装内存条的数量限制,包括交换空间)。然而,有许多实用工具可以每隔一段时间备份虚拟硬盘里面的数据,以及在关机前备份,然后在系统启动时加载上次保存的数据。
在一个 Minecraft 服务器,最大的一个瓶颈是相关的磁盘 I/O 操作(如区块管理)。通过向内存移动数据,访问时间会被大大缩减,数据传输速度也会大大提高,让区块加载和保存区块操作变得更快。因为一个 Minecraft 世界包含了许多区块文件,寻道时间没多大变化,因为重要的是整体速度。
确保在开始前备份了你的文件!
2011年3月12日,在 Aimless Bits 的博客里,发布了把一个 Minecraft 服务器加载到虚拟硬盘的简单方法。它包含了修改过的 Wiki 脚本,以及一些小更改。本指南充实了这一过程,并在 Aimless Bits 的脚本里做了一些小更改。
这个快速指南假设你已为加载 Minecraft 设定了一个用户、Minecraft 目录和运行中的服务器。你最好熟悉 /etc/init.d/minecraft 启动脚本。
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\ | 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
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/"
欲自动备份,这样做:
sudo crontab -e
然后添加下面2行:
*/5 * * * * /etc/init.d/minecraft disksaverun 20 */6 * * * /etc/init.d/minecraft backup
数字代表每隔多少分钟就保存世界,如果你有高容错的设置、备用电源等等,可以不那么频繁。否则坚持至少每五分钟备份一次!
第二行让 Minecraft 每隔6小时备份一次(运行backup函数),并且固定在:20时进行备份。不要跳过备份!这是最后一次警告!
但愿这能够对管理员有帮助,祝你好运!
在多数的 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//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 里。如果你知道如何做,那么你可以把这个添加到启动脚本中。
这是上述备选方案的一个快速却粗糙(效果完全相同)的版本。这个技巧在架设于Fedora的服务器上效果良好。
首先定位至服务器工作路径并备份现存世界。
cp -r world/ world_storage/
要使用这个方法,我们需要目录名为“world”,因此从工作路径中删除world/
rm world/ -rf
现在,我们需要将服务器的世界目录重定向至共享内存中。在crontab中输入一行命令即可。
*/5 * * * * rsync -r -t -v /dev/shm/world/ /path_to_minecraft/world_storage/
现在我们需要将世界“挂载”至共享内存中。新建 start.sh 文件,输入以下两行:
cp /path_to_minecraft/world_storage/ /dev/shm/world/ -r rsync -r -t -v /dev/shm/world/ /path_to_minecraft/world_storage/
每次重启服务器时,都可以使用 start.sh 将世界挂载至共享内存,其后你就可以正常启动服务器(方便起见也可以直接在 start.sh 中加上一行命令)。如果你希望在运行 start.sh 启动服务器并且使用screen命令,请一定用screen命令运行 start.sh。不要在脚本中使用screen命令,否则服务器将在后台运行而你将不能执行控制台命令。
使用一个像 Dataram RAMDisk(下载免费的版本)之类的虚拟硬盘实用工具来在内存中创建一个磁盘,并将服务器文件放进里面。 Dataram RAMDisk 提供了在其关闭的时候或隔几分钟自动保存图像的选项。
开始之前:
设置你的虚拟硬盘(简单用法)
你的虚拟硬盘现在会在关机时自动保存,并在开机时自动加载。你会注意到开机/关机的时间更长了,而增加的时间取决于你设置的尺寸。
同时,你可能希望调整 AutoSave (自动保存)间隔。
如果你没有选择“Save Disk Image on Shutdown”,继续看下去!
你需要在'每次'关闭计算机时完成下列步骤,否则数据就会丢失!
在 Mac OS 里键入下列命令来创建你的虚拟硬盘:
diskutil erasevolume HFS+ "ramdisk" `hdiutil attach -nomount ram://1165430`
这只有一条命令行,而且还很快,很有效果。 ????
如果你跟随这些操作去做了,你的虚拟硬盘将会出现在 /Volumes/ramdisk。在此之后,按照你在 Linux 那样做,使用 Terminal 和你喜爱的文字编辑器。
教程(作下划线标记的教程为中文独有教程) | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 新手教程 |
| ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 综合 |
| ||||||||||||||
| 农场 | |||||||||||||||
| 方块和物品 |
|
|---|---|
| 生物 |
|
| 基础红石 |
|
|---|---|
| 探测器 |
|
| 矿车 |
|
| 陷阱 |
|
| 活塞 |
|
| 高级红石 |
|
| 使用服务器 |
|
|---|---|
| 架设服务器 |
|
| 地图 |
|
|---|---|
| 资源包 |
|
| 数据包 |
|
| 附加包 |
|
| 制作游戏视频 |
|
| 游戏安装 |
|
| 仅Java版 |
|
| 教程 |
|
|---|---|