在寻找 MinIO 的轻量化替代方案时,SeaweedFS 绝对是一个无法忽视的性能怪兽。与 MinIO 这种对小文件存储会带来巨大元数据开销的传统对象存储不同,SeaweedFS 专门对十亿级、甚至百亿级的小文件并发吞吐进行了极致的优化。
本文将介绍如何使用 Docker-compose 单容器(Server 模式) 快速在你的 Linux 服务器上拉起一个完整的 SeaweedFS 实例,同步开启 S3 兼容 API 网关,并搭配 PostgreSQL 作为 Filer 的外部元数据存储引擎,实现元数据与底层物理文件的解耦分离。
一、 为什么引入 PostgreSQL 作为元数据存储?
标准的 SeaweedFS 在单容器模式下,默认使用内嵌的 LevelDB 来存放目录结构和文件元信息。但这种方式存在两个隐患:
- 如果容器或宿主机意外断电,内嵌数据库文件存在损坏甚至丢失目录树的风险。
- 无法进行高可用扩展或跨节点同步。
通过将元数据接管给独立的 PostgreSQL,SeaweedFS 容器本身将变成“无状态”的。即使容器被彻底销毁重建,只要 PostgreSQL 数据库和物理硬盘里的数据块(Volume)还在,整个分布式文件系统的目录树就能秒级完美恢复。
二、 准备工作与目录结构
在开始部署前,建议为 SeaweedFS 创建一个独立的持久化管理目录,并创建好必要的配置文件。
我们约定项目目录结构如下:
./docker/seaweedfs/
├── docker-compose.yml
├── filer.toml # Filer 对接 PostgreSQL 的核心配置文件
├── s3.json # S3 网关的 AccessKey 权限配置
└── seaweedfs_data/ # 数据存放的物理持久化目录(自动生成)
三、 核心配置与元数据层初始化
在部署 SeaweedFS 之前,我们需要先在现有的 PostgreSQL 实例中初始化数据库、配置元数据存储接管,最后生成 S3 的密钥文件。
- 基础设施:PostgreSQL 数据库准备
登录你的 PG 实例,并创建一个全新的空数据库(名称根据业务习惯,这里推荐叫 seaweedfs 或者是 s3):
docker exec -it postgresql psql -U root -d postgres
CREATE DATABASE seaweedfs;
- 数据库建表与索引初始化
假设你的 PostgreSQL 容器名称为 postgresql,你可以直接在宿主机执行以下命令,进入容器为刚才建好的数据库自动初始化 SeaweedFS 专属的元数据结构表与查询优化索引:
docker exec -it postgresql psql -U root -d seaweedfs -c "
CREATE TABLE IF NOT EXISTS filemeta (
dirhash BIGINT,
name VARCHAR(1000),
directory VARCHAR(4096),
meta BYTEA,
PRIMARY KEY (dirhash, name)
);
CREATE INDEX IF NOT EXISTS filemeta_dir_idx
ON filemeta (directory);
"
- 配置 Filer 元数据接管:filer.toml
现在我们需要告诉 SeaweedFS,不要再往本地 LevelDB 里面写元数据了,而是统统改写刚才建好的 PostgreSQL 表。创建(或修改)filer.toml,在 [postgres] 模块下配置你的连接信息,并禁用掉默认的本地内嵌存储:
vim filer.toml
[leveldb2]
enabled = false # 关闭默认的本地内嵌数据库
[postgres]
enabled = true
hostname = "127.0.0.1" # 或者是你 PG 容器的外部公共/内部网段 IP
port = 5432
username = "root"
password = "YOUR_POSTGRES_PASSWORD"
database = "seaweedfs" # 对应刚才建表的数据库名
sslmode = "disable"
connection_max_idle = 100
connection_max_open = 100
- 编写 S3 访问控制配置文件:s3.json
SeaweedFS 使用独立的 JSON 文件来管理 S3 的 IAM 密钥鉴权。创建一个名为 s3.json 的文件,填入你的自定义 AccessKey 和 SecretKey:
vim s3.json
{
"identities": [
{
"name": "admin",
"credentials": [
{
"accessKey": "YOUR_S3_ACCESS_KEY",
"secretKey": "YOUR_S3_SECRET_KEY"
}
],
"actions": [
"Read",
"Write",
"List",
"Tagging",
"Admin"
]
}
]
}
💡 请务必将 YOUR_S3_ACCESS_KEY 和 YOUR_S3_SECRET_KEY 替换为你自己的强随机密钥串。
四、 编写 Docker-compose 配置文件
接下来,创建你的 docker-compose.yml 文件。
此处我们使用的是规范的 version: "3.9" 语法,并加入了一系列针对小独立单实例运行的存储优化与内存边界限制策略:
vim docker-compose.yml
version: "3.9"
services:
seaweedfs:
image: chrislusf/seaweedfs:4.04
container_name: seaweedfs
restart: unless-stopped
command:
- "server"
- "-dir=/data" # 物理 Volume 数据块存储目录
- "-s3" # 启用 S3 模块
- "-s3.config=/etc/seaweedfs/s3.json" # 指定 S3 配置文件路径
# --- 存储策略 ---
- "-master.volumePreallocate=true" # 开启空间预分配
- "-master.garbageThreshold=0.1" # 碎片超过 10% 触发自动清理
# --- Volume 限制 ---
- "-volume.max=10" # 限制卷最大数量
- "-volume.minFreeSpace=4096m" # 最小剩余空间限制
volumes:
- ./seaweedfs_data:/data # 数据持久化
- ./filer.toml:/etc/seaweedfs/filer.toml:ro # 映射 filer 配置文件
- ./s3.json:/etc/seaweedfs/s3.json:ro # 映射 S3 权限配置
ports:
- "9333:9333" # Master 端口(Web 控制台)
- "19333:19333" # Master gRPC 通信端口
- "8888:8888" # Filer 端口(浏览文件系统)
- "8333:8333" # S3 API 端口(应用连接此端口)
- "8080:8080" # Volume 端口
mem_limit: 512m # 限制单容器最大内存占用
五、 启动与验证
在项目目录下,直接一键拉起 SeaweedFS 容器:
docker compose up -d
验证元数据是否写入 PostgreSQL
当服务运行成功后,尝试通过浏览器或客户端上传一个小文件。然后登录到你的 PostgreSQL 中查看 filemeta 表:
SELECT * FROM filemeta LIMIT 5;
如果能看到表中出现了二进制(BYTEA 类型的 meta 字段)的数据记录,说明元数据已经完美剥离并成功持久化进入了你的外部数据库。
六、 应用如何接入配置?
当你需要将 WordPress 的备份插件(如 UpdraftPlus)、或者其他自建程序(如图床、Nextcloud)对接到这个 SeaweedFS S3 时,对应的填写参数规范如下:
参数项 填写内容
Endpoint(服务节点) http://你的服务器IP:8333
Region(地区) us-east-1 (或者留空/随便填,SeaweedFS 内部不验证物理地区)
Access Key 填写你在 s3.json 中定义的 key
Secret Key 填写你在 s3.json 中定义的 secret
S3 签名版本 推荐选择 V4
Path Style(路径模式) 必须开启 (使用 http://ip:8333/bucket-name 形式访问)
文章评论