ARTICLE DETAIL

建站实战干货

来自一线的建站与推广经验沉淀,每一条都经过真实交付验证。

JuiceFS 文件系统状态检查与数据完整性维护实战:status、info、gc、fsck、compact 命令全解

2026/9/14 10:48:29 拓冰建站 浏览量
JuiceFS 文件系统状态检查与数据完整性维护实战:status、info、gc、fsck、compact 命令全解 JuiceFS 文件系统状态检查与数据完整性维护实战status、info、gc、fsck、compact 命令全解【免费下载链接】juicefsJuiceFS is a distributed POSIX file system built on top of Redis and S3.项目地址: https://gitcode.com/GitHub_Trending/ju/juicefs任何存储系统上线后都需要定期检查与维护以便及时发现并修复潜在问题保障文件系统可靠性与数据完整性。JuiceFS 提供了一组检查与维护工具juicefs status用于查看卷配置与活跃会话juicefs info用于查看文件/目录的元数据及对象映射juicefs gc用于扫描并清理对象存储中的泄漏对象juicefs fsck用于逐块核对元数据与数据块的一致性juicefs compact用于合并覆盖写产生的碎片化数据。读完本文你将掌握这五个命令的完整用法、关键参数与底层实现原理并能够独立完成生产环境的日常巡检与数据完整性修复。一、status查看卷配置与活跃会话juicefs status命令会展示 JuiceFS 文件系统的基本信息以及所有活跃会话的状态包括 FUSE 挂载、SDK 访问、S3 Gateway 和 WebDAV 连接。基本信息涵盖卷名Name、UUID、存储类型Storage、Bucket 地址和回收站Trash配置等。基本用法如下参数为元数据引擎地址juicefs status redis://xxx.cache.amazonaws.com:6379/1输出为 JSON 格式包含Setting卷配置和Sessions活跃会话列表两个部分{ Setting: { Name: myjfs, UUID: 6b0452fc-0502-404c-b163-c9ab577ec766, Storage: s3, Bucket: https://xxx.s3.amazonaws.com, AccessKey: xxx, SecretKey: removed, BlockSize: 4096, Compression: none, TrashDays: 1, MetaVersion: 1 }, Sessions: [ { Sid: 2, Heartbeat: 2021-08-23T16:47:5908:00, Version: 1.0.02022-08-08.cf0c269, Hostname: ubuntu-s-1vcpu-1gb-sgp1-01, MountPoint: /home/herald/mnt, ProcessID: 2869146 } ] }需要注意的是SecretKey等敏感字段在输出中会被脱敏为removed。这一行为来自源码status 实现 调用 meta.Status 获取卷配置后会先执行format.RemoveSecret()再输出避免密钥泄露到终端或日志。查看单个会话的详细信息通过--session, -s选项指定某个会话的Sid可以查看该会话的更详细信息juicefs status --session 2 redis://xxx.cache.amazonaws.com:6379/1{ Sid: 2, Heartbeat: 2021-08-23T16:47:5908:00, Version: 1.0.02022-08-08.cf0c269, Hostname: ubuntu-s-1vcpu-1gb-sgp1-01, MountPoint: /home/herald/mnt, ProcessID: 2869146 }会话处于不同状态时详细信息中还可能包含以下三类字段Sustained inodes已被删除但仍在当前会话中保持打开的文件这些 inode 会临时保留直到文件关闭Flocks该会话持有的 BSD 锁flock信息Plocks该会话持有的 POSIX 锁fcntl/flock 记录信息。从源码结构看这些字段定义在 Session 结构体 中Sustained []Ino、Flocks []Flock、Plocks []Plock均带有json:,omitempty标签因此只有确实存在对应资源时才会出现在输出里。Redis 元数据引擎会在 redis.go 的 GetSession 流程 中从锁键值中还原这些锁信息SQL 引擎则在 sql.go 中从锁表读取。此外status命令还支持--more, -m选项见 cmd/status.go它会额外扫描并输出回收站Trash Files / Trash Slices和待删除数据Pending Deleted Files / Slices的数量与容量统计。由于需要遍历已删除对象在数据量大时耗时较长对应 meta.Status 中 trash 分支 的扫描逻辑。还有一个使用细节只读read-only挂载的会话无法在元数据中注册自己因此不会出现在 Sessions 列表中这是 status 命令描述 中明确说明的。二、info查看文件与目录的元数据详情juicefs info命令用于检查指定文件或目录的元数据信息包括该文件每个数据块在对象存储中对应的对象路径object path。这是排查“文件内容到底存到对象存储哪里去了”“块大小是否符合预期”等问题时最常用的工具。检查文件元数据$ juicefs info mnt/luggage-6255515.jpg mnt/luggage-6255515.jpg : inode: 36 files: 1 dirs: 0 length: 789.02 KiB (807955 Bytes) size: 792.00 KiB (811008 Bytes) path: /luggage-6255515.jpg objects: ------------------------------------------------------------------ || chunkIndex | objectName | size | offset | length | ------------------------------------------------------------------ || 0 | myjfs/chunks/0/0/80_0_807955 | 807955 | 0 | 807955 | ------------------------------------------------------------------输出中几个关键字段的含义inode该文件在 JuiceFS 内部的 inode 编号length文件实际字节长度size按块对齐后的占用空间objects表格列出每个 chunk 中每个 slice 对应的对象名、对象总大小size、slice 在对象内的偏移offset与长度length。例如myjfs/chunks/0/0/80_0_807955表示对象路径chunks/0/0/80_0_807955即 slice id 为 80、块索引为 0、块大小为 807955 字节。检查目录元数据对目录执行info时默认只统计当前一层目录$ juicefs info ./mnt mnt : inode: 1 files: 9 dirs: 4 length: 2.41 MiB (2532102 Bytes) size: 2.44 MiB (2555904 Bytes) path: /如果要递归统计所有子目录需要指定--recursive, -r选项$ juicefs info -r ./mnt ./mnt : inode: 1 files: 33 dirs: 4 length: 80.29 MiB (84191037 Bytes) size: 80.34 MiB (84242432 Bytes) path: /源码中--recursive的说明还提示递归结果可能不精确需要精确结果时应配合--strict选项见 cmd/info.go 的 Flags 定义但--strict在超大目录树上可能耗时很长按需使用。通过 inode 反查文件路径与数据块当只知道 inode 编号时例如日志中报错只带 inode可以进入挂载点目录后用-i选项做反向查询~ $ cd mnt ~/mnt $ juicefs info -i 36 36 : inode: 36 files: 1 dirs: 0 length: 789.02 KiB (807955 Bytes) size: 792.00 KiB (811008 Bytes) path: /luggage-6255515.jpg objects: ------------------------------------------------------------------ || chunkIndex | objectName | size | offset | length | ------------------------------------------------------------------ || 0 | myjfs/chunks/0/0/80_0_807955 | 807955 | 0 | 807955 | ------------------------------------------------------------------注意使用-i时当前目录必须位于挂载点内命令会通过当前工作目录定位到对应的挂载卷。从实现原理看juicefs info并不是直接连元数据引擎查询而是通过挂载点下的控制文件control file与正在运行的挂载进程通信info 命令 先openController(d)打开控制文件写入meta.InfoV2协议头和参数inode、recursive、raw、strict然后由挂载进程在 VFS 层完成统计并回传 JSON 结果如果挂载端返回EINVAL老版本不支持 InfoV2则回退到 legacyInfo 旧协议。除文档示例中的字段外较新版本的输出还会包含 tier分层存储状态、chunks原始 slice 信息以及该文件上的flocks、plocks锁列表见 结果解析与打印逻辑对排查锁相关问题同样有用。三、gc扫描与清理泄漏对象对象垃圾回收juicefs gc命令处理“对象泄漏”object leak并对文件覆盖写产生的数据碎片执行压缩compaction。它会扫描元数据中的所有 slice并与对象存储中实际存在的对象逐一比对找出需要处理的对象。对象泄漏是指数据块存在于对象存储中但元数据引擎中没有对应记录的情况。对象泄漏比较少见通常由程序缺陷、元数据引擎或对象存储的意外问题、断电、网络中断等引起。扫描泄漏对象默认情况下juicefs gc只扫描、不删除$ juicefs gc sqlite3://myjfs.db 2022/11/10 11:35:53.662024 juicefs[24404] INFO: Meta address: sqlite3://myjfs.db [interface.go:402] 2022/11/10 11:35:53.662759 juicefs[24404] INFO: Data use file:///Users/herald/.juicefs/local/myjfs/ [gc.go:108] Listed slices count: 92 Scanned objects count: 91 / 91 [] done Valid objects count: 91 Valid objects bytes: 7.67 MiB (8040969 Bytes) Leaked objects count: 0 Leaked objects bytes: 0.00 b (0 Bytes) Skipped objects count: 0 Skipped objects bytes: 0.00 b (0 Bytes) 2022/11/10 11:35:53.665015 juicefs[24404] INFO: scanned 91 objects, 91 valid, 0 leaked (0 bytes), 0 skipped (0 bytes) [gc.go:306]输出的统计含义Listed slices是元数据中列出的 slice 数量Valid objects是仍然被元数据引用的对象Leaked objects是没有任何元数据引用的泄漏对象Skipped objects是被跳过的近期上传对象。清理泄漏对象扫描到泄漏对象后可以使用--delete选项将其清除。默认启动 10 个线程执行删除线程数可通过--threads, -p调整$ juicefs gc sqlite3://myjfs.db --delete 2022/11/10 10:49:31.490016 juicefs[24086] INFO: Meta address: sqlite3://myjfs.db [interface.go:402] 2022/11/10 10:49:31.490831 juicefs[24086] INFO: Data use file:///Users/herald/.juicefs/local/myjfs/ [gc.go:108] Listed slices count: 92 Deleted pending count: 0 Scanned objects count: 103 / 103 [] done Valid objects count: 92 Valid objects bytes: 7.67 MiB (8045065 Bytes) Leaked objects count: 11 Leaked objects bytes: 12.87 MiB (13494874 Bytes) Skipped objects count: 0 Skipped objects bytes: 0.00 b (0 Bytes) 2022/11/10 10:49:31.493682 juicefs[24086] INFO: scanned 103 objects, 92 valid, 11 leaked (13494874 bytes), 0 skipped (0 bytes) [gc.go:306]执行--delete后可以再运行一次不带删除选项的juicefs gc确认泄漏对象已被清理干净。关键参数与实现细节结合 gc 命令源码 与实现逻辑有几点值得注意跳过近期上传的对象文件上传到对象存储时可能先产生临时中间文件写入完成后才会被清理。为避免把中间文件误判为泄漏对象juicefs gc默认跳过最近 1 小时内上传的文件该时间范围单位秒可通过环境变量JFS_GC_SKIPPEDTIME调整例如跳过最近 2 小时export JFS_GC_SKIPPEDTIME7200。对应源码见 maxMtime 与 JFS_GC_SKIPPEDTIME 的解析 以及 filterGcObject 的过滤逻辑。扫描全部对象有额外开销juicefs gc会列举对象存储中chunks/前缀下的全部对象见 gcInMemory 中object.WithPrefix(blob, chunks/)数据量大的文件系统执行该命令会有明显开销建议在业务低峰期运行。判定“泄漏”的依据源码将对象键解析为sliceId_块索引_块大小如80_0_807955先在按 inode 分组的 slice 集合中查找若找不到则判定泄漏即使能匹配到 slice还会通过 isLeakedBlock 校验块大小与元数据记录是否一致防止把块边界不匹配的对象误认为有效数据。--delete 附带更多清理动作从 gc 主流程 看--delete除了删除泄漏对象还会清理回收站中已过保留期TrashDays的文件、超过 24 小时的 detached 节点记录以及触发 pending 状态的延迟删除 slice 的清理若加--compact还会对全卷 slice 主动触发压缩调用m.CompactAll。大卷外排模式--external-sort-dir可指定临时目录启用外部排序以降低超大卷场景下的内存占用见 gc 命令描述 与 gc 入口。四、fsck逐块核对元数据发现丢失的数据块juicefs fsck工具将元数据与对象存储逐块block-by-block比对主要用于发现并修复文件系统内部可以修复的问题它能找出“元数据中有记录、但对象存储中没有对应数据块”的情况也能检查文件属性信息是否存在。$ juicefs fsck sqlite3://myjfs2.db 2022/11/10 17:31:19.062348 juicefs[26158] INFO: Meta address: sqlite3://myjfs2.db [interface.go:402] 2022/11/10 17:31:19.063132 juicefs[26158] INFO: Data use file:///Users/herald/.juicefs/local/myjfs/ [fsck.go:73] 2022/11/10 17:31:19.065857 juicefs[26158] ERROR: cant find block 0/1/1063_0_2693747 for file /david-bruno-silva-Z19vToWBDIc-unsplash.jpg: stat /Users/herald/.juicefs/local/myjfs/chunks/0/1/1063_0_2693747: no such file or directory [fsck.go:146] Found blocks count: 68 Found blocks bytes: 34.24 MiB (35904042 Bytes) Listed slices count: 65 Scanned slices count: 65 / 65 [] done Scanned slices bytes: 36.81 MiB (38597789 Bytes) Lost blocks count: 1 Lost blocks bytes: 2.57 MiB (2693747 Bytes) 2022/11/10 17:31:19.066243 juicefs[26158] FATAL: 1 objects are lost (2693747 bytes), 1 broken files: INODE: PATH 57: /david-bruno-silva-Z19vToWBDIc-unsplash.jpg [fsck.go:168]结果说明扫描发现了文件系统中的一个数据块缺失导致该文件损坏broken file并给出受影响的 inode 与文件路径。发现块丢失后还有一步重要的补救先确认挂载点下该文件是否仍然可访问。因为 JuiceFS 会把最近访问过的文件数据缓存在本地如果损坏前的文件版本还留在缓存中可以用缓存的数据块重新上传避免数据真正丢失。具体做法是按juicefs fsck输出的块路径上例为0/1/1063_0_2693747到缓存目录即挂载时--cache-dir选项对应的路径中查找对应的缓存文件。更多检查选项除全卷扫描外fsck 命令 还支持以下选项--path path只检查 JuiceFS 内的指定绝对路径目录或文件--repair修复指定路径必须配合--path使用否则命令会直接报错退出--recursive, -r递归检查或修复--sync-dir-stat同步所有目录的 stat 信息包括未损坏的目录大树耗时较长--repair-dir-mode修复目录时使用的权限模式八进制默认0755。例如对某个目录做递归检查与修复$ juicefs fsck redis://localhost --path /d1/d2 --repair # 递归检查 $ juicefs fsck redis://localhost --path /d1/d2 --recursive从实现看全卷模式 先列出全部 slice再列举对象存储中 chunks/ 前缀下的所有块然后对每个 slice 按BlockSize切分、逐一构造对象键普通模式为id/1000000/id/1000/sliceId_i_sizeHashPrefix 卷则为id%256:02X/id/1000000/sliceId_i_size执行 Head 校验见 块核对循环任何一个块缺失都会把对应文件记入 broken 列表若发现丢失块命令以 FATAL 级别输出丢失对象数、丢失字节数和损坏文件清单见 结果汇总。指定--path时则改走m.Check流程可校验目录结构并执行修复。五、compact合并覆盖写产生的碎片数据juicefs compact是 v1.2 版本引入的命令用于处理文件覆盖写overwrite造成的碎片化数据。随机写或原地修改会在同一个 chunk 中留下大量不连续的 slice读放大明显compact 工具将这些非连续 slice 合并或清理从而提升文件系统读性能。与juicefs gc的区别特性juicefs gcjuicefs compact作用范围整个文件系统仅指定目录/文件泄漏对象处理不处理待清理pending对象处理--delete不处理覆盖写碎片压缩支持--compact核心功能基本用法是指定挂载点内的路径juicefs compact /mnt/jfs/foo通过-p或--threads选项可以指定并发线程数加速处理默认值为 10可根据实际情况调整juicefs compact /mnt/jfs/foo -p 20从实现看compact 命令 与info类似也是先解析路径得到 inode再通过挂载点控制文件向挂载进程发送meta.CompactPath消息携带 inode 与并发数由挂载进程异步执行压缩命令行端则显示 “Compacted chunks” 进度条若挂载端返回EINVAL会提示需要升级并重新挂载。真正的合并逻辑在 vfs.Compact先检查可用内存是否充足等待空闲内存达到 BufferSize 的 1.5 倍以上然后依次读出各 slice 数据按BlockSize切页写入新的 slice writer最后Finish生成新的连续对象旧 slice 随元数据更新进入待删除队列由后台回收或juicefs gc清理。六、日常维护建议结合上述工具的能力一个典型的周期性维护流程是常规巡检运行juicefs status确认各客户端会话Hostname、MountPoint、Version符合预期发现异常节点或旧版本客户端及时处理必要时加--more查看回收站与待删除数据占用。对象用量核对当对象存储用量高于预期时运行juicefs gc扫描泄漏对象确认无误后用--delete清理并用JFS_GC_SKIPPEDTIME控制跳过窗口避免误删正在上传的中间文件。一致性校验定期或在发生断电、网络故障、存储告警后运行juicefs fsck重点排查 “Lost blocks / broken files”发现损坏文件时立即检查本地缓存能否恢复数据块。碎片治理对写入模式以随机覆盖为主、读性能下降的目录执行juicefs compact path合并碎片配合-p提升处理速度。这些命令的实现分别位于 cmd/status.go、cmd/info.go、cmd/gc.go、cmd/fsck.go、cmd/compact.go配套的元数据层实现可参考 pkg/meta/status.go 与 pkg/meta/interface.go便于在排查具体问题时进一步深入源码。【免费下载链接】juicefsJuiceFS is a distributed POSIX file system built on top of Redis and S3.项目地址: https://gitcode.com/GitHub_Trending/ju/juicefs创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考