MiniSlurm 是一个仅面向 Linux 的轻量级本机资源队列,可以直接嵌入已有脚本。它不负责启动或终止任务;当指定逻辑资源的剩余容量不足时,脚本会阻塞在 queue_lock,获得资源后再继续执行。
queue_lock cuda:0 10 20m
python3 train.py
queue_unlock cuda:0这里的 20m 是预计运行时间,只用于 SJF 排序,不是租约。任务运行超过 20 分钟时,调度器不会终止进程,也不会释放资源。不提供预计时间表示预计运行时间无限。
需要同时获得多个资源时,使用可重复的 --resource NAME=SIZE。整个资源 bundle 是原子的:只有全部资源同时可用时才会授予,否则一个都不占用。
queue_lock \
--resource cuda:0=10 \
--resource cuda:1=10 \
--estimate 20m
python3 train.py
queue_unlock原有单资源命令保持兼容。
完整的产品定义与实现设计参见 docs/plan.md。
需要 Go 1.25 或更高版本。
make test
make build
sudo make install项目会生成四个二进制文件:
queue_schedulerqueue_lockqueue_unlockqueue_status
将配置文件安装到 /etc/minislurm/config.json:
{
"scheduler": {
"policy": "sjf",
"process_check_interval": "2s"
},
"resources": [
{ "name": "cuda:0", "budget": 20 },
{ "name": "cuda:1", "budget": 20 }
]
}policy 可以是 sjf 或 fcfs。时间使用 Go duration 格式,例如 30s、20m、2h 或 48h。
作为 systemd 系统服务运行:
sudo groupadd --system minislurm
sudo usermod -aG minislurm "$USER"
sudo install -D -m 0644 packaging/minislurm.service /etc/systemd/system/minislurm.service
sudo systemctl daemon-reload
sudo systemctl enable --now minislurm将当前用户加入 minislurm 组后,需要退出并重新登录,新的组权限才会生效。
不安装、仅在本地测试:
tmpdir="$(mktemp -d)"
bin/queue_scheduler \
--config examples/config.json \
--data-dir "$tmpdir/data" \
--socket "$tmpdir/minislurm.sock" \
--lock-file "$tmpdir/minislurm.lock"客户端需要使用同一个 Unix socket:
bin/queue_lock --socket "$tmpdir/minislurm.sock" cuda:0 10 20m
bin/queue_status --socket "$tmpdir/minislurm.sock"
bin/queue_unlock --socket "$tmpdir/minislurm.sock" cuda:0queue_lock 会向 STDOUT 输出申请参数、当前资源状态、排队位置和最终获锁结果,例如:
queue_lock: 申请资源 resources=cuda:0=10 estimated=20m0s owner_pid=1234
queue_lock: 当前状态 resource=cuda:0 requested=10 used=20 budget=20 available=0 queue_position=2
queue_lock: 已获取资源锁 resources=cuda:0=10
queue_lock: 获取后状态 resource=cuda:0 used=20 budget=20 available=0
如果连接在排队期间中断,queue_lock 会输出重连日志,并使用同一个 request ID 继续等待。
默认情况下,客户端把资源锁归属于自己的父进程。在 shell 脚本中,owner 是运行脚本的 shell,而不是短暂存在的 queue_lock 进程。调度器会同时记录 PID、UID 和 Linux 进程启动时间,避免 PID 重用导致错误释放或错误持有。
不要让 owner shell 在后台任务仍然运行时提前退出:
queue_lock cuda:0 10 1h
python3 train.py &
wait对于特殊的进程树,可以使用 --pid PID 显式指定 owner。
每个已授予的 allocation 都对应 /var/lib/minislurm/lockfiles 下的一个不可变锁文件。创建文件表示授予资源,删除文件表示释放资源。恢复所需的关键字段编码在文件路径中,因此即使锁文件内可选的 JSON 内容损坏,调度器仍能恢复正确的资源占用量。
多资源 bundle 仍然只对应一个锁文件,文件路径同时编码 bundle 中的全部资源和容量,因此创建和删除动作不会产生部分持有状态。对 bundle 中任意资源执行 queue_unlock RESOURCE_NAME 会释放整个 bundle;不带资源名的 queue_unlock 会释放 owner 的全部 allocation。
每个等待请求分别存储在 /var/lib/minislurm/requests 下。MiniSlurm 不需要数据库,也不依赖中央状态 JSON。
go test ./...
go test -race ./...
go vet ./.../proc、Unix peer credentials 和端到端 socket 测试需要在 Linux 上运行。