科普文:详解 JuiceFS 读性能:预读、预取、缓存、FUSE 和对象存储

在高性能计算场景中,往往采用全闪存架构和内核态并行文件系统,以满足性能要求。随着数据规模的增加和分布式系统集群规模的增加,全闪存的高成本和内核客户端的运维复杂性成为主要挑战。

JuiceFS,是一款全用户态的云原生分布式文件系统,通过分布式缓存大幅提升 I/O 吞吐量,并使用成本较低的对象存储来完成数据存储,适用于大规模 AI 业务。

JuiceFS 数据读取流程从客户端的读请求开始,然后再经过 FUSE 发送给 JuiceFS 客户端,通过预读缓冲层,接着进入缓存层,最终访问对象存储。为了提高读取效率,JuiceFS 在其架构设计中采用了包括数据预读、预取和缓存在内的多种策略。

本文将详细解析这些策略的工作原理,并分享我们在特定场景下的测试结果,以便读者深入理解 JuiceFS 的性能优势及一些相关的限制,从而更有效地应用于各种使用场景。

鉴于文章内容的深度和技术性,需要读者有一定操作系统知识,建议收藏这篇文章以便在需要时进行仔细阅读。

01 JuiceFS 架构简介

JuiceFS 社区版架构分为客户端、数据存储和元数据三部分。数据访问支持多种接口,包括 POSIX 、HDFS API、S3 API,还有 Kubernetes CSI,以满足不同的应用场景。在数据存储方面,JuiceFS 支持几十种对象存储,包括公共云服务和自托管解决方案,如 Ceph 和 MinIO。元数据引擎支持多种常见的数据库,包括 Redis、TiKV 和 MySQL 等。

图片

JuiceFS 社区版(左)与企业版(右)架构图

企业版与社区版的主要区别在图片左下角元数据引擎和数据缓存的处理。企业版包括一个自研的分布式元数据引擎,并支持分布式缓存,社区版只支持本地缓存。

02 Linux 中关于“读”的几个概念

在 Linux 系统中,数据读取主要通过几种方式实现:

  • • Buffered I/O:这是标准的文件读取方式,数据会通过内核缓冲区,并且内核会进行预读操作,以优化读取效率;

  • • Direct I/O:允许绕过内核缓冲区直接进行文件 I/O 操作,以减少数据拷贝和内存占用,适合大量数据传输;

  • • Asynchronous I/O:通常与 Direct I/O 一起使用。它允许应用程序在单个线程中发出多个 I/O 请求,而不必等待每个请求完成,从而提高 I/O 并发性能;

  • • Memory Map:将文件映射到进程的地址空间,可以通过指针直接访问文件内容。通过内存映射,应用程序可以像访问普通内存一样访问映射的文件区域,由内核自动处理数据的读取和写入。

几种主要的读取模式及它们对存储系统带来的挑战:

  • • 随机读取,包括随机大 I/O 读和随机小 I/O 读,主要考验存储系统的延迟和 IOPS。

  • • 顺序读取,主要考验存储系统的带宽。

  • • 大量小文件读取,主要考验存储系统的元数据引擎的性能和系统整体的 IOPS 能力。

03 JuiceFS 读流程原理解析

JuiceFS 采用了文件分块存储的策略。一个文件首先逻辑上被分割成若干个 chunk,每个 chunk 固定大小为 64MB。每个 chunk 进一步被细分为若干个 4MB 的 block,block 是对象存储中的实际存储单元,JuiceFS 的设计中有不少性能优化措施与这个分块策略紧密相关。(进一步了解 JuiceFS 存储模式[1])。为了优化读取性能, JuiceFS 采取了预读、预取与缓存等多种优化方案。

图片

预读 readahead

预读(readahead):通过预测用户未来的读请求,提前从对象存储中加载数据到内存中,以降低访问延迟,提高实际 I/O 并发。下面这张图是一张简化的读取流程的示意图。虚线以下代表应用层,虚线以上是内核层。

当用户进程(左下角标蓝色的应用层) 发起文件读写的系统调用时,请求首先通过内核的 VFS,然后传递给内核的 FUSE 模块,经过 /dev/fuse 设备与 JuiceFS 的客户端进程通信。

图片

JuiceFS 数据读取流程示意图

右下角所示的流程是后续在 JuiceFS 中进行的预读优化。系统通过引入“session” 跟踪一系列连续读。每个 session 记录了上一次读取的偏移量、连续读取的长度以及当前预读窗口大小,这些信息可用于判断新来的读请求是否命中这个 session,并自动调整/移动预读窗口。通过维护多个 session,JuiceFS 还能轻松支持高性能的并发连续读。

为了提升连续读的性能,在系统设计中,我们增加了提升并发的措施。具体来说,预读窗口中的每一个 block (4MB) 都会启动一个 goroutine 来读数据。这里需要注意的是,并发数会受限于 buffer-size 参数。在默认 300MB 设置下,理论最大对象存储并发数为 75(300MB 除以 4MB),这个设置在一些高性能场景下是不够的,用户需要根据自己的资源配置和场景需求去调整这个参数,下文中我们也对不同参数进行了测试。

以下图第二行为例,当系统接收到连续的第二个读请求时,实际上会发起一个包含预读窗口和读请求的连续三个数据块的请求。按照预读的设置,接下来的两个请求都会直接命中预读的 buffer 并被立即返回。

图片

JuiceFS 预读机制简化示例(实际流程以代码为准)

如果第一个和第二个请求没有被预读,而是直接访问对象存储,延迟会比较高(通常大于10ms)。而当延迟降低在 100 微秒以内,则说明这个 I/O 请求成功使用了预读,即第三个和第四个请求,直接命中了内存中预读的数据。

预取 prefetch

预取(prefetch):当随机读取文件中的一小段数据时,我们假设这段数据附近的区域也可能会被读取,因此客户端会异步将这一小段数据所在的整个 block 下载下来。

但是在有些场景,预取这个策略不适用,例如应用对大文件进行大幅偏移的、稀疏的随机读取,预取会访问到一些不必要的数据,导致读放大。因此,用户如果已经深入了解应用场景的读取模式,并确认不需要预取,可以通过 --prefetch=0 禁用该行为

图片

JuiceFS 预取流程示意图

缓存 cache

在之前的一次分享中,我们的架构师高昌健详细介绍了 JuiceFS 的缓存机制,或查看缓存文档[2]。在这篇文章中,对于缓存的介绍会以基本概念为主。

页缓存 page cache

页缓存(page cache)是 Linux 内核提供的机制。它的核心功能之一就是预读(readahead),它通过预先读取数据到缓存中,确保在实际请求数据时能够快速响应。

进一步,页缓存(page cache)在特定场景下的应用也非常关键,例如在处理随机读操作时,如果用户能策略性地使用页缓存,将文件数据提前填充至进页缓存,如内存空闲的情况下提前完整连续读一遍文件,可以显著提高后续随机读的性能,从而极大地提升业务整体性能。

本地缓存 local cache

JuiceFS 的本地缓存可以利用本地内存或本地磁盘保存 block,从而在应用访问这些数据时可以实现本地命中,降低网络时延并提升性能。我们通常推荐使用高性能 SSD。数据缓存的默认单元是一个 block,大小为 4MB,该 block 会在首次从对象存储中读取后异步写入本地缓存。

关于本地缓存的配置,如 --cache-dir 和 --cache-size 等细节,企业版用户可以查看文档[3]。

分布式缓存 cache group

分布式缓存是企业版的一个重要特性。与本地缓存相比,分布式缓存将多个节点的本地缓存聚合成同一个缓存池,提高缓存的命中率。但由于分布式缓存增加了一次网络请求,这导致其在时延上通常稍高于本地缓存,分布式缓存随机读延迟一般是 1-2ms,而本地缓存随机读延迟一般是 0.2-0.5ms。关于分布式缓存具体架构[4],可以查看官网文档。

04 FUSE & 对象存储的性能表现

JuiceFS 的读请求都要经过 FUSE,数据要从对象存储读取,因此理解 FUSE 和对象存储的性能表现是理解 JuiceFS 性能表现的基础。

关于 FUSE 的性能

我们对 FUSE 性能进行了两组测试。测试场景是当 I/O 请求到达 FUSE 挂载进程后,数据被直接填充到内存中并立即返回。测试主要评估 FUSE 在不同线程数量下的总带宽,单个线程平均带宽以及CPU使用情况。硬件方面,测试 1 是 Intel Xeon 架构,测试 2 则是 AMD EPYC 架构。

ThreadsBandwidth(GiB/s)Bandwidth per Thread (GiB/s)CPU Usage(cores)
17.957.950.9
215.47.71.8
320.96.92.7
427.66.93.6
6437.25.3
8556.97.1
1069.66.968.6
1590613.6
201045.218
251024.0822.6
3098.53.2827.4

FUSE 性能测试 1, 基于 Intel Xeon CPU 架构

  • • 在单线程测试中,最大带宽达到 7.95GiB/s,同时 CPU 使用量不到一个核;

  • • 随着线程数增加,带宽基本实现线性扩展,当线程数增加到 20 时,总带宽增加到 104 GiB/s;

此处,用户需要特别注意的是,相同 CPU 架构下使用不同硬件型号、不同操作系统测得的 FUSE 带宽表现都有可能不同。我们使用过多种机型进行测试,在其中一种机型上测得的最大单线程带宽仅为 3.9GiB/s

ThreadsBandwidth(GiB/s)Bandwidth per Thread (GiB/s)CPU Usage(cores)
13.53.51
26.33.151.9
39.53.162.8
49.72.433.8
614.02.335.7
817.02.137.6
1018.61.99.4
15211.413.7

FUSE 性能测试 2, 基于 AMD EPYC CPU 架构

  • • 在测试 2 中,带宽不能线性扩展,特别是当并发数量达到 10 个时,每个并发的带宽不足 2GiB/s;

在多并发情况下,测试 2( EPYC 架构)带宽峰值约为 20GiBps;测试 1(Intel Xeon 架构)表现出更高的性能空间,峰值通常在 CPU 资源被完全占用后出现,这时应用进程和 FUSE 进程的 CPU 都达到了资源极限。

在实际应用中,由于各个环节的时间开销,实际的 I/O 性能往往会低于上述测试峰值 3.5GiB/s。例如,在模型加载的场景中,加载 pickle 格式的模型文件,通常单线程带宽只能达到 1.5 到 1.8GiB/s。这主要是因为读取 pickle 文件的同时,要进行数据反序列化,还会遇到 CPU 单核处理的瓶颈。即使是不经过 FUSE,直接从内存读取的情况下,带宽也最多只能达到 2.8GiB/s。

关于对象存储的性能

我们使用 juicefs objbench 工具进行测试,测试涵盖了单并发、10 并发、200 并发以及 800 并发的不同负载。用户需要注意的是,不同对象存储的性能差距可能很大。

上传带宽 upload objects- MiB/s下载带宽 download objects MiB/s上传平均耗时 ms/object下载平均耗时 ms/object
单并发32.8940.46121.6398.85ms
10 并发332.75364.8210.0210.96
200 并发5590.263551.650671.13
800 并发8270.284038.410.480.99

当我们增加对象存储 GET 操作的并发数到 200 和 800 后,才能够达到非常高的带宽。这说明直接从对象存储上读数据时,单并发带宽非常有限,提高并发对整体的带宽性能至关重要

05 连续读与随机读测试

为了给大家提供一个直观的基准参考,我们使用 fio 工具测试了 JuiceFS 企业版在连续读取和随机读场景下的性能。

连续读

从下图可以看到 99% 的数据都小于 200 微秒。在连续读场景下,预读窗口总能很好地发挥作用,因此延迟很低。

图片

默认挂载参数,buffer-size=300MiB,连续从对象存储读10GB

同时,我们也能通过加大预读窗口,以提高 I/O 并发,从而提升带宽。当我们将 buffer-size 从默认 300MiB 调整为 2GiB 后,读并发不再受限,读带宽从 674MiB/s 提升到了 1418 MiB/s,此时达到单线程 FUSE 的性能峰值,进一步提高带宽需要提高业务代码中 I/O 并发度。

buffer-size带宽
300MiB674MiB/s
2GiB1418MiB/s

不同 buffer-size 带宽性能测试(单线程)

当提高业务线程数到 4 线程时,带宽能达到 3456MiB/s;16 线程时,带宽达到了 5457MiB/s,此时网络带宽已经达到饱和。

buffer-size带宽
1线程1418MiB/s
4线程3456MiB/s
16线程5457MiB/s

不同线程数量下带宽性能测试 (buffer-size:2GiB)

随机读

对于小 I/O 随机读,其性能主要由延迟和 IOPS 决定,由于总 IOPS 能够通过增加节点线性扩展,所以我们先关注单节点上的延迟数据。

“FUSE 数据带宽”是指通过 FUSE 层传输的数据量,代表用户应用实际可观察和操作的数据传输速率;“底层数据带宽”则指的存储系统本身在物理层或操作系统层面处理数据的带宽。

从表格中可以看到与穿透到对象存储相比,命中本地缓存和分布式缓存的情况下,延迟都更低,当我们需要优化随机读延迟的时候就需要考虑提高数据的缓存命中率。同时,我们也能看到使用异步 I/O 接口及提高线程数可以大大提高 IOPS。

图片

JuiceFS 小 I/O 随机读测试结果

不同于小 I/O 的场景,大 I/O 随机读场景还要注意读放大问题[5]。如下表所示,底层数据带宽高于 FUSE 数据带宽,这是因为预读的作用,实际的数据请求会比来自于应用的数据请求多1-3倍,此时可以尝试关闭 prefetch 并调整最大预读窗口来调优。

分类

FUSE 数据带宽

底层数据带宽

1MB buffered IO

92MiB

290MiB

2MB buffered IO

155MiB

435MiB

4MB buffered IO

181MiB

575MiB

1MB direct IO

306MiB

306MiB

2MB direct IO

199MiB

340MiB

4MB direct IO

245MiB

735MiB

JuiceFS(开启分布式缓存) 大 I/O 随机读测试结果

相关阅读

  • • 千卡利用率超 98%,详解 JuiceFS 在权威AI测试中的实现策略

  • • 极限挑战:使用 Go 打造百亿级文件系统的实践之旅

  • • 如何借助分布式存储 JuiceFS 加速 AI 模型训练

引用链接

[1] 进一步了解 JuiceFS 存储模式: https://juicefs.com/docs/zh/community/internals/io_processing
[2] 缓存文档: https://juicefs.com/docs/zh/community/guide/cache
[3] 查看文档: https://juicefs.com/docs/zh/cloud/guide/cache/#data-cache
[4] 分布式缓存具体架构: https://juicefs.com/docs/zh/cloud/guide/distributed-cache
[5] 读放大问题: https://juicefs.com/docs/zh/cloud/administration/troubleshooting/#read-amplification

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/50012.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL优化相关

文章目录 SQL优化1. 数据插入2. 主键优化页分裂页合并索引设计原则 3. order by 优化4. group by 优化5. limit优化6. count优化7. update 优化 SQL优化 1. 数据插入 当我们需要插入多条数据时候,建议使用批量插入,因为每次插入数据都会执行一条SQL&am…

【Linux】多线程4——线程同步/条件变量

1.Linux线程同步 1.1.同步概念与线程饥饿问题 先来理解同步的概念 什么是线程同步 在一般情况下,创建一个线程是不能提高程序的执行效率的,所以要创建多个线程。但是多个线程同时运行的时候可能调用线程函数,在多个线程同时对同一个内存地…

centos stream 9安装 Kubernetes v1.30 集群

1、版本说明: 系统版本:centos stream 9 Kubernetes版本:最新版(v1.30) docker版本:27.1.1 节点主机名ip主节点k8s-master172.31.0.10节点1k8s-node1172.31.0.11节点2k8s-node2172.31.0.12 2、首先,使用Vagrant和Virt…

前端缓存问题(浏览器缓存和http缓存)- 解决办法

问题描述:前端代码更新,但因浏览器缓存问题,导致页面源代码并未更新 查看页面源代码的方法:鼠标右键,点击查看页面源代码 如图: 解决方法: 注:每执行一步,就检查一下浏览…

string indices must be integers

string indices must be integers 目录 string indices must be integers 【常见模块错误】 【解决方案】 常见原因及解决方法 具体案例分析 总结 欢迎来到英杰社区https://bbs.csdn.net/topics/617804998 欢迎来到我的主页,我是博主英杰,211科班出…

Java1.1标准之重要特性及用法实例(十二)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列…

kafka高性能的底层原理分析

目录 1.磁盘顺序写 2.零拷贝 3.数据压缩 4.消息批量处理 5.pageCache 6.稀疏索引 总结 Kafka是一种高吞吐量的分布式发布订阅消息系统,它可以处理消费者在网站中的所有动作流数据。那么他是如何做到高性能的呢,本篇文章从宏观上分析一下&#xff…

C++——初识模板

前言 模板是C中的重大板块,是使C真正超越C语言的工具,在C模板没有设计出来之前其实C是没有那么被行业和社会所认可的,本节我们将初步了解C中的模板(仅作大致讲解,具体的细枝末节将会再过几节讲解)&#xf…

Linuxnat网络配置

📑打牌 : da pai ge的个人主页 🌤️个人专栏 : da pai ge的博客专栏 ☁️宝剑锋从磨砺出,梅花香自苦寒来 ☁️运维工程师的职责:监…

一维数组--最长平台

这道题目挺简单的&#xff0c;那你还想这么久&#xff01; 直接看代码&#xff01; #include<cstdio> long long n,a[100002],sum,b[100002],max-99999,j; int main(){scanf("%d",&n);scanf("%d",&a[1]);sum1;for(int i2;i<n;i){j;scan…

【ESP32 IDF 定时器Timer】

目录 TIM定时器介绍硬件定时器和软件定时器硬件定时器基本参数硬件定时器的操作流程初始化硬件定时器设置报警注册回调函数使能和禁用定时器启动和停止定时器硬件定时器驱动代码调试 软件定时器使用软件定时器代码编写 TIM定时器 介绍 定时器是单片机内部集成&#xff0c;可以…

鸿蒙HarmonyOS开发:多种内置弹窗及自定义弹窗的详细使用指南

文章目录 一、消息提示框&#xff08;showToast&#xff09;1、导入模块2、语法3、参数4、示例5、效果 二、对话框&#xff08;showDialog&#xff09;1、导入模块2、语法3、参数4、示例5、效果 三、警告弹窗&#xff08;AlertDialog&#xff09;1、语法2、参数3、AlertDialogP…

STM32的GPIO输入输出方式设置示例

1、GPIO口做基本的输入/输出口使用时&#xff0c;输入有上拉输入、下拉输入、浮空输入&#xff08;既无上拉电阻也无下拉电阻&#xff09;3种输入方式&#xff1b;输出有开漏输出、推挽输出2种输出方式。 2、示例 &#xff08;1&#xff09;示例1&#xff1a;GPIO做输出的设置…

项目比赛经验分享:如何让即兴发言出彩

项目比赛经验分享&#xff1a;如何让即兴发言出彩 前言1. 顺势趁便法2. 词语撮要法3. 起承转合法4. 数字串连法结语 在项目管理和比赛的激烈竞争中&#xff0c;即兴发言往往成为展示个人魅力和团队精神的重要环节。如何在短时间内组织语言&#xff0c;表达清晰、有力的观点&…

基于JSP、java、Tomcat三者的项目实战--校园交易网(3)主页

前文功能的实现 技术支持&#xff1a;JAVA、JSP 服务器&#xff1a;TOMCAT 7.0.86 编程软件&#xff1a;IntelliJ IDEA 2021.1.3 x64 前文三篇登录和注册功能的实现 基于JSP、java、Tomcat、mysql三层交互的项目实战--校园交易网&#xff08;1&#xff09;-项目搭建&#xf…

Cisco路由器OSPF配置

Cisco路由器OSPF配置 本文已经迁移至 https://www.geekery.cn 本文档将详细介绍如何配置 OSPF&#xff08;开放最短路径优先&#xff09;协议&#xff0c;使用三个路由器&#xff1a;RA、RB 和 RC。一步一步说明每个路由器的配置、设置 IPv4 和 IPv6 地址的、配置OSPF 的启用以…

Cocos Creator2D游戏开发-(1)初始化设置

初心: 做一款微信或者抖音小游戏,然后发布,对于我来说这是一个新的赛道; 写这些文档的原因,记录一下自己学习过程,下次用的时候方便找 cocos creator版本: 3.8.3 当前小游戏飞机大战教程来源于: 抖音: 禅影 chanying001 源码目录: https://www.kdocs.cn/l/caLr6XCbEfPa 创建一个…

zeal 开发者离线文档工具

zeal是一款程序开发者不可或缺的离线文档查看器 下载地址 官网地址&#xff1a; windows版csdn下载(开箱即用含)&#xff1a;https://download.csdn.net/download/xzzteach/89588765 已离线 Android.docset Apache_HTTP_Server.docset Bash.docset Bootstrap_4.docset Bootst…

selenium入门超详细教程——网页自动化操作

文章目录 简介一、环境安装1.selenium安装2.安装浏览器驱动2.1 确定浏览器版本2.2 下载驱动 二、基础用法1.对页面进行操作1.1 初始化浏览器对象1.2 访问页面1.3 设置浏览器大小1.4 前进后退1.5 获取页面基础属性 2.定位页面元素3.模拟鼠标操作3.1 常用操作 4.模拟键盘操作4.1 …

测评Copilot和ChatGPT-4o从PDF创建PPT功能

关于 Copilot 由 PDF 创建 PPT&#xff0c;之前已经发过几篇文档说明&#xff1a; Copilot for Microsoft 365 现已支持从PDF创建Word和PPT Copilot读PDF文献一键生成PPT&#xff0c;吓傻了导师 Copilot一键将PDF转为PPT&#xff0c;治好了我的精神内耗 今天来测评对比 Cop…