全部文档
当前文档

暂无内容

如果没有找到您期望的内容,请尝试其他搜索词

文档中心

通过分布式缓存提供多客户端缓存共享能力

最近更新时间:2025-03-03 10:56:44

客户端本地缓存数据无法共享,当本地缓存容量无法满足缓存需求时,推荐使用分布式缓存。

在大量客户端反复访问同一批文件的场景,可以使用分布式缓存将海量数据缓存到多个客户端共享。如AI训练读取数据集场景,多个客户端需要频繁访问相同的数据,单机缓存无法满足容量和性能需求,可将训练数据集缓存到多个GPU节点的空闲SSD或内存中,有效提升访问性能。

本文介绍如何通过分布式缓存提供多客户端缓存共享能力。以下仅介绍分布式缓存相关的关键参数,完整参数列表参见客户端命令参考

架构

启用分布式缓存后,多个客户端会构成一个分布式缓存组(一个一致性哈希环),每一个缓存组的数据在组内共享。缓存组内的每个成员,需通过 --cache-group设置组名,相同组名的成员即构成一个缓存组。缓存组内任何一个成员在读取文件时,会根据目前缓存组拓扑结构计算出当前数据块所在节点,并向该节点发起请求,如果数据尚未存在该节点,该节点从KPFS下载数据并存储在本地缓存盘中。

如上图所示,KPFS客户端4读取文件a(由4个数据块a1-a4组成)时,假设根据一致性哈希算法,得出a1-a4分别位于KPFS客户端1-4所在节点,因此每个成员节点都会访问KPFS,下载所需数据块。下载完毕后,KPFS客户端1-3通过内网通信,将数据块返回给KPFS客户端4,完成文件读取。

注意

  1. 建议将分布式缓存组部署在高性能(至少以万兆网络相互连接)、安全的内网环境,确定节点间通信顺畅,以获得更好的性能。

  2. 推荐用同构节点(至少缓存盘大小相同)来构建缓存组,缓存组目前的一致性哈希算法并不会考虑到不同节点的可用空间不一致,从而调整各个节点的权重,因此如果缓存组节点的磁盘大小不一致,将会在均匀分配的算法下产生空间浪费。

多级数据缓存

启用分布式缓存后,除了单客户端自身的本地数据缓存,还有来自缓存组内客户端的多级数据缓存。

读请求会依次请求内核分页缓存、客户端内存缓冲区、本地缓存,分布式缓存组,缓存中没找到对应数据时才会读取KPFS从缓存组获取的数据,依然会缓存到本地盘。

使用说明

分布式缓存配置步骤

  1. 分布式缓存组就是由一个个 KPFS 客户端组成的,在分布式缓存组的每个节点上运行如下客户端挂载命令,组建分布式缓存。

# 将 $VOL_NAME 替换为文件系统名,$MOUNTPOINT 则替换成实际挂载的路径,--cache-group 是用户自定义的缓存组名称
juicefs mount $VOL_NAME $MOUNTPOINT --cache-group=mygroup
  1. 集群网络往往很复杂,每个节点都绑定了多块性能不同的网卡,为了让缓存组达到最大性能,推荐将性能好的网卡分配给缓存组,用于节点间通信。在分布式缓存组的每个节点绑定用于节点间通信的网卡,需要手动设置完整IP地址 或 CIDR类型地址。

# --group-ip为缓存组绑定的网卡,如下填写了完整IP地址
juicefs mount $VOL_NAME $MOUNTPOINT --cache-group=mygroup --group-ip=10.6.5.1
# 如下填写了CIDR类型地址
juicefs mount $VOL_NAME $MOUNTPOINT --cache-group=mygroup --group-ip=10.6.0.0/16
  1. 挂载完毕后,查看客户端日志,确认缓存组已启用。

# 在日志中查看「peer」字样,就能看到缓存组相关日志
# 例如 <INFO>: Peer listen at 172.16.255.181:36985 [peer.go:790]
grep peer /var/log/juicefs.log
  1. 缓存组搭建完毕,但组内成员节点还没有缓存任何数据,为了提升应用首次访问的速度,可运行预热命令,从而将数据预热到整个缓存组。

# 在任意缓存组成员节点运行预热命令,效果相同。如下为缓存/datadir/train-data目录下所有文件
# 如果规模庞大,使用 -c 增加并发度,加速预热
juicefs warmup /datadir/train-data -c 80

独立缓存集群

适合场景:在Kubernetes集群中,客户端Pod不常驻,客户端不断被销毁、重建,可能导致缓存利用率很低对于此类动态创建伸缩的计算集群,可以将文件系统挂载在固定几个节点,组成一个常驻、稳定的独立缓存集群(本质就是一个分布式缓存组)。示范步骤如下:

  1. 独立缓存集群:准备n个客户端,组建一个分布式缓存组,名称为mygroup,参见上文分布式缓存配置步骤;如果需要在Kubernetes中通过DaemonSet方式部署独立缓存集群,参见在容器环境中部署独立缓存集群

  2. 应用侧客户端:加入独立缓存集群并启用--no-sharing参数,挂载完毕后应用侧客户端会从独立缓存集群获取数据。但不分享自己的缓存数据,避免其频繁变动,影响缓存集群的服务能力。

# 添加 --no-sharing 参数,虽然加入缓存组,但不向其他成员提供分布式缓存服务
juicefs mount $VOL_NAME $MOUNTPOINT  --cache-group=mygroup --no-sharing
# 挂载完毕以后,如果有需要,也可以直接在 --no-sharing 挂载点上执行预热,同样能将数据预热到整个缓存组
juicefs warmup /datadir/train-data -c 80
  1. 挂载完毕后,应用侧客户端就会以「只索取,不分享」的方式来使用独立缓存集群的数据了。另外,即便对于这些客户端,多级缓存的设计依然生效:从缓存组获取到的数据,依然会缓存到本地。如果您希望应用侧客户端完全不保留任何本地缓存(如:本地缓存盘性能较差,比不上缓存组节点间的内网通信吞吐),所有文件访问均通过独立缓存集群来完成,可通过--cache-size=0参数禁用其本地缓存。

# 应用侧客户端禁用本地缓存,所有读请求都走缓存集群
juicefs mount $VOL_NAME  $MOUNTPOINT  --cache-group=mygroup --no-sharing --cache-size=0

混合部署缓存组

适合场景:客户端本缓存盘性能很好,希望充分利用客户端本地缓存盘的I/O能力,减少节点间网络通信。对于此类场景,可以在所有节点混合部署两个KPFS客户端:一个是缓存集群挂载点,另一个是业务侧实际使用的挂载点。混合部署策略的好处是:

  • 高性能缓存盘同时用作分布式缓存和本地缓存,更充分利用本地高性能I/O。

  • 所有节点都加入同一个缓存组,读任何文件,都只需通过缓存组请求一次KPFS。

挂载步骤如下:

  1. 在所有节点挂载缓存集群以及--no-sharing客户端。假设节点缓存盘共1000000MiB。

# 缓存集群挂载点
# --cache-size=500000 表示最多使用500GiB 缓存盘空间
# --free-space-ratio=0.1 表示最多使用缓存盘90%的空间
# --cache-dir与应用侧挂载点所使用的--cache-dir不能混用
juicefs mount $VOL_NAME $DISTRIBUTED-DMOUNTPOINT --cache-group=mygroup --cache-dir=/data/distributed-cache --cache-size=500000 --free-space-ratio=0.1

# 应用侧挂载点
# --cache-size=1000000 表示最多可以用满 1TiB 缓存盘空间
# --free-space-ratio=0.01 表示最多使用缓存盘99%的空间
# --cache-dir与缓存集群挂载点所使用的--cache-dir不能混用
juicefs mount $VOL_NAME $APPLICATION-DMOUNTPOINT --cache-group=mygroup --cache-dir=/data/local-cache --cache-size=1000000 --free-space-ratio=0.01 --no-sharing

摘盘、换盘操作

  1. 将待摘除盘中数据拷贝到其它盘;

  2. 调整以下挂载参数:

    • --cache-dir,删去该节点旧盘;

    • 调整 --group-weight降低该节点权重,避免节点间空间不一致导致的利用率不理想。

  3. 参数修改完毕后,客户端平滑重新挂载使这些修改生效。

  4. 重启后客户端会重新扫描目录并再次加入缓存组,如果权重有所调整,那么也会在缓存组内重新均衡数据。

依照和上方步骤相同的原理,换盘的过程也是类似的,拷贝数据到新盘,然后视情况调整参数、重新挂载即可。

纯净模式常规模式

纯净模式

点击可全屏预览文档内容