- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
随着大模型流行,GPU 算力资源正变得日益稀缺,传统的“算力跟着存储跑”的策略需要转变为“存储跟着算力跑”。为了确保数据一致性和管理的便捷性,企业通常在特定地区的公有云上选择对象存储作为所有模型数据的集中存储点。当进行计算任务调度时,往往需要人工介入,手动进行数据拷贝和迁移方法不仅成本高昂,还存在管理和维护的复杂性,包括权限控制等问题都极为棘手.
JuiceFS 企业版的 “镜像文件系统” 功能允许用户从一个地区自动复制元数据到多个地区,形成一对多的复制模式。在多云架构下,该功能在确保数据一致性的同时,大幅降低人工运维的工作量.
最新的 JuiceFS 企业版 5.1 中, 镜像文件系统除了支持读取,还新增了可直接写入的功能。本文将探讨镜像文件系统的读写实现原理.
让我们设想这样一个场景,某用户的文件系统部署在北京,但北京地区的 GPU 资源供给不足,而该用户在上海还有可用的 GPU 资源。这时用户想在上海运行模型训练任务,有两个简单的方案:
综上所述,这两个简单的方案都无法令人满意。为此 JuiceFS 企业版提供了镜像文件系统功能。它允许用户为已有文件系统创建一个或多个完整的镜像,这些镜像会自动从源端同步元数据,这样在镜像区域的客户端可以就近访问文件系统,来得到高性能的体验。由于可以只镜像元数据,并且同步过程是自动的,因此相较于之前提到的方案二而言,镜像文件系统在成本与运维复杂性上都有明显的优势.
JuiceFS 企业版的架构与社区版相似,都包括客户端、对象存储以及元数据引擎。区别在于社区版的元数据引擎通常采用第三方数据库如 Redis、TiKV、MySQL 等,而企业版则配备了自研的高性能元数据服务,其中的元数据引擎由一个或多个 Raft 组组成,其架构图如下:
得益于元数据与数据分离的架构设计,用户在创建镜像文件系统时可以独立选择是否镜像元数据和是否镜像数据。两者皆配置镜像的架构如下:
此时,镜像的元数据服务其实跟源端的元数据服务同属一个 Raft 组,只是它们的角色是 learner。在源端发生元数据更新时,服务会自动推送变更日志到镜像端,并在镜像服务中进行回放。这样,镜像文件系统的存在并不会影响源端文件系统的性能表现,只是镜像的元数据版本会略落后一点点.
数据的镜像也是采用异步复制的方式,由指定配置的节点进行自动同步。不同的是,对镜像区域的客户端而言,它仅访问本区域的元数据,但是可以同时访问两个区域的对象存储。实际读取数据时,客户端优先从本区域读取;如果查找不到所需的对象,再尝试从源端区域读取.
一般而言,数据本身的体量较大,再拷贝一份的成本也比较高,因此另一种更推荐的方式是仅镜像元数据,并且在镜像区域构建一套分布式缓存组来提升读取数据的速度,示意如下:
JuiceFS 镜像文件系统推荐使用方法:两区域共用同一个对象存储,镜像区域搭建分布式缓存组来提升性能 。
这种使用方式尤其适合模型训练等可以提前准备数据集的场景。用户在执行训练任务前,先通过 juicefs warmup 命令将所需数据对象拉取到镜像区域的缓存组中,接下来的训练就能在镜像区域内完成,且性能与在源端(假设也配置了类似的分布式缓存组)基本一致.
在之前的版本中,镜像客户端默认为只读模式,因为镜像元数据本身只支持读取,所有的修改操作必须在源端执行。然而,随着用户需求的增加,我们注意到一些新的使用情况,例如在数据训练过程中产生的临时数据。用户希望避免维护两个不同的文件系统,并期望镜像端也能支持少量写操作.
为了满足这些需求,我们在 5.1 版本中引入了 “可写镜像文件系统” 功能。在设计这项功能时,我们主要考虑三个方面:首先是系统的稳定性,这是必须保证的;其次是两端数据的一致性;最后是写入的性能。 最初,我们探索的一种直接方案是允许元数据镜像也能处理写操作。然而,在开发中我们发现,当需要将两端的元数据更新进行合并时,会面临非常复杂的细节处理和一致性问题。因此我们还是维持 “仅源端元数据可写” 的设计。为了处理镜像客户端的写请求,有两个可选的方案:
方案一:客户端将写请求发送至镜像的元数据服务,然后由其转发到源端。源端接收到请求后开始执行操作,并在完成后将元数据同步回镜像端,并最终返回。这个方法的优点是客户端操作简单,只需发送请求并等待响应。然而,这样会使元数据服务的实现变得复杂,因为需要管理请求的转发和元数据的同步。此外,由于链路较长,任何环节的错误都可能导致请求处理出错.
方案二:客户端不仅连接镜像的元数据服务,还直接连接源端的元数据服务。客户端内部进行读写分离,读请求仍然发送至镜像端,但将写请求发送至源端。这种方法虽然使客户端的处理逻辑复杂化,但简化了元数据服务的实现,让它们仅需做很小的适配改动即可。对整个系统而言,这样的做法稳定性也更高.
考虑到服务的简洁性和可靠性,我们最终选择了方案二,具体如下图所示。相较于原来的架构而言,这个方案主要多了一条镜像客户端发送写请求到源端元数据服务的流程.
以下将以创建一个新文件(create 请求)为例对此流程进行详细的介绍。假设源端和镜像端的元数据服务分别是 A 和 B,镜像客户端为 C,请求的完成大致分为 5 步:
C 在第 4 步确认镜像版本已经达到 v1,或者第 5 步收到 wait OK 后返回给上层应用。无论哪种情况,都表示 B 已经包含了本次 create 的修改,因此后续 C 在读取时,就能访问到最新的元数据。另外,由于步骤 2 和 3 几乎是同时发生的,所以大部分情况下 wait 消息都能被立即处理并返回.
镜像客户端的读操作也有类似的检查版本的机制。具体而言,C 在发送读请求前,会先比较其缓存中源端服务和镜像端服务的元数据版本号;如果源端的版本号更新,则会先发送 wait 消息给 B,等到其版本也更新上来后再处理原来的读请求。遗憾的是,C 缓存的源端版本号并不一定是最新的(比如其长时间未发送过写请求的情况),也就是说该机制只是尽可能地让 C 能读到较新的数据,但并不保证其一定是最新的(可能会有小于 1 秒的滞后,与原有的只读镜像相同).
最后,我们通过一个稍复杂些的读写混合的例子,来简要说明使用 JuiceFS 镜像文件系统给用户带来的直接收益.
需求是客户端 C 希望在 /d1/d2/d3/d4 目录下创建一个新文件 newf。按照文件系统的设计,C 需要逐级查找路径上的每一个目录和文件,并在确认文件不存在后再发送创建请求。现假设 C 到 A 和 B 的网络延迟分别是 30ms 和 1ms,C 尚未建立元数据缓存,并且忽略 A 和 B 的请求处理时间.
使用镜像文件系统的情况:C 的读请求都由 B 处理,只有最后的创建文件请求需要发往 A。总耗时大概需要 1 * 2 * 6(mirror lookup) + 30 * 2(source create) + 1 * 2(mirror wait) = 74ms.
没有使用镜像文件系统的情况:如果直接在镜像区域挂载源文件系统,C 的每个请求都需要跟 A 交互,那么总耗时就需要 30 * 2 * 6(source lookup) + 30 * 2(source create) = 420ms,是前者的 5 倍还多.
在 AI 研究中,由于 GPU 资源的成本极高,多云架构已成为众多企业的标配。通过使用 JuiceFS 镜像文件系统,用户可创建一个或多个完整的文件系统镜像,这些镜像会自动从源端同步元数据,使得镜像区域的客户端能够就近访问文件,从而提供高性能并减少运维工作量.
在最新的 JuiceFS 5.1 版本中,我们对镜像文件系统进行了重要的优化,新增了允许写入的功能,使得企业能够在任何数据中心通过统一的命名空间访问数据。同时在保证数据一致性的前提下,享受就近缓存的加速效果。希望通过这篇文章分享的实现思路与尝试,为用户提供一些见解与启发.
最后此篇关于详解JuiceFS在多云架构下的数据同步与一致性的文章就讲到这里了,如果你想了解更多关于详解JuiceFS在多云架构下的数据同步与一致性的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
初学者 android 问题。好的,我已经成功写入文件。例如。 //获取文件名 String filename = getResources().getString(R.string.filename
我已经将相同的图像保存到/data/data/mypackage/img/中,现在我想显示这个全屏,我曾尝试使用 ACTION_VIEW 来显示 android 标准程序,但它不是从/data/dat
我正在使用Xcode 9,Swift 4。 我正在尝试使用以下代码从URL在ImageView中显示图像: func getImageFromUrl(sourceUrl: String) -> UII
我的 Ubuntu 安装 genymotion 有问题。主要是我无法调试我的数据库,因为通过 eclipse 中的 DBMS 和 shell 中的 adb 我无法查看/data/文件夹的内容。没有显示
我正在尝试用 PHP 发布一些 JSON 数据。但是出了点问题。 这是我的 html -- {% for x in sets %}
我观察到两种方法的结果不同。为什么是这样?我知道 lm 上发生了什么,但无法弄清楚 tslm 上发生了什么。 > library(forecast) > set.seed(2) > tts lm(t
我不确定为什么会这样!我有一个由 spring data elasticsearch 和 spring data jpa 使用的类,但是当我尝试运行我的应用程序时出现错误。 Error creatin
在 this vega 图表,如果我下载并转换 flare-dependencies.json使用以下 jq 到 csv命令, jq -r '(map(keys) | add | unique) as
我正在提交一个项目,我必须在其中创建一个带有表的 mysql 数据库。一切都在我这边进行,所以我只想检查如何将我所有的压缩文件发送给使用不同计算机的人。基本上,我如何为另一台计算机创建我的数据库文件,
我有一个应用程序可以将文本文件写入内部存储。我想仔细看看我的电脑。 我运行了 Toast.makeText 来显示路径,它说:/数据/数据/我的包 但是当我转到 Android Studio 的 An
我喜欢使用 Genymotion 模拟器以如此出色的速度加载 Android。它有非常好的速度,但仍然有一些不稳定的性能。 如何从 Eclipse 中的文件资源管理器访问 Genymotion 模拟器
我需要更改 Silverlight 中文本框的格式。数据通过 MVVM 绑定(bind)。 例如,有一个 int 属性,我将 1 添加到 setter 中的值并调用 OnPropertyChanged
我想向 Youtube Data API 提出请求,但我不需要访问任何用户信息。我只想浏览公共(public)视频并根据搜索词显示视频。 我可以在未经授权的情况下这样做吗? 最佳答案 YouTube
我已经设置了一个 Twilio 应用程序,我想向人们发送更新,但我不想回复单个文本。我只是想让他们在有问题时打电话。我一切正常,但我想在发送文本时显示传入文本,以确保我不会错过任何问题。我正在使用 p
我有一个带有表单的网站(目前它是纯 HTML,但我们正在切换到 JQuery)。流程是这样的: 接受用户的输入 --- 5 个整数 通过 REST 调用网络服务 在服务器端运行一些计算...并生成一个
假设我们有一个名为 configuration.js 的文件,当我们查看内部时,我们会看到: 'use strict'; var profile = { "project": "%Projec
这部分是对 Previous Question 的扩展我的: 我现在可以从我的 CI Controller 成功返回 JSON 数据,它返回: {"results":[{"id":"1","Sourc
有什么有效的方法可以删除 ios 中 CBL 的所有文档存储?我对此有疑问,或者,如果有人知道如何从本质上使该应用程序像刚刚安装一样,那也会非常有帮助。我们正在努力确保我们的注销实际上将应用程序设置为
我有一个 Rails 应用程序,它与其他 Rails 应用程序通信以进行数据插入。我使用 jQuery $.post 方法进行数据插入。对于插入,我的其他 Rails 应用程序显示 200 OK。但在
我正在为服务于发布请求的 API 调用运行单元测试。我正在传递请求正文,并且必须将响应作为帐户数据返回。但我只收到断言错误 注意:数据是从 Azure 中获取的 spec.js const accou
我是一名优秀的程序员,十分优秀!