在法国用二手 NUC 跑 Gitea,别把仓库放 USB 硬盘上
去年冬天把一台二手 NUC8i3 装成 Debian 12,跑 Gitea 自用,顺带给两个朋友做私有仓库。机器放家里,Freebox 后面,数据盘一开始图省事插了块旧 USB3 的 2.5 寸 HDD——这就是后面所有麻烦的起点。
场景很小:仓库不到 40 个,其中两个带 LFS 的模型文件,最大的单个 pack 约 1.8G。日常就是 push、pull,偶尔用 Actions 跑个 lint。前两个月没感觉,第三个月开始偶发 fatal: the remote end hung up unexpectedly,重试就好;再后来 Gitea 的 web 界面偶尔转圈,journalctl -u gitea 里能看到 i/o timeout 和 context deadline exceeded。
我先怀疑是 MTU 和 Freebox 的端口转发,改了、没用。真正定位是跑了一次 fio:
fio --name=randwrite --ioengine=libaio --direct=1 \
--bs=4k --size=512M --numjobs=1 --iodepth=16 \
--filename=/mnt/usbdisk/testfile --runtime=60 --time_based
结果在 USB 盘上 4k 随机写只有几百 IOPS,而且延迟尾部拉得很长,--direct=1 下尤其明显。换成 NUC 内部的 SATA SSD 再跑,数字正常。问题不是 Gitea,是 USB 桥接和 UAS 在这种持续小 IO 下的表现。
做法很土:把 /var/lib/gitea 和仓库目录整体迁到内置 SSD,USB 盘只留冷备份。迁移前先停服务,用 rsync 保权限:
systemctl stop gitea
rsync -aHAX --info=progress2 /mnt/usbdisk/gitea/ /var/lib/gitea/
chown -R git:git /var/lib/gitea
systemctl start gitea
/etc/gitea/app.ini 里把 [repository] ROOT 指到新路径,顺手把 LFS_CONTENT_PATH 也改过去,否则 LFS 对象还在旧盘上,push 大文件照样卡。改完 systemctl restart gitea,再 gitea admin 里确认路径生效。
为什么这样取舍:Gitea 的 SQLite 和仓库文件都在同一个目录树下,小 IO 密集,SSD 的随机写延迟比顺序带宽重要得多。USB 盘顺序读写看着能到 100MB/s,但 git 的实际负载不是顺序的。代价是内置盘容量小,冷备份要定期拉走,我现在的做法是每周 rsync 到 USB 盘一次,而不是让它在线上。
会失效的地方:如果仓库量很大、需要多盘,单 SSD 也顶不住,那就得考虑把 LFS 单独挂一块盘,或者干脆用对象存储;另外 NUC 的 SATA 口只有一个,换盘意味着停机。我自己踩过的坑是迁移后忘了改 LFS_CONTENT_PATH,结果 web 端能看到仓库,clone 带 LFS 的仓库却报 404,查了半天才发现是路径没同步。
你们在法国这边自建 Gitea 或 Forgejo 的,仓库目录是放内置盘还是外挂?外挂的话有没有遇到类似的小 IO 抖动?
0 条评论
还没有评论,写下第一条。