- 存储
- 分布式文件系统
- 对象存储
- 云原生
【免费下载链接】cubefs
cloud-native distributed storage
CubeFS 的本地缓存(BlockCache)功能通过在计算节点本地部署缓存服务,将后端多副本子系统或纠删码子系统中被反复读取的热点数据就近缓存,从而大幅缩短客户端读路径。本文基于 docs-zh/source/feature/cache.md 整理,并结合 client/blockcache 目录下的服务端与客户端源码展开讲解,覆盖磁盘版与内存版两种缓存的配置、启动步骤、缓存一致性策略,以及底层读写实现原理,帮助你快速在 AI 训练、数据分析等"重复读小文件/小批量数据"的场景中落地这一能力。
本地缓存解决什么问题
在 AI 训练等场景中,任务执行过程会反复读取相同的小批量数据或模型配置文件。如果每次读取都从远端存储(多副本子系统或纠删码子系统)拉取,网络往返和 IO 延迟会显著拖累任务效率。本地缓存正是为此设计:把热点数据缓存在计算节点的本地磁盘或内存中,后续读请求命中缓存后直接本地返回,避免重复访问远端。
从读写路径看(见 架构示意图):
- 客户端读请求优先访问本地磁盘的数据缓存区;
- 若缓存命中,直接从本地获得数据,请求快速完成;
- 若未命中,再从后端的多副本子系统或纠删码子系统读取,并在读取后异步将缓存数据写入本地,为后续请求提速。
图片出处:docs-zh/source/feature/pic/cfs-bache-localdisk.png
本地缓存-磁盘版
磁盘版本地缓存利用计算节点的本地磁盘作为数据块缓存,适合缓存数据量较大的场景。
第一步:启动本地 bcache 服务
要开启本地磁盘缓存功能,需要先在计算节点上启动本地 cache 服务(对应的服务端源码位于 client/blockcache/cmd.go 与 client/blockcache/bcache/service.go):
./cfs-bcache -c bcache.json配置文件bcache.json中各参数的含义如下:
| 参数 | 类型 | 含义 | 必需 |
|---|---|---|---|
| cluster | string | 集群名称 | 是 |
| vol | string | 卷名称 | 是 |
| cacheDir | string | 缓存数据的本地存储路径:分配空间(单位 Byte) | 是 |
| logDir | string | 日志路径 | 是 |
| logLevel | string | 日志级别 | 是 |
结合服务端源码可以补充几个关键细节:
- cluster 与 vol 是硬性要求:启动逻辑会校验
vol与cluster,任一为空则直接报错退出(见 client/blockcache/cmd.go)。其中vol会被服务端写入缓存元数据,用于后续按卷统计与路由。 - cacheDir 的格式是"路径:容量":即
本地目录:字节数。服务端解析时以冒号:分隔路径与容量(CacheConfSeparator = ":"),容量为 0 或路径为空会视为配置错误(见 client/blockcache/bcache/manage.go 与 client/blockcache/bcache/service.go)。文档内存版示例中的"/dev/shm/cubefs-cache:16106127360"即 15 GB 内存空间。 - cacheDir 还支持配置多个目录:用分号
;分隔多个路径:容量组合,例如"/data/cache1:1073741824;/data/cache2:1073741824",数据块会按 key 的 CRC32 哈希取模(hashKey(key) % len(bstore))分散到不同目录(见 client/blockcache/bcache/manage.go 与selectDiskKv)。 - 服务端还支持额外配置项:
cacheLimit(缓存文件数量上限,默认 50000000,上限同样为 50000000)、cacheFree(缓存空间剩余比例阈值,默认 0.15)、blockSize(数据块大小,单位字节),以及prof(pprof 端口)、warnLogDir(UMP 告警日志目录)等(见 client/blockcache/bcache/service.go 与 client/blockcache/cmd.go)。logLevel支持debug/info/warn/error,默认error。 - 默认以后台守护进程方式运行:
cfs-bcache默认会 daemonize 后台运行,-f参数可强制前台运行便于调试(见 client/blockcache/cmd.go);服务启动时还会把进程打开文件数上限(RLIMIT_NOFILE)调整到 1024000,以支撑大量缓存文件句柄。 - 服务端通过 Unix Domain Socket 对外提供服务:监听路径为
/var/run/cubefscache/bcache.socket,并配合.lock文件做单实例互斥(见 client/blockcache/bcache/service.go)。
第二步:在客户端配置中增加 bcacheDir
服务启动后,只需在客户端挂载配置中增加bcacheDir项,指定需要缓存到本地的数据目录:
{ ... "bcacheDir": "path/to/data" // 需要缓存到本地的数据目录 }客户端在解析挂载参数时会读取bcacheDir(配置项定义见 proto/mount_options.go),并在 client/fs/super.go 中完成路径归一化:若bcacheDir为空且启用了缓存,则默认使用挂载点目录;bcacheDir相对挂载点的路径会被转换为卷内根目录起始的绝对路径,并创建BcacheClient用于与服务端通信(连接池大小为 20 起、上限 200,见 client/blockcache/bcache/client.go)。
缓存一致性
本地缓存与后端存储之间是最终一致性关系。CubeFS 通过以下三种策略来保证:
按文件后缀禁用缓存
某些文件在任务执行过程中会被反复更新,缓存后反而可能出现读到旧数据的问题。例如训练任务生成的 checkpoint 文件(.pt、.pth后缀)就属于这类不适合本地缓存的场景。可以在客户端配置文件的bcacheFilterFiles项中追加后缀,对这些文件禁用缓存:
{ ... "bcacheFilterFiles": "pt" // 禁止对 .pt 后缀的文件进行缓存 }客户端侧配置项默认值为"py;pyx;sh;yaml;conf;pt;pth;log;out",即默认就会跳过上述后缀文件的缓存(见 proto/mount_options.go)。追加时用分号;分隔多个后缀,例如"pt;pt;pth;ckpt"。客户端在读取路径上会依据该过滤清单决定是否查询/写入本地缓存。
定期检查
客户端会定期向后端查询缓存数据对应的元数据是否有变更,一旦发现变更,就删除本地缓存数据。该机制由两个可调参数控制(见 proto/mount_options.go):
bcacheCheckIntervalS:缓存检查间隔,默认 300 秒;bcacheBatchCnt:单轮批量获取元数据的数量上限,默认 100000。
两个参数会被读入客户端挂载上下文(见 client/fs/super.go),周期性驱动元数据比对任务,保证本地缓存与远端元数据最终一致。
主动失效
- 单个挂载点场景:用户更新数据后会主动删除本地缓存数据,避免读到过期内容;
- 多个挂载点场景:其他挂载点无法感知本次更新,只能等待缓存数据生命周期到期后失效(即等待定期检查或缓存条目被 LRU 淘汰/空间回收)。
因此,如果多个客户端同时挂载同一卷并高频写入更新,建议结合应用对数据新鲜度的要求,合理设置检查间隔,或对高频更新的文件类型使用bcacheFilterFiles直接排除。
本地缓存-内存版
如果缓存数据量少、且希望进一步降低 IO 延迟,可以使用计算节点的内存资源作为本地缓存。由于读写完全在内存中进行,性能相比磁盘版更高。
图片出处:docs-zh/source/feature/pic/cfs-bache-localmemory.png
/dev/shm是 Linux 的内存文件系统,支持动态调整容量。这里将/dev/shm调整至 15G,表示最多可用 15G 内存来缓存数据:
$ sudo mount -o size=15360M -o remount /dev/shm然后将 bcache 服务的配置文件改为/dev/shm的子目录即可,例如:
{ ... "cacheDir":"/dev/shm/cubefs-cache:16106127360" // 使用 15G 内存作为数据缓存 }16106127360即 15 GiB(15 × 1024³)的字节数。需要说明的是,/dev/shm容量调整是系统级的,重启后可能恢复默认大小(通常为物理内存的一半),生产环境建议将调整命令纳入开机脚本;同时内存缓存容量不建议超过可用内存,以免影响训练/业务进程本身的内存使用。
底层实现原理(源码级剖析)
在掌握配置与操作之后,理解服务端与客户端的数据流能帮助你更好地调优和排查问题。
服务端:按块缓存 + LRU 管理 + 异步落盘
服务端核心实现在 client/blockcache/bcache/manage.go:
- 缓存键格式:缓存条目以
vid_inode_offset形式的 key 组织(见waitFlush注释),例如2_1024_0;落盘路径按 key 哈希与 inode 号散列到blocks目录下的两级子目录,兼顾了目录扇出与局部性(buildCachePath,见 client/blockcache/bcache/manage.go)。 - LRU 淘汰与空间管理:每个缓存 key 对应一个 LRU 链表节点(
lrulist+bcacheKeys索引);后台spaceManager每 60 秒巡检一次各缓存目录的使用率,当剩余空间比例低于freeLimit或文件数超过limit时,按 LRU 顺序淘汰最久未访问的缓存块;另有每 20 分钟一次的临时文件(.tmp)清理任务(见 client/blockcache/bcache/manage.go)。 - 写入路径:
cache()默认先投递到容量 1024 的异步 pending 队列,由flush()协程统一落盘(先写.tmp再原子 rename);队列满时退化为同步直写,避免阻塞读请求(见 client/blockcache/bcache/manage.go)。 - 数据加密:缓存文件内容写入前会做异或混淆(
encryptXOR,与0xF逐字节异或),读取时再解密,避免明文数据直接散落在缓存盘(见 client/blockcache/bcache/manage.go)。 - 服务协议:服务端通过 Unix Socket 处理三类操作码——
OpBlockCachePut(写入)、OpBlockCacheGet(查询缓存路径并读取)、OpBlockCacheDel(删除/失效),见 client/blockcache/bcache/service.go。
客户端:连接池 + 命中/未命中分流
客户端侧BcacheClient(见 client/blockcache/bcache/client.go):
- 与本地服务端之间维护一个连接池(初始 20、上限 200、连接过期时间可配置),请求复用连接降低开销;
Get流程先向服务端请求缓存文件路径并校验路径合法性,随后直接以ReadAt读取缓存文件并解密返回;Put将远端读取的数据块投递给服务端落盘;Evict用于主动失效(单挂载点更新后删除本地缓存)。
使用建议与注意事项
- 容量规划:磁盘版
cacheDir的容量是硬上限,超出后由 LRU 淘汰腾挪空间;内存版务必保证/dev/shm容量不超过可用物理内存,并为训练进程预留足够内存。 - 文件类型取舍:对高频更新的 checkpoint、日志类文件(
.pt/.pth/.log/.out等)默认已被过滤,若业务存在其他热更新后缀,记得在bcacheFilterFiles中补充。 - 多挂载点场景:跨挂载点的缓存失效依赖定期检查(
bcacheCheckIntervalS),对新鲜度敏感的数据应调小检查间隔,或直接用后缀过滤规避。 - 客户端与服务端配合:先启动
cfs-bcache服务(确认/var/run/cubefscache/bcache.socket存在),再挂载客户端并配置bcacheDir;服务端日志输出在logDir/blockcache/output.log,排查命中率与淘汰问题时优先查看该日志及bcache_meta_count相关监控指标(见 client/blockcache/bcache/manage.go)。 - 适用前提:本地缓存面向"读多写少、重复读"的负载形态(如 AI 训练反复读取小批量数据与模型配置),并不适用于强一致、随机大文件顺序流等场景,评估时可先用监控观察读命中率再决定是否开启。
至此,你已经掌握了 CubeFS 本地缓存的磁盘版、内存版两种部署方式,理解了cacheDir/bcacheDir/bcacheFilterFiles等核心配置的语义与默认值,并清楚了其服务端 LRU 管理、异步落盘、一致性检查的底层实现,可以在实际集群中按需启用并持续调优。
- 存储
- 分布式文件系统
- 对象存储
- 云原生
【免费下载链接】cubefs
cloud-native distributed storage
相关推荐
Kingfisher缓存一致性保障:内存与磁盘缓存同步机制
Kingfisher缓存一致性保障:内存与磁盘缓存同步机制 一、缓存一致性痛点与解决方案 你是否曾在iOS开发中遇到过以下问题:图片已加载却无法立即显示?内存缓
移动开发图像处理缓存LiveAutoRecord缓存机制:内存缓存与磁盘缓存优化
LiveAutoRecord缓存机制:内存缓存与磁盘缓存优化 引言:直播录制中的缓存挑战 直播自动录制软件面临着独特的性能挑战:需要实时处理海量视频流数据、频繁
SafeLine缓存机制:内存缓存与磁盘缓存优化
SafeLine缓存机制:内存缓存与磁盘缓存优化 引言:WAF性能优化的关键挑战 在Web应用防火墙(WAF)的实际部署中,缓存机制的性能直接影响着系统的整体响
WAF网络安全应用安全
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考