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、作用:

      1. 生成文件元数据
      2. 切割文件为等大的Block (注意JuiceFS 如何存储文件的三个概念Chunk、Slice、Block)

假设我们有一个名为 example.txt 的文件,其元数据包括:

  1. 文件名(File Name): 文件的名称,即 "example.txt"。
  2. 文件大小(File Size): 文件的大小,例如 1 MB。
  3. 创建时间(Creation Time): 文件的创建时间戳,表示文件创建的日期和时间。
  4. 修改时间(Modification Time): 文件的修改时间戳,表示文件上次修改的日期和时间。
  5. 权限和访问控制(Permissions): 文件的访问权限,例如哪些用户或应用程序有权访问、读取或写入文件。
  6. 文件路径(File Path): 文件在文件系统中的路径,例如 "/documents/example.txt"。
  7. 文件类型(File Type): 文件的类型,例如文本文件、图像文件等。
  8. 文件拥有者(File Owner): 文件的拥有者,即创建文件的用户或应用程序。
  9. 文件版本(File Version): 如果支持版本控制,可能会包括文件的版本信息。

这些元数据信息帮助 JuiceFS 管理文件和目录,以及支持文件的访问和操作。例如,当用户请求读取 example.txt 文件时,JuiceFS 使用元数据信息来确定文件的位置,并将文件内容提供给用户。

3、JuiceFS 如何存储文件(三个流程Chunk、Slice、Block)

流程:

  1. JuiceFS生成等大的Chunk(64MB)
  2. 根据文件写入情况,在Chunk里生成大小不一的Slice
  3. 整合大小不一的Slice为等大的Block(默认大小为4MB),我们使用的为16MB

假设你有一个名为 example.txt 的文本文件,文件大小为 1 MiB,你希望将其上传到 JuiceFS。在上传的过程中,你进行了以下操作:

  1. 开始上传: 你开始上传 example.txt
  2. 初始 Slice: JuiceFS 创建了一个初始的 Slice,并将前一部分数据(例如,最初的 100 KiB)写入其中。
  3. 不连续的写入: 然后,你停止了上传,没有一次性上传整个文件,而是分为多个步骤。例如,你只上传了前 100 KiB 部分。
  4. 创建新 Slice: 一段时间后,你继续上传,这次上传了文件的下一部分(例如,接下来的 200 KiB)。由于当前的 Slice 已满,JuiceFS 创建了一个新的 Slice 来存储这部分数据。
  5. 继续写入: 你可能多次停止上传,然后再次继续,每次上传一部分数据。每次 Slice 都会根据需要创建,以存储上传的数据。
  6. 最终结果: 最终,整个文件(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(一个开源的对象存储服务器)

Logo

更多推荐