
更好的自动保存
为Forge 1.20.1服务器的异步世界保存——将区块、实体和已保存数据的序列化移出主线程。消除自动保存造成的卡顿。
BetterAutoSave

让服务器自动保存不再卡顿 ~ 本模组部分代码由 Claude Opus 4.8 / Claude Fable 5 生成。如果遇到任何问题,请提交 issue
本模组解决什么问题
原版 Minecraft 服务器每 5 分钟自动保存一次。保存时,主线程必须序列化每个已修改的区块并将其写入磁盘——在此期间整个服务器都会冻结。在空载服务器上你可能注意不到,但在安装大量模组和多名玩家的服务器上,这种暂停通常为 200 毫秒到数秒不等,并且所有玩家会同时卡顿。
除了定期自动保存外,以下几种情况也会导致同样的卡顿:
- 玩家传送,或大量区块被卸载(区块在离开内存前必须保存)
- 保存时实体密集的区域(大型农场 / 刷怪塔)——逐个保存实体会增加额外的停顿
- 村庄、袭击以及某些模组数据(如 MTR 的列车数据)写入磁盘——单个大文件可能导致 50-200 毫秒的停滞
BAS 将整个保存过程移到后台线程。主线程只执行一项必须同步进行的操作——拍摄待保存数据的快照。序列化和磁盘 I/O 都交由后台处理。卡顿基本消失。
需求
- Minecraft 1.20.1
- Forge 47.3.22 或更新版本(47.3 / 47.4 系列均可)
- Java 17 或更新版本
- 仅服务端安装,客户端无需安装
安装
将 shinoyuki_betterautosave-0.11.0.jar 放入服务器的 mods/ 文件夹并启动。首次启动后,配置文件将生成在:
config/Shinoyuki-Optimize/shinoyuki_betterautosave/common.toml
默认配置开箱即用;大多数服务器无需修改任何内容。
会丢失世界数据吗?
不会。BAS 的设计前提是:绝对不能比原版更不安全。
- 关闭服务器时,它会等待所有待处理的保存写入磁盘后才允许服务器退出。
- 关闭时的最终保存会走原版同步路径,与未安装 BAS 时完全一致。
- BAS 绝不会“推迟保存”——区块一旦需要保存,立即进入后台处理。不会出现“几分钟未保存,崩溃导致全部丢失”的时间窗口(一些类似模组存在此问题,详见下方兼容性说明)。
- 如果后台写入失败,它会自动重试;重试耗尽后,会回退到原版同步写入,而非假装成功。
工作原理(可选阅读)
原版保存卡顿是因为两个繁重任务都放在主线程上:将世界数据序列化为保存格式,以及将序列化后的数据写入磁盘。
BAS 让主线程只做快照——将区块当前的方块、光照、方块实体等复制到一个独立副本中。这一步很快,因为它只是复制,不进行格式转换。复制完成后,主线程立即返回运行游戏,同时后台线程对副本进行序列化和磁盘 I/O。
由于后台线程操作的是副本,它们绝不会干扰主线程;快照完成后主线程便放手,无需等待写入完成。区块、实体和已保存数据都经过此流水线处理。
当服务器负载较高时,BAS 会自动减速(当 TPS 低于阈值时,每 tick 的快照数减少),但在下一次自动保存周期临近时会强制全速运行,以防止积压。
配置
配置文件位于 config/Shinoyuki-Optimize/shinoyuki_betterautosave/common.toml。常用条目:
| 键 | 默认值 | 描述 |
|---|---|---|
| general.enabled | true | 总开关;关闭则恢复原版行为,如同未安装 |
| throttle.chunksPerTickBase | 4 | 主线程每游戏 tick 最多快照的区块数 |
| throttle.adaptiveEnabled | true | 服务器负载高时自动减速;建议保持开启 |
| workers.chunkWorkerThreads | 2 | 处理区块的后台线程数 |
| workers.entityWorkerThreads | 2 | 处理实体的后台线程数 |
| workers.savedDataWorkerThreads | 1 | 处理已保存数据的后台线程数;如果有重型数据模组(如 MTR)可设为 2 |
| compat.eventCompatMode | PARTIAL | 兼容性等级,见下方说明 |
其余条目(重试次数、关闭超时、监控开关等)在配置文件中有注释说明。
兼容性等级:eventCompatMode
少数模组会监听“区块保存”事件。此开关控制 BAS 提供给它们的数据完整性:
- PARTIAL(默认,推荐):性能最佳,99% 的模组无法察觉差异。
- FULL:100% 与原版一致,性能降低一半。仅当某个模组因无法读取区块方块数据而报错时切换至此模式。
- DISABLED:完全不派发该事件;最节省资源,前提是你确定没有模组监听此事件。
不确定时,请保持 PARTIAL。
游戏内命令(需要 OP 权限)
| 命令 | 效果 |
|---|---|
/betterautosave status |
一行显示当前状态 |
/betterautosave metrics |
一行指标摘要 |
/betterautosave debug |
完整诊断信息:队列深度、各阶段耗时、计数器 |
/betterautosave flush |
立即同步刷新所有待处理的保存到磁盘 |
/betterautosave drain-unload |
在关闭前手动等待所有待处理区块落地 |
/betterautosave hottest-chunks [count] |
列出保存最慢的区块(默认 10,最多 50),用于定位热点 |
/betterautosave force-async |
强制对当前维度所有区块执行一次后台保存(诊断用途) |
监控(v0.9,可选)
v0.9 添加了两个诊断工具,让你无需外部分析器即可查看保存性能。
hottest-chunks 命令列出按保存时间降序排列的最慢区块:
/betterautosave hottest-chunks 20
高耗时区块通常位于方块实体密集的区域——大型自动化农场、模组商店面板、复杂红石。一旦知道精确位置,可以直接进行优化。
Prometheus 指标端点(默认关闭)会在配置的端口上提供 /metrics 页面。接入 Grafana 后可获得长期保存性能趋势,比反复运行 /betterautosave debug 方便得多。在配置中启用:
[prometheus]
enabled = true
port = 9450
安全提示:端口默认监听 0.0.0.0。在公共服务器(云 / VPS)上,请使用防火墙限制端口 9450,或将 bindAddress 设置为 127.0.0.1 以仅允许本地连接。指标不包含玩家隐私信息,但会暴露服务器的活动模式。
模组冲突
- Smooth Chunk Save:二选一。两者都修改了区块卸载保存路径。相比之下,BAS 不会延迟磁盘写入(无数据丢失窗口),不会取消原版定期自动保存,也不会吞掉异常。
- C2ME-Forge:接管了与 BAS 相同的保存路径;同时安装意味着重复处理,请二选一。该模组已不再维护,因此实际中重叠情况应该很少。
- Lithium 移植版(Radium / Canary)、Starlight Forge:兼容。
- 其他也涉及区块保存的模组:它们有时可能导致 BAS 接管失败,此时 BAS 会自动回退到原版处理——数据安全不受影响,只是会损失部分性能收益。
完整兼容性矩阵请参见 ROADMAP(中文)。
出问题时的快速恢复
以下三种方式均可保持世界数据完整:
- 临时禁用:在配置中将
general.enabled设为false,重启或使用/reload。模组仍然安装,但所有逻辑被跳过——完全原版。 - 完全卸载:将 jar 移出
mods/文件夹并重启。世界数据受原版保存保护;卸载不会丢失任何内容。 - 调优而非移除:如果你怀疑是性能设置问题,可以先调整
chunksPerTickBase(范围 1-64)或将eventCompatMode切换为FULL——无需卸载。
构建 / 开发
./gradlew build # 编译 + 运行测试
./gradlew runServer # 启动开发服务器
技术深入分析、生态研究、完整兼容性矩阵及版本路线图请参见 ROADMAP.md(中文)。
许可证
请参阅 LICENSE 文件。
正在加载版本记录…
正在加载评论…
评论在新手盒子客户端中发表,这里同步展示。