
[观前提示] 这个笨蛋up主配置虚拟机时忘记把CPU类别改成host,因此下文虚拟机的数据都在CPU类别为kvm64的情况下测得,得出的结论也只适用于kvm64。后续我改成host重测了一遍,你可以前往容器与虚拟化(host)阅读。
这次测试的目的是探索Minecraft服务端在宿主机、LXC容器与虚拟机中运行时的性能。
一、测试环境
本次测试的硬件配置与红蓝对决中的蓝方相同。
软件方面分为四组:
①宿主机,或称物理机。操作系统为 Proxmox VE 7.4-16,服务端直接运行在宿主机上,不包含虚拟化。
②LXC容器。使用 Debian 12.0-1 的容器模板,服务端运行在容器中。
③虚拟机(12线程)。操作系统为 Debian 12.0-1,服务端运行在虚拟机中。虚拟机可以占用CPU的所有12个线程。
④虚拟机(6线程)。操作系统为 Debian 12.0-1,服务端运行在虚拟机中。虚拟机可以占用CPU的6个线程,这6个线程分别属于6个物理核心,可以不严谨地认为在虚拟化中关闭了超线程。

图1 分配6个线程的方式
此外,Java 版本更新为 17.0.8,其他均与红蓝对决中相同。
下面说明一下设置6线程虚拟机的原因:
超线程在宿主机上能以正确的方式被识别和调用,但分配给虚拟机时,虚拟机可能无法认识到哪两个线程来自同一物理核心,因此在涉及多核计算时无法正确地调用。后面的数据将验证这一猜测。
红蓝对决中也对读者可能产生的一些问题做了说明。
二、测试项目
与红蓝对决中的项目相同,但取消了活塞测试,因为其数据不稳定。后续补测了改进的活塞测试(也是在这时才发现CPU类别是kvm64)。

图2 改进的活塞测试
三、测试流程
每次测试的流程与红蓝对决中相同,这样的流程重复了20次。第1、5、9、13、17次是宿主机测试,第2、6、10、14、18次是LXC容器测试,第3、7、11、15、19次是虚拟机(12线程)测试,第4、8、12、16、20次是虚拟机(6线程)测试。目的也同样是排除偶然因素、获取能相互验证的测试结果。
补测的活塞测试是单独进行的,其他方面同上。
四、测试结果
测试得到的数据如下。

图3 测试数据
对数据做可视化。

图4 mspt(绝对值)最大值、均值和最小值,越小越好
将每项测试的数据除以宿主机平均值得到相对值。

图5 mspt(绝对值)最大值、均值和最小值,越小越好
另外截取了宿主机测试时的CPU占用图形。

图6 CPU占用
图6中占用8%-9%的一大段对应前三项测试,这是(12线程处理器)单线程满载的典型特征。后面超出单线程满载的部分对应TNT测试,说明这项测试中服务端调用了更多线程。
图6不包含活塞测试的部分,但活塞测试中的CPU占用也高于20%,说明服务端也调用了更多线程。TNT与活塞测试中都有大量的光照更新,而前三项测试没有光照更新,考虑到光照更新是独立于主线程的,可以推断这种超出一个线程的占用主要由光照更新导致。
五、总结
通过图4、图5不难看出,TNT和活塞测试中虚拟机(6线程)明显优于虚拟机(12线程),这两组在前三项测试中基本持平。考虑到前述的多线程调用情况,这些现象有力地验证了之前的猜测:虚拟机不能正确识别和调用超线程,因此只分配每个核心的一个线程给虚拟机能取得更大性能优势。
此外,虚拟机相比于LXC容器在性能上更接近宿主机。尤其在村民测试中,虚拟机的性能甚至优于宿主机,这种差异可能是由操作系统不同导致的。尽管虚拟机本身也运行在PVE中,但其面向Minecraft服务端的操作系统是Debian。
虚拟机和LXC容器的表现互有胜负。前四项测试中虚拟机(6线程)均优于LXC容器,在村民测试中虚拟机(6线程)甚至略优于宿主机,但在活塞测试中,情况发生了反转。在容器与虚拟化(host)的活塞测试中,虚拟机的性能衰减远没有这么严重,因此这一情况主要与CPU类别有关。