1. 部署方案
在开始容器化部署之前,先提几点要求:
- 为了简化交付,只需要一个镜像
- 为了可靠性,尽可能多副本部署
- 通过不同的参数启动不同的服务
- 通过环境变量注入配置,渲染到配置文件中
下面是 DeepSeek 3FS 的部署方案:

需要部署:
- 一个 Monitor 用来收集监控数据,数据存储在 ClickHouse 中
- 一个 Admin CLI 提供集群管理的终端,每个组件都需要通过 Admin CLI 提交配置
- 三个 MgmtD 用来管理集群,将组件、心跳等信息存储在 FoundationDB 中
- 三个 Meta 用来提供 Chain 和文件信息,数据存储在 FoundationDB 中
- 尽可能多的 Storage 用来存储数据, 文件以 Chunk 的形式存储在磁盘目录中
- 若干 Fuse 用来提供 POSIX 文件系统接口,将数据存储在应用层,如果能基于 USRBIO 用户态的接口调用存储服务,相较于 Fuse 会有 3-5 倍的性能提升。
这些服务部署的主机全都需要 RDMA 网络(不仅是支持 RDMA 的网卡,还要交换机支持 RDMA)连接起来。消费 3FS 存储服务的应用程序也需要运行在支持 RDMA 的主机上。
默认情况下 MgmtD 和 Storage 服务有端口冲突,需要部署在不同的主机上。可能大部分团队并没有规划专用的 RDMA 存储集群,使用 3FS 时要和训练、推理任务部署在一起,以充分利用资源。本着尽可能节约资源的原则,将 Monitor 与 Mgmd 部署在一起;为了方便管理集群部署地 Admin CLI 也与 Mgmd 部署在一起。
2. 编译 3FS 镜像
1
| nerdctl run -it --rm -v $(pwd):/app shaowenchen/demo-3fsbuilder:latest bash
|
基础镜像使用的是 Ubuntu 22.04,我也制作了基于 Ubuntu 20.04 的镜像 shaowenchen/demo-3fsbuilder:latest.2004
。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| ARG BASE_IMAGE=shaowenchen/demo-3fsbuilder:latest
FROM ${BASE_IMAGE} as builder
RUN git clone https://github.com/deepseek-ai/3FS && \
cd 3FS && \
git submodule update --init --recursive && \
./patches/apply.sh && \
cmake -S . -B build -DCMAKE_CXX_COMPILER=clang++-14 -DCMAKE_C_COMPILER=clang-14 -DCMAKE_BUILD_TYPE=RelWithDebInfo -DCMAKE_EXPORT_COMPILE_COMMANDS=ON && \
cmake --build build -j 100
FROM ${BASE_IMAGE}
COPY --from=builder /app/3FS/build/bin /opt/3fs/bin
COPY --from=builder /app/3FS/configs /opt/3fs/etc
COPY --from=builder /app/3FS/deploy /opt/3fs/deploy
COPY --from=builder /app/3FS/build/third_party/jemalloc/lib/libjemalloc.so.2 /lib/x86_64-linux-gnu/
RUN mkdir -p /var/log/3fs/ && \
wget -O /opt/3fs/bin/3fs-entrypoint.sh https://raw.githubusercontent.com/shaowenchen/demo/master/3fs-deploy/3fs-entrypoint.sh && \
chmod +x /opt/3fs/bin/3fs-entrypoint.sh
WORKDIR /opt/3fs/bin
|
默认是 Ubuntu 22.04
1
| nerdctl build --build-arg BASE_IMAGE=shaowenchen/demo-3fsbuilder -t shaowenchen/demo-3fs .
|
也可以使用 Ubuntu 20.04
1
| nerdctl build --build-arg BASE_IMAGE=shaowenchen/demo-3fsbuilder:latest.2004 -t shaowenchen/demo-3fs:latest.2004 .
|
不方便编译的同学,可以直接去镜像中拿二进制和依赖包,如果访问 Dockerhub 网络不通,可以使用 registry.cn-beijing.aliyuncs.com/shaowenchen/demo-3fs 镜像地址。
3. 部署依赖的中间件
3.1 ClickHouse
1
| kubectl apply -f https://raw.githubusercontent.com/shaowenchen/hubimage/refs/heads/main/storage/clickhouse-operator-0.24.5/crd.install-bundle.yaml
|
1
| kubectl apply -f https://raw.githubusercontent.com/shaowenchen/hubimage/refs/heads/main/storage/clickhouse-operator-0.24.5/deploy.install-bundle.yaml
|
1
| kubectl apply -f https://raw.githubusercontent.com/shaowenchen/hubimage/refs/heads/main/storage/clickhouse-operator-0.24.5/cluster.yaml
|
在 yaml 中设置有 clickhouse 的访问凭证信息。
1
2
3
4
5
6
7
| kubectl get pod -l clickhouse.altinity.com/cluster=test-cluster
NAME READY STATUS RESTARTS AGE
chi-test-cluster-test-cluster-0-0-0 1/1 Running 0 7m53s
chi-test-cluster-test-cluster-0-1-0 1/1 Running 0 3m9s
chi-test-cluster-test-cluster-1-0-0 1/1 Running 0 7m55s
chi-test-cluster-test-cluster-1-1-0 1/1 Running 0 3m14s
|
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
| kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: chi-test-cluster-exposed
namespace: default
labels:
clickhouse.altinity.com/cluster: test-cluster
spec:
type: NodePort
selector:
clickhouse.altinity.com/cluster: test-cluster
ports:
- name: tcp
port: 9000
protocol: TCP
targetPort: 9000
nodePort: 30000
- name: http
port: 8123
protocol: TCP
targetPort: 8123
- name: interserver
port: 9009
protocol: TCP
targetPort: 9009
EOF
|
这样在 http://node-ip:30000
就可以访问 ClickHouse 了。
进入任意一个 ClickHouse 的 Pod
1
| kubectl exec -it chi-test-cluster-test-cluster-0-0-0 bash
|
下载数据库脚本
1
| wget https://raw.githubusercontent.com/deepseek-ai/3FS/refs/heads/main/deploy/sql/3fs-monitor.sql
|
创建数据库
1
| clickhouse-client -n < 3fs-monitor.sql
|
3.2 FoundationDB
1
| kubectl apply -f https://raw.githubusercontent.com/shaowenchen/hubimage/refs/heads/main/storage/fdb-kubernetes-operator-2.0.0/apps.foundationdb.org_foundationdbbackups.yaml
|
1
| kubectl apply -f https://raw.githubusercontent.com/shaowenchen/hubimage/refs/heads/main/storage/fdb-kubernetes-operator-2.0.0/apps.foundationdb.org_foundationdbclusters.yaml
|
1
| kubectl apply -f https://raw.githubusercontent.com/shaowenchen/hubimage/refs/heads/main/storage/fdb-kubernetes-operator-2.0.0/apps.foundationdb.org_foundationdbrestores.yaml
|
1
| kubectl apply -f https://raw.githubusercontent.com/shaowenchen/hubimage/refs/heads/main/storage/fdb-kubernetes-operator-2.0.0/deployment.yaml
|
1
| kubectl apply -f https://raw.githubusercontent.com/shaowenchen/hubimage/refs/heads/main/storage/fdb-kubernetes-operator-2.0.0/cluster.yaml
|
这里的实例名字已经改为 fdb-a800。
1
2
3
4
5
6
7
8
9
10
11
| kubectl get pod -l foundationdb.org/fdb-cluster-name=fdb-a800
NAME READY STATUS RESTARTS AGE
fdb-a800-cluster-controller-49248 2/2 Running 0 4h21m
fdb-a800-log-19564 2/2 Running 0 4h21m
fdb-a800-log-30929 2/2 Running 0 4h21m
fdb-a800-log-98017 2/2 Running 0 4h21m
fdb-a800-log-9876 2/2 Running 0 4h21m
fdb-a800-storage-16687 2/2 Running 0 4h21m
fdb-a800-storage-31181 2/2 Running 0 4h21m
fdb-a800-storage-90277 2/2 Running 0 4h21m
|
1
2
3
| kubectl exec -it fdb-a800-cluster-controller-49248 cat /var/dynamic-conf/fdb.cluster
fdb_a800:[email protected]:4501,fdb-a800-log-30929.fdb-a800.default.svc.cluster.local:4501,fdb-a800-log-98017.fdb-a800.default.svc.cluster.local:4501
|
但在 Containerd 启动的容器中无法解析上面的域名,需要使用 Service 的 IP。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| kubectl apply -f - <<EOF
apiVersion: v1
kind: Service
metadata:
name: fdb-a800-exposed
spec:
ports:
- port: 4501
protocol: TCP
targetPort: 4501
selector:
foundationdb.org/fdb-cluster-name: fdb-a800
foundationdb.org/fdb-process-class: log
type: ClusterIP
EOF
|
下面才是容器需要的连接信息:
这里有一个细节是,在 K8s 集群的节点上使用 nerdctl 启动的容器可以访问集群的 Service\Pod IP。
没有使用 NodePort 的原因在于,会出现下面的错误,端口不一致断言。
1
| Assertion pkt.canonicalRemotePort == peerAddress.port failed @ /home/foundationdb_ci/src/oOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOoOo/foundationdb/fdbrpc/FlowTransport.actor.cpp 1545:
|
在集群外访问 FoundationDB,建议使用二进制部署 FoundationDB,使用物理机 IP 作为连接地址。
1
2
3
4
| wget https://ghfast.top/https://github.com/apple/foundationdb/releases/download/7.1.26/foundationdb-clients_7.1.26-1_amd64.deb
wget https://ghfast.top/https://github.com/apple/foundationdb/releases/download/7.1.26/foundationdb-server_7.1.26-1_amd64.deb
dpkg -i foundationdb-clients_7.1.26-1_amd64.deb
dpkg -i foundationdb-server_7.1.26-1_amd64.deb
|
将 /etc/foundationdb/fdb.cluster
中的 IP 替换为主机的 IP,重启之后,即可从任意连通的来源访问 FoundationDB 服务。
1
| systemctl restart foundationdb.service
|
4. 容器启动 3FS 服务
4.1 公共环境变量
这里主要设置一些公共的变量,每次启动服务之前都需要设置。
1
2
| export FDB_CLUSTER="xxx:[email protected]:4500"
export IMAGE=shaowenchen/demo-3fs:latest
|
4.2 一个 Monitor
CLUSTER_ID
是 3FS 的集群 ID,需要保持集群组件中一致。
在设置 DEVICE_FILTER
之前可以先运行 ibdev2netdev
查看有哪些可用的设备,这里需要注意不要将 IB 和 RoCE 设备混用。
1
2
3
4
5
6
7
| export CLUSTER_ID=stage
export CLICKHOUSE_DB=3fs
export CLICKHOUSE_HOST=x.x.x.x
export CLICKHOUSE_PASSWD=xxxx
export CLICKHOUSE_PORT=30000
export CLICKHOUSE_USER=app
export DEVICE_FILTER="mlx5_0,mlx5_1,mlx5_4,mlx5_5"
|
Monitor 会占用端口 10000
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| nerdctl run --name 3fs_monitor \
--privileged \
--network host \
-d --restart always \
--env CLUSTER_ID=${CLUSTER_ID} \
--env CLICKHOUSE_DB=${CLICKHOUSE_DB} \
--env CLICKHOUSE_HOST=${CLICKHOUSE_HOST} \
--env CLICKHOUSE_PASSWD=${CLICKHOUSE_PASSWD} \
--env CLICKHOUSE_PORT=${CLICKHOUSE_PORT} \
--env CLICKHOUSE_USER=${CLICKHOUSE_USER} \
--env FDB_CLUSTER=${FDB_CLUSTER} \
--env DEVICE_FILTER=${DEVICE_FILTER} \
${IMAGE} \
./3fs-entrypoint.sh monitor
|
4.3 一个 Admin CLI
Admin CLI 是一个管理终端,不占用端口,可以和其他服务公用一个节点部署。
这里的 MGMTD_SERVER_ADDRESSES
需要提前规划出来,不用先启动服务,可以直接设置;REMOTE_IP
是 Monitor 服务暴露的地址。
1
2
| export MGMTD_SERVER_ADDRESSES="RDMA://x.x.x.x:8000,RDMA://x.x.x.x:8000,RDMA://x.x.x.x:8000"
export REMOTE_IP=x.x.x.x:10000
|
1
2
3
4
5
6
7
8
9
10
11
| nerdctl run --name 3fs_admin_cli \
--privileged \
--network host \
-d --restart always \
--env FDB_CLUSTER=${FDB_CLUSTER} \
--env MGMTD_SERVER_ADDRESSES=${MGMTD_SERVER_ADDRESSES} \
--env DEVICE_FILTER=${DEVICE_FILTER} \
--env CLUSTER_ID=${CLUSTER_ID} \
--env REMOTE_IP=${REMOTE_IP} \
${IMAGE} \
./3fs-entrypoint.sh admin_cli
|
1
| nerdctl exec -it 3fs_admin_cli bash
|
1
| /opt/3fs/bin/admin_cli -cfg /opt/3fs/etc/admin_cli.toml "init-cluster --mgmtd /opt/3fs/etc/mgmtd_main.toml 1 1048576 6"
|
1 表示链表 ID;1048576 表示块大小(以字节为单位),也就是 1M;6 表示文件条带化大小。
4.4 多个 MgmtD
每个 Mgmtd 设置的 MGMTD_NODE_ID
应该不一样。
1
2
3
| export MGMTD_NODE_ID="1"
export DEVICE_FILTER="mlx5_0,mlx5_1,mlx5_4,mlx5_5"
export REMOTE_IP=x.x.x.x:10000
|
Mgmtd 服务监听端口 8000、9000
1
2
3
4
5
6
7
8
9
10
11
| nerdctl run --name 3fs_mgmtd \
--privileged \
--network host \
-d --restart always \
--env CLUSTER_ID=${CLUSTER_ID} \
--env FDB_CLUSTER=${FDB_CLUSTER} \
--env MGMTD_NODE_ID=${MGMTD_NODE_ID} \
--env DEVICE_FILTER=${DEVICE_FILTER} \
--env REMOTE_IP=${REMOTE_IP} \
${IMAGE} \
./3fs-entrypoint.sh mgmtd
|
Meta 和 Mgmtd 监听的端口不一样,可以部署在同一台机器上。
每个 Meta 设置的 META_NODE_ID
应该不一样。
1
2
3
4
| export MGMTD_SERVER_ADDRESSES="RDMA://x.x.x.x:8000,RDMA://x.x.x.x:8000,RDMA://x.x.x.x:8000"
export META_NODE_ID="101"
export DEVICE_FILTER="mlx5_0,mlx5_1,mlx5_4,mlx5_5"
export REMOTE_IP=x.x.x.x:10000
|
Meta 服务监听端口 8001、9001
1
2
3
4
5
6
7
8
9
10
11
12
| nerdctl run --name 3fs_meta \
--privileged \
-d --restart always \
--network host \
--env CLUSTER_ID=${CLUSTER_ID} \
--env FDB_CLUSTER=${FDB_CLUSTER} \
--env MGMTD_SERVER_ADDRESSES=${MGMTD_SERVER_ADDRESSES} \
--env META_NODE_ID=${META_NODE_ID} \
--env DEVICE_FILTER=${DEVICE_FILTER} \
--env REMOTE_IP=${REMOTE_IP} \
${IMAGE} \
./3fs-entrypoint.sh meta
|
4.6 多个 Storage
Storage 服务需要与 Mgmtd 服务分开,它们使用了相同的端口。
每个 Storage 设置的 STORAGE_NODE_ID
应该不一样;TARGET_PATHS
是存储的目录,由于这里是容器化部署可以保持固定值,通过修改挂载参数设置存储目录。
1
2
3
4
5
| export MGMTD_SERVER_ADDRESSES="RDMA://x.x.x.x:8000,RDMA://x.x.x.x:8000,RDMA://x.x.x.x:8000"
export STORAGE_NODE_ID="1001"
export TARGET_PATHS="/3fs/data"
export DEVICE_FILTER="mlx5_0,mlx5_1,mlx5_4,mlx5_5"
export REMOTE_IP=x.x.x.x:10000
|
1
| sysctl -w fs.aio-max-nr=67108864
|
Storage 服务监听端口 8000、9000
mkdir -p /data/3fs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| nerdctl run --name 3fs_storage \
--privileged \
-d --restart always \
--network host \
-v /data/3fs:/3fs/data \
--env CLUSTER_ID=${CLUSTER_ID} \
--env FDB_CLUSTER=${FDB_CLUSTER} \
--env MGMTD_SERVER_ADDRESSES=${MGMTD_SERVER_ADDRESSES} \
--env STORAGE_NODE_ID=${STORAGE_NODE_ID} \
--env TARGET_PATHS=${TARGET_PATHS} \
--env DEVICE_FILTER=${DEVICE_FILTER} \
--env REMOTE_IP=${REMOTE_IP} \
${IMAGE} \
./3fs-entrypoint.sh storage
|
4.7 Admin Cli 查看节点
1
| nerdctl exec -it 3fs_admin_cli bash
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| /opt/3fs/bin/admin_cli -cfg /opt/3fs/etc/admin_cli.toml list-nodes
Id Type Status Hostname Pid Tags LastHeartbeatTime ConfigVersion ReleaseVersion
1 MGMTD PRIMARY_MGMTD 58ca52320c3b 16 [] N/A 1(UPTODATE) 250228-dev-1-999999-8c9883c2
2 MGMTD HEARTBEAT_CONNECTED 391173a5a978 16 [] 2025-03-15 13:45:48 1(UPTODATE) 250228-dev-1-999999-8c9883c2
3 MGMTD HEARTBEAT_CONNECTED 8c05a1fbdf97 16 [] 2025-03-15 13:45:50 1(UPTODATE) 250228-dev-1-999999-8c9883c2
101 META HEARTBEAT_CONNECTED b3fea43900e6 202 [] 2025-03-15 13:45:48 4(UPTODATE) 250228-dev-1-999999-8c9883c2
102 META HEARTBEAT_CONNECTED fcebcb6ca5c3 192 [] 2025-03-15 13:45:52 4(UPTODATE) 250228-dev-1-999999-8c9883c2
103 META HEARTBEAT_CONNECTED fea159ba0bd6 194 [] 2025-03-15 13:45:49 4(UPTODATE) 250228-dev-1-999999-8c9883c2
1001 STORAGE HEARTBEAT_CONNECTED 919404e2891f 188 [] 2025-03-15 13:45:51 7(UPTODATE) 250228-dev-1-999999-8c9883c2
1002 STORAGE HEARTBEAT_CONNECTED e19b012d073c 180 [] 2025-03-15 13:45:51 7(UPTODATE) 250228-dev-1-999999-8c9883c2
1003 STORAGE HEARTBEAT_CONNECTED fd2423d5e695 173 [] 2025-03-15 13:45:52 7(UPTODATE) 250228-dev-1-999999-8c9883c2
1004 STORAGE HEARTBEAT_CONNECTED e8b6fbb9a774 184 [] 2025-03-15 13:45:52 7(UPTODATE) 250228-dev-1-999999-8c9883c2
1005 STORAGE HEARTBEAT_CONNECTED 283ae64fb9c4 168 [] 2025-03-15 13:45:53 7(UPTODATE) 250228-dev-1-999999-8c9883c2
|
5. 创建 3FS 存储实例
1
| nerdctl exec -it 3fs_admin_cli bash
|
1
| /opt/3fs/bin/admin_cli -cfg /opt/3fs/etc/admin_cli.toml "user-add --root --admin 0 root"
|
1
2
3
4
5
6
7
| Uid 0
Name root
Token AAA1+B5D8QCAeUKZ2wCBx/b5(Expired at N/A)
IsRootUser true
IsAdmin true
Gid 0
SupplementaryGids
|
这里的 AAA1+B5D8QCAeUKZ2wCBx/b5
就是 root 用户的 token。
1
2
3
| apt update
apt install -y python3-pip
pip install -r /opt/3fs/deploy/data_placement/requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
|
1
2
| python3 /opt/3fs/deploy/data_placement/src/model/data_placement.py \
-ql -relax -type CR --num_nodes 5 --replication_factor 3 --min_targets_per_disk 6
|
这里的 replication_factor
不能大于 num_nodes
,需要记录一下输出的结果,下一步会用到。
1
| 2025-03-15 16:21:45.429 | SUCCESS | __main__:run:148 - saved solution to: output/DataPlacementModel-v_5-b_10-r_6-k_3-λ_2-lb_1-ub_1
|
这里的 node_id_begin
和 node_id_end
需要和上面的 storage 节点的 STORAGE_NODE_ID
一致。
1
2
3
4
5
| python3 /opt/3fs/deploy/data_placement/src/setup/gen_chain_table.py \
--chain_table_type CR --node_id_begin 1001 --node_id_end 1005 \
--num_disks_per_node 1 --num_targets_per_disk 6 \
--target_id_prefix 1 --chain_id_prefix 9 \
--incidence_matrix_path output/DataPlacementModel-v_5-b_10-r_6-k_3-λ_2-lb_1-ub_1/incidence_matrix.pickle
|
1
| /opt/3fs/bin/admin_cli --cfg /opt/3fs/etc/admin_cli.toml --config.user_info.token $(<"/opt/3fs/etc/token.txt") < output/create_target_cmd.txt
|
这里会输出一个 target 在每个节点上的分布情况。
1
| /opt/3fs/bin/admin_cli --cfg /opt/3fs/etc/admin_cli.toml --config.user_info.token $(<"/opt/3fs/etc/token.txt") "upload-chains output/generated_chains.csv"
|
1
| /opt/3fs/bin/admin_cli --cfg /opt/3fs/etc/admin_cli.toml --config.user_info.token $(<"/opt/3fs/etc/token.txt") "upload-chain-table --desc stage 1 output/generated_chain_table.csv"
|
6. Fuse 挂载
这里的 TOKEN
就是上面创建的 root 用户的 token。
1
2
3
4
5
6
7
| export CLUSTER_ID=stage
export FDB_CLUSTER="x:[email protected]:4500"
export MGMTD_SERVER_ADDRESSES="RDMA://x.x.x.x:8000,RDMA://x.x.x.x:8000,RDMA://x.x.x.x:8000"
export REMOTE_IP=x.x.x.x:x
export DEVICE_FILTER="mlx5_0,mlx5_1,mlx5_4,mlx5_5"
export TOKEN=xxx
export IMAGE=shaowenchen/demo-3fs:latest
|
1
2
3
4
5
6
7
8
9
10
11
12
13
| nerdctl run --name 3fs_fuse_container \
--privileged \
-d --restart always \
--network host \
--mount type=bind,source=/mnt/3fs,target=/mnt/3fs,bind-propagation=shared \
--env CLUSTER_ID=${CLUSTER_ID} \
--env FDB_CLUSTER=${FDB_CLUSTER} \
--env MGMTD_SERVER_ADDRESSES=${MGMTD_SERVER_ADDRESSES} \
--env REMOTE_IP=${REMOTE_IP} \
--env DEVICE_FILTER=${DEVICE_FILTER} \
--env TOKEN=${TOKEN} \
${IMAGE} \
./3fs-entrypoint.sh fuse
|
-v
只能将主机的目录挂载到容器中,而这里需要的是将容器中的目录挂载到主机上,所以使用 --mount
参数配合 bind-propagation=shared
进行挂载。
1
2
3
4
| df -h /mnt/3fs/
Filesystem Size Used Avail Use% Mounted on
hf3fs.stage 57T 2.5T 55T 5% /mnt/3fs
|
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
| tree /mnt/3fs
/mnt/3fs
└── 3fs-virt
├── get-conf
│ ├── sys.io_job_deq_timeout -> '1ms'
│ ├── sys.io_worker_coros.hi -> 8
│ ├── sys.io_worker_coros.lo -> 8
│ ├── sys.max_jobs_per_ioring -> 32
│ ├── sys.periodic_sync.enable -> true
│ ├── sys.periodic_sync.flush_write_buf -> true
│ ├── sys.periodic_sync.interval -> '30s'
│ ├── sys.storage.net_client.rdma_control.max_concurrent_transmission -> 64
│ ├── usr.attr_timeout -> 30.0
│ ├── usr.dryrun_bench_mode -> false
│ ├── usr.enable_read_cache -> true
│ ├── usr.entry_timeout -> 30.0
│ ├── usr.flush_on_stat -> true
│ ├── usr.negative_timeout -> 5.0
│ ├── usr.readonly -> false
│ ├── usr.symlink_timeout -> 5.0
│ └── usr.sync_on_stat -> true
├── iovs
│ ├── submit-ios -> /dev/shm/sem.hf3fs-submit-ios.c52d4079-b1c0-4684-9d08-6f2ee18d8a6e
│ ├── submit-ios.ph -> /dev/shm/sem.hf3fs-submit-ios.dd3eac7c-3802-422d-93a7-efaf56c6e2af
│ └── submit-ios.pl -> /dev/shm/sem.hf3fs-submit-ios.e8cf7b88-e65a-4cb5-a3ba-de71351bccee
├── rm-rf
└── set-conf
5 directories, 20 files
|
7. 总结
本篇主要介绍了如何使用容器化部署 DeepSeek 3FS 存储系统,主要包括以下几个步骤:
- 编译 3FS 镜像
- 部署 ClickHouse 和 FoundationDB 中间件
- 启动 Monitor、Admin CLI、MgmtD、Meta、Storage 服务
根据启动参数的不同,可以启动不同的服务,3fs-entrypoint.sh 脚本内容已经提交到 https://github.com/shaowenchen/demo/blob/master/3fs-deploy/3fs-entrypoint.sh 以供参考。