惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Hacker News: Ask HN
Hacker News: Ask HN
Recent Commits to openclaw:main
Recent Commits to openclaw:main
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
C
Check Point Blog
S
Security Affairs
Hacker News - Newest:
Hacker News - Newest: "LLM"
S
Secure Thoughts
Recorded Future
Recorded Future
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
T
The Blog of Author Tim Ferriss
B
Blog
C
Cybersecurity and Infrastructure Security Agency CISA
Google DeepMind News
Google DeepMind News
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
A
Arctic Wolf
T
The Exploit Database - CXSecurity.com
Stack Overflow Blog
Stack Overflow Blog
T
Threat Research - Cisco Blogs
GbyAI
GbyAI
AWS News Blog
AWS News Blog
MongoDB | Blog
MongoDB | Blog
Y
Y Combinator Blog
Google Online Security Blog
Google Online Security Blog
T
Troy Hunt's Blog
I
InfoQ
L
LINUX DO - 热门话题
WordPress大学
WordPress大学
C
Cisco Blogs
G
GRAHAM CLULEY
The Register - Security
The Register - Security
A
About on SuperTechFans
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Schneier on Security
Schneier on Security
Project Zero
Project Zero
H
Hackread – Cybersecurity News, Data Breaches, AI and More
P
Privacy & Cybersecurity Law Blog
Cloudbric
Cloudbric
H
Hacker News: Front Page
小众软件
小众软件
雷峰网
雷峰网
The Hacker News
The Hacker News
www.infosecurity-magazine.com
www.infosecurity-magazine.com
T
Tor Project blog
博客园 - 聂微东
N
Netflix TechBlog - Medium
V
Vulnerabilities – Threatpost
The GitHub Blog
The GitHub Blog
腾讯CDC
P
Palo Alto Networks Blog
Scott Helme
Scott Helme

陈少文的网站

巨变与机遇的未来十年 Kubernetes 平台管理软件压力测试方案 使用镜像部署 Hexo 静态页面 终于等到你 - GitHub 镜像仓库服务(ghcr.io) 一起来学 Go --(6)Interface 一起来学 Go --(5)Goroutine 和 Channel 什么是函数式编程 如何在 Kubernetes 集群集成 Kata 柯里化与偏函数 使用 PyGithub 自动创建 Label 软件产品是团队能力的输出 Helm 2 、Helm 3 比较 IoT 变现 Kubernetes 中的 DNS 服务 国内的 Helm 镜像源 Harbor 使用自签证书支持 Https 访问 DevOps 工具链之 Prow 如何使用 kfctl 安装 Kubeflow VS Code 无法下载 Go 插件的工具包 工程师更应具有服务精神 你不知道的 Docker 使用技巧 使用 Docker 运行 Tensorflow 论中国 什么是左移 如何清空 Git 仓库全部历史记录 一禅小和尚 有风吹过厨房 时间的玫瑰 如何在 CentOS 安装 GPU 驱动 开发 Tips(19) 使用 Velero 备份 Kubernetes 集群 Kubernetes Cheat Sheet 开发 Tips(18) 如何构建一个 Java 工程 开发 Tips(17) KubeSpray 安装 Kubernetes 报错 ip in ansible_all_ipv4_addresses 基于 Kubernetes 和 Jenkins 搭建自动化测试系统 在 Kubernetes 上动态创建 Jenkins Slave 使用 Jenkins 进行服务拨测 开发 Tips(16) Kubernetes 签发 Ingress 证书及日常故障运维 Kubernetes 中 Deployment 的基本操作 Kubernetes 中的证书 如何使用 KubeBuilder 开发一个 Operator Kubernetes 1.6.0 安装问题汇总 镜像管理工具 -- Harbor 开发 Tips(15) Docker 如何拉取镜像 开发 Tips(14) 使用 Helm 安装 harbor 开发 Tips(13) 使用 S2I 构建云原生应用 在 Kubernetes 中使用 emptyDir、hostPath、localVolume 开发 Tips(12) 开发 Tips(11) 代码质量分析工具 SonarQube 使用 Kubeadm 安装 Kubernetes 集群 一起来学 Go --(4)常用函数 Kubernetes 中的 Ceph Kubernetes 之 Volumes Kubernetes 之 Labels、Selectors 开发 Tips(10) 开源正在重构商业模式 Kubernetes 之网络 Kubernetes 之 API 使用 Helm 和 Operator 快速部署 Prometheus Kubernetes 复杂有状态应用管理框架 -- Operator Kubernetes 的包管理器 -- Helm 一起来学 Go --(3)Go Modules 如何一步一步地优化博客方案 kubectl 实用指南 Kubernetes 中的基本概念 搭建远程 Kubernetes 开发环境 大公司和小公司的 ToB 思路 开发 Tips(9) Go 入门指南 一起来学 Go --(2)数据与逻辑结构 如何预防 Web 富文本中的 XSS 攻击 django-xss-cleaner 云工作时代 一起来学 Go --(1)背景与特点 SaaS 开发团队的不同阶段 你不知道的 Git 使用技巧 输出既服务 微服务设计 继续奔跑 开发 Tips(8) 从账户安全到二次验证 Django 性能之数据库查询优化 Django 性能之分库分表 敏捷开发之研发流程 打造一致性的团队 开发 Tips(7) Pytest 进阶学习之 Mock PaaS 部署之 buildpack Go 开发配置 领域输出才是 PaaS 的核心竞争力 Pytest 入门学习 开发 Tips(6) 如何使用 Jenkins、Docker、GitLab 搭建 Django 自动化部署流程
在 Kubernetes 中使用 Fluid 挂载 3FS 存储及性能测试
微信公众号 · 2025-03-09 · via 陈少文的网站

1. 为什么要将 3FS 对接到 Fluid

3FS 是 DeepSeek 开源的分布式存储系统,因其极优异的性能测试结果,而被津津乐道,star 量快速飙升。

我所在的团队也对 3FS 展开了技术上的跟踪,寻找合适的应用场景,发挥 AI 硬件基础设施的最大价值。

我们线上推理、训练服务使用的存储系统都是通过 Fluid 进行管理的,使用 Fluid 可以很方便地创建出 PVC,在使用存储的节点上自动进行挂载,十分方便。

在对接 Fluid 之前,我们已经在 IB + H100 环境下部署好了 3FS 存储系统,并进行了一些测试,为了方便进行更多的测试、创建存储进行使用,我们需要使用 Fluid 将 3FS 对接到 Kubernetes 中。

2. 编译 3FS 的 builder 镜像

2.1 为什么要单独提供 3FS 的 builder 镜像

  • 提供容器化的 3FS 编译环境

避免安装依赖时,影响主机的本地配置。

同时,推荐使用服务器环境进行编译,需要的编译资源很多。低内存的配置会直接导致编译失败,CPU 核数太少会导致编译时间过长。

  • 提供容器化的 3FS 运行环境

方便部署,3FS 依赖的动态库文件很多,在 builder 镜像中能够提供完整的依赖环境。

只需要拷贝编译好的二进制文件到 builder 镜像中,就可以直接运行。

2.2 编写 Dockerfile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# Base image
FROM ubuntu:22.04

# Arguments
ARG FOUNDATIONDB_TAG=7.1.26
ARG FOUNDATIONDB_VERSION=${FOUNDATIONDB_TAG}-1
ARG LIBFUSE_TAG=fuse-3.16.1
ARG LIBFUSE_VERSION=3.16.1

# Install system dependencies and build tools
RUN apt update && \
    apt install -y \
        infiniband-diags cmake libuv1-dev liblz4-dev liblzma-dev libdouble-conversion-dev \
        libprocps-dev libdwarf-dev libunwind-dev libaio-dev libgflags-dev \
        libgoogle-glog-dev libgtest-dev libgmock-dev clang-format-14 clang-14 \
        clang-tidy-14 lld-14 libgoogle-perftools-dev google-perftools libssl-dev \
        ccache gcc-12 g++-12 libboost-all-dev git meson ninja-build lsb-release wget && \
    wget https://apache.jfrog.io/artifactory/arrow/$(lsb_release --id --short | tr 'A-Z' 'a-z')/apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb && \
    apt install -y -V ./apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb && \
    apt update && \
    apt install -y -V libarrow-dev && \
    rm -rf /var/lib/apt/lists/* apache-arrow-apt-source-latest-$(lsb_release --codename --short).deb

RUN wget https://raw.githubusercontent.com/Mellanox/container_scripts/refs/heads/master/ibdev2netdev -O /usr/sbin/ibdev2netdev && \
chmod +x /usr/sbin/ibdev2netdev
# Install Rust
RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y

# Install FoundationDB client
RUN wget https://github.com/apple/foundationdb/releases/download/${FOUNDATIONDB_TAG}/foundationdb-clients_${FOUNDATIONDB_VERSION}_amd64.deb && \
    dpkg -i ./foundationdb-clients_${FOUNDATIONDB_VERSION}_amd64.deb && \
    rm -f foundationdb-clients_${FOUNDATIONDB_VERSION}_amd64.deb

# Build and install libfuse
RUN wget https://github.com/libfuse/libfuse/releases/download/${LIBFUSE_TAG}/fuse-${LIBFUSE_VERSION}.tar.gz && \
    tar -zxvf fuse-${LIBFUSE_VERSION}.tar.gz && \
    cd fuse-${LIBFUSE_VERSION} && \
    mkdir build && \
    cd build && \
    meson setup .. && \
    ninja && \
    ninja install && \
    cd ../.. && \
    rm -rf fuse-${LIBFUSE_VERSION} fuse-${LIBFUSE_VERSION}.tar.gz

# Set up environment variables
ENV PATH="/root/.cargo/bin:${PATH}"

WORKDIR /app

2.3 编译并推送镜像

1
docker build -t shaowenchen/3fs-builder:latest . --push

如果使用的是 nerdctl 进行编译,还需要配置一下 BuildKit,参考 使用 Nerdctl 构建多架构镜像

3. 制作 ThinRuntime 镜像

Fluid 提供了一种快速对接 mount 类型存储的方式就是 ThinRuntime。Fluid 提供的存储配置、管理能力,就可以快速赋能给新的存储系统。

3.1 编写 fluid_config_init.py 脚本

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#!/usr/bin/env python

import json

rawStr = ""
try:
    with open("/etc/fluid/config/config.json", "r") as f:
        rawStr = f.readlines()
except:
    pass

if rawStr == "":
    try:
        with open("/etc/fluid/config.json", "r") as f:
            rawStr = f.readlines()
    except:
        pass

rawStr = rawStr[0]

script = """
#!/bin/sh
set -ex
# xxxxx@RDMA://0.0.0.0:8000
MNT_FROM=$mountPoint
TOKEN=$(echo $MNT_FROM | awk -F'@' '{print $1}')
RDMA=$(echo $MNT_FROM | awk -F'@' '{print $2}' | awk -F'://' '{print $2}')
RDMA="RDMA://${RDMA}"

echo $TOKEN > /opt/3fs/etc/token.txt

sed -i "s#RDMA://0.0.0.0:8000#${RDMA}#g" /opt/3fs/etc/hf3fs_fuse_main_launcher.toml

CLUSTER_ID=$clusterID
sed -i "s/^cluster_id.*/cluster_id = '${CLUSTER_ID:-default}'/" /opt/3fs/etc/hf3fs_fuse_main_launcher.toml

DEVICE_FILTER=$deviceFilter
if [[ -n "${DEVICE_FILTER}" ]]; then
  QUOTED_DEVICE_FILTER=$(echo ${DEVICE_FILTER} | sed "s/\\([^,]*\\)/'\\1'/g")
  sed -i "s|device_filter = \\[\\]|device_filter = [${QUOTED_DEVICE_FILTER}]|g" /opt/3fs/etc/hf3fs_fuse_main_launcher.toml
fi

MNT_TO=$targetPath
trap "umount ${MNT_TO}" SIGTERM
mkdir -p ${MNT_TO}
sed -i "s#/3fs/stage#${MNT_TO}#g" /opt/3fs/etc/hf3fs_fuse_main_launcher.toml

cat /opt/3fs/etc/hf3fs_fuse_main_launcher.toml

/opt/3fs/bin/hf3fs_fuse_main --launcher_cfg /opt/3fs/etc/hf3fs_fuse_main_launcher.toml
"""

obj = json.loads(rawStr)

with open("/mount-3fs.sh", "w") as f:
    f.write('mountPoint="%s"\n' % obj["mounts"][0]["mountPoint"])
    f.write('targetPath="%s"\n' % obj["targetPath"])
    f.write('clusterID="%s"\n' % obj["mounts"][0]["options"]["clusterID"])
    f.write('deviceFilter="%s"\n' % obj["mounts"][0]["options"]["deviceFilter"])
    f.write(script)

这段脚本的作用就是将 Fluid 动态提供的参数,渲染到 3FS 的配置文件中,然后启动 3FS Fuse 服务。

从 Fluid v1.1 版本开始,Fluid 使用 /etc/fluid/config/config.json 作为配置文件,而不是更早版本中使用的 /etc/fluid/config.json 文件。为了兼容不同 Fluid 版本使用的配置文件路径不同,我在脚本中做了一些兼容处理。

3.2 编写 entrypoint.sh 脚本

1
2
3
4
5
6
7
#!/usr/bin/env bash
set +x

echo "sleep inf" > /mount-3fs.sh
python3 /fluid_config_init.py
chmod u+x /mount-3fs.sh
bash /mount-3fs.sh

3.3 编译 hf3fs_fuse_main

  • 启动 3FS builder 容器
1
docker run -it --rm -v $(pwd):/app shaowenchen/demo:3fsbuilder bash
  • 克隆 3FS 代码
1
2
3
git clone https://github.com/deepseek-ai/3FS
cd 3FS
git submodule update --init --recursive
  • 应用补丁
  • 编译
1
cmake -S . -B build -DCMAKE_CXX_COMPILER=clang++-14 -DCMAKE_C_COMPILER=clang-14 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_EXPORT_COMPILE_COMMANDS=ON

这里的 -j 100 是为了加快编译速度,具体的值可以根据自己的 CPU 机器配置来调整,3FS 社区设置的是 32。

1
cmake --build build -j 100
  • 退出容器查看产物
1
2
3
4
ls 3FS/build/bin/

admin_cli    hf3fs_fuse_main  mgmtd_main      monitor_collector_main  storage_bench
hf3fs-admin  meta_main        migration_main  simple_example_main     storage_main

对接 Fluid 时,只需要 hf3fs_fuse_main 二进制文件即可。

3.4 准备 hf3fs_fuse_main_launcher.toml 配置文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
allow_other = true
cluster_id = 'stage'
mountpoint = '/3fs/stage'
token_file = '/opt/3fs/etc/token.txt'

[client]
default_compression_level = 0
default_compression_threshold = '128KB'
default_log_long_running_threshold = '0ns'
default_report_metrics = false
default_send_retry_times = 1
default_timeout = '1s'
enable_rdma_control = false
force_use_tcp = false

[client.io_worker]
num_event_loop = 1
rdma_connect_timeout = '5s'
read_write_rdma_in_event_thread = false
read_write_tcp_in_event_thread = false
tcp_connect_timeout = '1s'
wait_to_retry_send = '100ms'

[client.io_worker.connect_concurrency_limiter]
max_concurrency = 4

[client.io_worker.ibsocket]
buf_ack_batch = 8
buf_signal_batch = 8
buf_size = 16384
drain_timeout = '5s'
drop_connections = 0
event_ack_batch = 128
max_rd_atomic = 16
max_rdma_wr = 128
max_rdma_wr_per_post = 32
max_sge = 1
min_rnr_timer = 1
record_bytes_per_peer = false
record_latency_per_peer = false
retry_cnt = 7
rnr_retry = 0
send_buf_cnt = 32
sl = 0
start_psn = 0
timeout = 14

[client.io_worker.transport_pool]
max_connections = 1

[client.processor]
enable_coroutines_pool = true
max_coroutines_num = 256
max_processing_requests_num = 4096
response_compression_level = 1
response_compression_threshold = '128KB'

[client.rdma_control]
max_concurrent_transmission = 64

[client.thread_pool]
bg_thread_pool_stratetry = 'SHARED_QUEUE'
collect_stats = false
enable_work_stealing = false
io_thread_pool_stratetry = 'SHARED_QUEUE'
num_bg_threads = 2
num_connect_threads = 2
num_io_threads = 2
num_proc_threads = 2
proc_thread_pool_stratetry = 'SHARED_QUEUE'

[ib_devices]
allow_no_usable_devices = false
allow_unknown_zone = true
default_network_zone = 'UNKNOWN'
default_pkey_index = 0
default_roce_pkey_index = 0
default_traffic_class = 0
device_filter = []
fork_safe = true
prefer_ibdevice = true
skip_inactive_ports = true
skip_unusable_device = true
subnets = []

[mgmtd_client]
accept_incomplete_routing_info_during_mgmtd_bootstrapping = true
auto_extend_client_session_interval = '10s'
auto_heartbeat_interval = '10s'
auto_refresh_interval = '10s'
enable_auto_extend_client_session = true
enable_auto_heartbeat = false
enable_auto_refresh = true
mgmtd_server_addresses = ["RDMA://0.0.0.0:8000"]
work_queue_size = 100

配置中需要注意的有两点:

  • RDMA 地址,最终会由 Fluid 动态注入,在镜像中的值应该能被唯一识别,方便进行 sed 替换
  • device_filter 为空时,默认会使用全部 RDMA 设备,可能导致 IB 和 RoCE 设备混用,最终挂载失败

3.5 编写 Dockerfile

1
2
3
4
5
6
7
8
9
FROM shaowenchen/demo:3fsbuilder
RUN apt-get install -y python3
COPY bin /opt/3fs/bin
RUN chmod +x /opt/3fs/bin/*  && mkdir -p /var/log/3fs
COPY etc /opt/3fs/etc
COPY ./fluid_config_init.py /
COPY ./entrypoint.sh /usr/local/bin/
RUN chmod +x /usr/local/bin/entrypoint.sh
ENTRYPOINT []

3.6 编写并推送 ThinRuntime 镜像

  • 目录结构
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
tree -L 3 .

.
├── Dockerfile
├── bin
│   └── hf3fs_fuse_main
├── entrypoint.sh
├── etc
│   ├── hf3fs_fuse_main_launcher.toml
│   └── token.txt
└── fluid_config_init.py

token.txt 在镜像中是空的。

  • 编译并推送 ThinRuntime 镜像
1
docker build -t shaowenchen/demo:fluid-3fs  .

4. 使用 Fluid 挂载 3FS 存储

4.1 创建 ThinRuntimeProfile

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
kubectl apply -f - <<EOF
apiVersion: data.fluid.io/v1alpha1
kind: ThinRuntimeProfile
metadata:
  name: 3fs
spec:
  fileSystemType: 3fs
  fuse:
    image: shaowenchen/demo:fluid-3fs
    imageTag: latest
    imagePullPolicy: Always
    command:
      - "/usr/local/bin/entrypoint.sh"
EOF

4.2 创建 Dataset

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
kubectl apply -f - <<EOF
apiVersion: data.fluid.io/v1alpha1
kind: Dataset
metadata:
  name: demo-3fs
spec:
  mounts:
  - mountPoint: my3fsTOKEN@RDMA://x.x.x.x:8000
    name: demo-3fs
    options:
      clusterID: ds3fs
      deviceFilter: ""
EOF

这里的 mountPoint 是由 token 和 RDMA 地址组成的,token 是 3FS 的认证信息,RDMA 地址是 3FS 的服务地址。

4.3 创建 ThinRuntime

1
2
3
4
5
6
7
8
kubectl apply -f - <<EOF
apiVersion: data.fluid.io/v1alpha1
kind: ThinRuntime
metadata:
  name: demo-3fs
spec:
  profileName: 3fs
EOF

4.4 创建测试 Pod

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
kubectl apply -f - <<EOF
apiVersion: v1
kind: Pod
metadata:
  name: demo-3fs
spec:
  containers:
    - name: demo-3fs
      image: shaowenchen/demo:ubuntu
      volumeMounts:
        - mountPath: /data
          name: demo-3fs
  volumes:
    - name: demo-3fs
      persistentVolumeClaim:
        claimName: demo-3fs
EOF

5. 性能测试

3FS 在 DD 下的测试数据并不好,这里为了方便观测 RDMA 、SSD 的极限性能,使用了 FIO 工具进行测试。目前,我们尝试 3FS 在各种场景下的适用性,后面会专门写一篇文章输出测试数据。

  • 进入测试 Pod
1
kubectl exec -it demo-3fs -- bash
  • 安装 FIO
1
2
apt-get update
apt-get install -y fio
  • 主机 VS Pod 读

主机上

1
2
3
4
fio -numjobs=128 -fallocate=none -iodepth=2 -ioengine=libaio -direct=1 -rw=read -bs=4M --group_reporting -size=100M -time_based -runtime=30 -name=2depth_128file_4M_direct_read_bw -directory=/3fs/stage/fio-read

Run status group 0 (all jobs):
   READ: bw=12.0GiB/s (12.9GB/s), 12.0GiB/s-12.0GiB/s (12.9GB/s-12.9GB/s), io=361GiB (388GB), run=30029-30029msec

Pod 上

fio -numjobs=128 -fallocate=none -iodepth=2 -ioengine=libaio -direct=1 -rw=read -bs=4M --group_reporting -size=100M -time_based -runtime=30 -name=2depth_128file_4M_direct_read_bw -directory=/data/fio-read

Run status group 0 (all jobs):
   READ: bw=12.1GiB/s (12.0GB/s), 12.1GiB/s-12.1GiB/s (12.0GB/s-12.0GB/s), io=363GiB (390GB), run=30030-30030msec

两个测试结果基本一致,读取速度都在 12GB/s 左右,正好是测试环境全部磁盘的读取极限,2 块盘,单盘读取速度 6GB/s。

  • 主机 VS Pod 写

主机上

1
2
3
4
fio -numjobs=128 -fallocate=none -iodepth=2 -ioengine=libaio -direct=1 -rw=write -bs=4M --group_reporting -size=100M -time_based -runtime=30 -name=2depth_128file_4M_direct_write_bw -directory=/3fs/stage/fio-write

Run status group 0 (all jobs):
  WRITE: bw=1623MiB/s (1702MB/s), 1623MiB/s-1623MiB/s (1702MB/s-1702MB/s), io=47.9GiB (51.5GB), run=30238-30238msec

Pod

1
2
3
4
fio -numjobs=128 -fallocate=none -iodepth=2 -ioengine=libaio -direct=1 -rw=write -bs=4M --group_reporting -size=100M -time_based -runtime=30 -name=2depth_128file_4M_direct_write_bw -directory=/data/fio-write

Run status group 0 (all jobs):
  WRITE: bw=1610MiB/s (1688MB/s), 1610MiB/s-1610MiB/s (1688MB/s-1688MB/s), io=47.6GiB (51.1GB), run=30259-30259msec

两个测试结果基本一致,写入速度都在 1.6GB/s 左右,与测试环境单盘 4GB/s 的写入速度有些差距。

6. 总结

本篇介绍了如何将 3FS 对接到 Fluid 中,主要内容如下:

  • 为了方便编译和运行 3FS,最好打包一个 builder 镜像,shaowenchen/3fs-builder:latest
  • Fluid 提供了一种快速对接 mount 类型存储的方式就是 ThinRuntime,文中提供了 3FS 的 ThinRuntime 镜像 shaowenchen/demo:fluid-3fs
  • 通过 ThinRuntimeProfile、Dataset、ThinRuntime 的创建,可以将 3FS 挂载到 Pod 中,避免手动挂载的繁琐操作
  • 通过性能测试发现,主机和 Pod 挂载的 3FS 在读取速度上基本一致,可以放心使用

文中相关脚本已经整理在 GitHub 上。