1、关于JuiceFS整合MinIO的解析(分布式文件系统)
一个分布式文件系统,JuiceFS 会将数据格式化以后存储在对象存储,同时会将文件的元数据存储在元数据引擎。JuiceFS 采用多引擎设计,目前已支持 Redis、TiKV、MySQL/MariaDB、PostgreSQL、SQLite 等作为元数据服务引擎。
·
JuiceFS
1、概念:
一个分布式文件系统,JuiceFS 会将数据格式化以后存储在对象存储,同时会将文件的元数据存储在元数据引擎。在这个过程中,Chunk、Slice、Block 是三个重要的概念:
数据存储(Data Storage):(MinIO)
- 对象存储,也就是存储我们的数据(我们这里使用的就是MinIO),JuiceFS 支持几乎所有的公有云对象存储,同时也支持 OpenStack Swift、Ceph、MinIO 等私有化的对象存储,
- MinIO 是一个对象存储服务器,它可以存储各种类型的数据,包括文本、图像、视频、日志文件等。每个对象都有一个唯一的键(Key),通过该键可以检索对象。
元数据引擎(Metadata Engine):(数据库PG、Mysql)
- 常规文件系统的元数据:文件名、文件大小、权限信息、创建修改时间、目录结构、文件属性、符号链接、文件锁等。
- 文件数据的索引:文件的数据分配和引用计数、客户端会话等。
- 也就是用数据库存储JuiceFS产生的元数据
JuiceFS 采用多引擎设计,目前已支持 Redis、TiKV、MySQL/MariaDB、PostgreSQL、SQLite 等作为元数据服务引擎
2、作用:
-
-
- 生成文件元数据
- 切割文件为等大的Block (注意JuiceFS 如何存储文件的三个概念Chunk、Slice、Block)
-
假设我们有一个名为 example.txt
的文件,其元数据包括:
- 文件名(File Name): 文件的名称,即 "example.txt"。
- 文件大小(File Size): 文件的大小,例如 1 MB。
- 创建时间(Creation Time): 文件的创建时间戳,表示文件创建的日期和时间。
- 修改时间(Modification Time): 文件的修改时间戳,表示文件上次修改的日期和时间。
- 权限和访问控制(Permissions): 文件的访问权限,例如哪些用户或应用程序有权访问、读取或写入文件。
- 文件路径(File Path): 文件在文件系统中的路径,例如 "/documents/example.txt"。
- 文件类型(File Type): 文件的类型,例如文本文件、图像文件等。
- 文件拥有者(File Owner): 文件的拥有者,即创建文件的用户或应用程序。
- 文件版本(File Version): 如果支持版本控制,可能会包括文件的版本信息。
这些元数据信息帮助 JuiceFS 管理文件和目录,以及支持文件的访问和操作。例如,当用户请求读取 example.txt
文件时,JuiceFS 使用元数据信息来确定文件的位置,并将文件内容提供给用户。
3、JuiceFS 如何存储文件(三个流程Chunk、Slice、Block)
流程:
- JuiceFS生成等大的Chunk(64MB)
- 根据文件写入情况,在Chunk里生成大小不一的Slice
- 整合大小不一的Slice为等大的Block(默认大小为4MB),我们使用的为16MB
假设你有一个名为 example.txt
的文本文件,文件大小为 1 MiB,你希望将其上传到 JuiceFS。在上传的过程中,你进行了以下操作:
- 开始上传: 你开始上传
example.txt
。 - 初始 Slice: JuiceFS 创建了一个初始的 Slice,并将前一部分数据(例如,最初的 100 KiB)写入其中。
- 不连续的写入: 然后,你停止了上传,没有一次性上传整个文件,而是分为多个步骤。例如,你只上传了前 100 KiB 部分。
- 创建新 Slice: 一段时间后,你继续上传,这次上传了文件的下一部分(例如,接下来的 200 KiB)。由于当前的 Slice 已满,JuiceFS 创建了一个新的 Slice 来存储这部分数据。
- 继续写入: 你可能多次停止上传,然后再次继续,每次上传一部分数据。每次 Slice 都会根据需要创建,以存储上传的数据。
- 最终结果: 最终,整个文件(1 MiB)的数据被上传并分布在多个不连续的 Slice 中,每个 Slice 包含了文件的一部分。这些 Slice 按照写入的顺序创建,并且它们的长度根据数据的上传方式而变化。
也就是slice和我们写入状态有关,是不是连续写入的,不连续写入就存在多个Slice了, 100 KiB、 200 KiB、300KiB、400KiB ,这样几个Slice,也就是写入一次就生成一个Slice。
4、Slice的碎片处理流程(异步合并)
- 问题:Slice 的排列模式可以是多种多样的:如果文件在相同区域被反复修改,Slice 之间会发生重叠。如果在互不重合的区域进行写入,Slice 中间会有间隔。
- 解决方案:对于每一处文件位置,都会读到该位置最新写入的 Slice,用下图可以更加直观地理解:Slice 虽然会相互堆叠,但读文件一定是“从上往下看”,因此一定会看到该文件的最新状态。
最后的成果:
MinIO
- 概念:可以存储各种类型的数据,包括文本、图像、视频、日志文件等。每个对象都有一个唯一的键(Key),通过该键可以检索对象。
- 我们通过JuiceFS 的元数据找到MinIO中的对应文件
JuiceFS+MinIO实例
import org.juicefs.client.FileSystem;
import org.juicefs.client.FileSystemConfig;
import org.juicefs.client.Path;
public class JuiceFSMinIOExample {
public static void main(String[] args) {
try {
// 配置 JuiceFS 文件系统
FileSystemConfig config = new FileSystemConfig();
config.set("juice.backend", "minio");
config.set("juice.minio.endpoint", "https://your-minio-server.com");
config.set("juice.minio.accessKey", "YOUR_ACCESS_KEY");
config.set("juice.minio.secretKey", "YOUR_SECRET_KEY");
config.set("juice.minio.bucket", "juicefs-bucket");
FileSystem fs = FileSystem.create(config);
// 在 JuiceFS 中创建一个文件
Path filePath = new Path("/example.txt");
fs.touch(filePath);
// 写入数据到文件
String data = "Hello, MinIO!";
fs.writeString(filePath, data);
// 上传文件到 MinIO 存储桶
byte[] fileData = fs.readBytes(filePath);
MinioClient minioClient = MinioClient.builder()
.endpoint("https://your-minio-server.com")
.credentials("YOUR_ACCESS_KEY", "YOUR_SECRET_KEY")
.build();
minioClient.putObject("juicefs-bucket", "example.txt", new ByteArrayInputStream(fileData), null);
System.out.println("Data uploaded to MinIO: " + "juicefs-bucket/example.txt");
// 从 MinIO 中下载文件
InputStream minioInputStream = minioClient.getObject("juicefs-bucket", "example.txt");
// 处理 minioInputStream 中的数据...
// 从 JuiceFS 中读取文件
String readData = fs.readString(filePath);
System.out.println("Data read from JuiceFS: " + readData);
} catch (Exception e) {
e.printStackTrace();
}
}
}
三大组成
- JuiceFS
- 数据库PG
- 存储系统MinIO(一个开源的对象存储服务器)
更多推荐
所有评论(0)