跳转至

MinIO: 自托管 S3 兼容对象存储

为什么要学 MinIO

对象存储是现代应用的基础设施——文件上传、数据湖、备份、日志归档、生信大文件存储都离不开它。AWS S3 是行业标准,但在以下场景中你可能需要自托管方案:

场景为什么需要自托管
数据合规数据不能出境或必须存在特定位置
成本控制大量数据的 S3 费用可观(特别是出口流量)
开发测试本地开发需要 S3 兼容接口
生信数据测序数据动辄 TB 级,云存储成本高
内网环境无法访问公有云
低延迟数据离计算节点更近

MinIO 是高性能的 S3 兼容对象存储,用 Go 编写。关键特点:

特性说明
S3 兼容几乎 100% 兼容 S3 API
性能单节点可达数 GB/s 吞吐
轻量单二进制文件,50MB
分布式支持纠删码和多节点部署
加密服务端和客户端加密
版本控制对象版本管理

核心概念

白话解释

对象存储和文件系统不同。文件系统是树状目录结构,对象存储是扁平的"桶(Bucket)+ 对象(Object)"结构。

文件系统:              对象存储:
/data/                 Bucket: sequencing-data
├── sample1/             ├── sample1/reads_R1.fastq.gz  (对象)
│   ├── reads_R1.fq      ├── sample1/reads_R2.fastq.gz  (对象)
│   └── reads_R2.fq      ├── sample2/reads_R1.fastq.gz  (对象)
└── sample2/             └── results/report.html        (对象)
    └── reads_R1.fq

虽然看起来有"路径",但对象存储中的 / 只是命名约定,不是真正的目录。

核心概念表

概念说明S3 等价物
Bucket对象的容器S3 Bucket
Object存储的数据单元S3 Object
Key对象的唯一标识(路径)S3 Key
Policy访问控制策略S3 Bucket Policy
Presigned URL临时授权的下载/上传链接S3 Presigned URL
Multipart Upload大文件分片上传S3 Multipart
Versioning对象版本管理S3 Versioning
Lifecycle自动过期/转储规则S3 Lifecycle
Erasure Coding纠删码(数据冗余)S3 跨区复制
mcMinIO 命令行客户端aws s3 CLI

安装配置

方式一:Docker(推荐快速开始)

# 单节点快速启动
docker run -d \
  --name minio \
  -p 9000:9000 \
  -p 9001:9001 \
  -v minio-data:/data \
  -e MINIO_ROOT_USER=minioadmin \
  -e MINIO_ROOT_PASSWORD=minioadmin123 \
  quay.io/minio/minio server /data --console-address ":9001"

# 访问 Web 控制台: http://localhost:9001
# 用户名: minioadmin
# 密码: minioadmin123

方式二:Docker Compose(生产推荐)

# docker-compose.yml
version: '3'

services:
  minio:
    image: quay.io/minio/minio:latest
    container_name: minio
    command: server /data --console-address ":9001"
    ports:
      - '9000:9000'   # API
      - '9001:9001'   # Console
    environment:
      MINIO_ROOT_USER: minioadmin
      MINIO_ROOT_PASSWORD: ${MINIO_ROOT_PASSWORD:-changeme}
    volumes:
      - minio-data:/data
    healthcheck:
      test: ["CMD", "mc", "ready", "local"]
      interval: 30s
      timeout: 20s
      retries: 3
    restart: unless-stopped

volumes:
  minio-data:

方式三:直接安装

# Linux
wget https://dl.min.io/server/minio/release/linux-amd64/minio
chmod +x minio
sudo mv minio /usr/local/bin/

# 启动
MINIO_ROOT_USER=minioadmin MINIO_ROOT_PASSWORD=minioadmin123 \
  minio server /data --console-address ":9001"

安装 mc 客户端

# macOS
brew install minio/stable/mc

# Linux
wget https://dl.min.io/client/mc/release/linux-amd64/mc
chmod +x mc
sudo mv mc /usr/local/bin/

# 配置别名
mc alias set local http://localhost:9000 minioadmin minioadmin123

# 验证连接
mc admin info local

快速上手

mc 命令行操作

# 创建 Bucket
mc mb local/my-bucket

# 上传文件
mc cp myfile.txt local/my-bucket/
mc cp -r ./data/ local/my-bucket/data/

# 列出文件
mc ls local/my-bucket/
mc ls -r local/my-bucket/  # 递归列出

# 下载文件
mc cp local/my-bucket/myfile.txt ./downloaded.txt
mc cp -r local/my-bucket/data/ ./local-data/

# 删除
mc rm local/my-bucket/myfile.txt
mc rm -r --force local/my-bucket/old-data/

# 查看文件信息
mc stat local/my-bucket/myfile.txt

# 查看 Bucket 磁盘使用
mc du local/my-bucket

Python SDK (boto3)

由于 MinIO 完全兼容 S3 API,可以直接使用 AWS 的 boto3:

pip install boto3
import boto3
from botocore.client import Config

# 创建 S3 客户端(连接 MinIO)
s3 = boto3.client(
    's3',
    endpoint_url='http://localhost:9000',
    aws_access_key_id='minioadmin',
    aws_secret_access_key='minioadmin123',
    config=Config(signature_version='s3v4'),
    region_name='us-east-1'
)

# 创建 Bucket
s3.create_bucket(Bucket='sequencing-data')

# 上传文件
s3.upload_file('sample.fastq.gz', 'sequencing-data', 'sample1/reads.fastq.gz')

# 上传大文件(自动分片)
from boto3.s3.transfer import TransferConfig
config = TransferConfig(multipart_threshold=100 * 1024 * 1024)  # 100MB
s3.upload_file('large_file.bam', 'sequencing-data', 'sample1/aligned.bam',
               Config=config)

# 下载文件
s3.download_file('sequencing-data', 'sample1/reads.fastq.gz', 'local_copy.fastq.gz')

# 列出文件
response = s3.list_objects_v2(Bucket='sequencing-data', Prefix='sample1/')
for obj in response.get('Contents', []):
    print(f"{obj['Key']}  {obj['Size']} bytes")

# 生成预签名下载链接(有效期 1 小时)
url = s3.generate_presigned_url(
    'get_object',
    Params={'Bucket': 'sequencing-data', 'Key': 'sample1/reads.fastq.gz'},
    ExpiresIn=3600
)
print(f"Download URL: {url}")

MinIO 原生 Python SDK

pip install minio
from minio import Minio

client = Minio(
    "localhost:9000",
    access_key="minioadmin",
    secret_key="minioadmin123",
    secure=False  # 本地开发用 HTTP
)

# 创建 Bucket
if not client.bucket_exists("my-data"):
    client.make_bucket("my-data")

# 上传
client.fput_object("my-data", "report.pdf", "/path/to/report.pdf")

# 下载
client.fget_object("my-data", "report.pdf", "/tmp/report.pdf")

# 列出对象
for obj in client.list_objects("my-data", recursive=True):
    print(f"{obj.object_name}: {obj.size} bytes")

# 预签名 URL
from datetime import timedelta
url = client.presigned_get_object("my-data", "report.pdf", expires=timedelta(hours=1))

进阶用法

生信大文件存储方案

# 批量上传测序数据
import os
from minio import Minio
from concurrent.futures import ThreadPoolExecutor

client = Minio("minio.lab.internal:9000",
               access_key="bioinfo", secret_key="bioinfo123",
               secure=True)

def upload_file(filepath, bucket, prefix):
    object_name = f"{prefix}/{os.path.basename(filepath)}"
    client.fput_object(bucket, object_name, filepath)
    print(f"Uploaded: {object_name}")

# 并行上传
fastq_files = [f for f in os.listdir("./raw_data") if f.endswith('.fastq.gz')]
with ThreadPoolExecutor(max_workers=4) as executor:
    for f in fastq_files:
        executor.submit(upload_file, f"./raw_data/{f}", "sequencing", "run001")

Bucket 策略

# 设置 Bucket 为公开只读
mc anonymous set download local/public-data

# 设置自定义策略
cat > policy.json << 'EOF'
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {"AWS": ["*"]},
      "Action": ["s3:GetObject"],
      "Resource": ["arn:aws:s3:::public-data/*"]
    }
  ]
}
EOF
mc anonymous set-json policy.json local/public-data

事件通知

# 配置 Webhook 通知
mc event add local/my-bucket arn:minio:sqs::_:webhook \
  --event put --prefix uploads/ --suffix .fastq.gz

对象生命周期

# 设置生命周期规则:30 天后自动删除 tmp/ 前缀的对象
mc ilm rule add --prefix "tmp/" --expire-days 30 local/my-bucket

# 查看规则
mc ilm rule ls local/my-bucket

版本控制

# 启用版本控制
mc version enable local/my-bucket

# 列出对象的所有版本
mc ls --versions local/my-bucket/config.json

# 恢复特定版本
mc cp --version-id xxx local/my-bucket/config.json ./restored.json

分布式部署

# 4 节点纠删码部署
# 至少需要 4 个节点,每个节点一个磁盘
minio server http://node{1...4}:9000/data

# 每个节点多盘
minio server http://node{1...4}:9000/data{1...4}
# docker-compose.yml - 4 节点分布式
version: '3'

services:
  minio1:
    image: quay.io/minio/minio
    command: server http://minio{1...4}:9000/data --console-address ":9001"
    volumes:
      - minio1-data:/data

  minio2:
    image: quay.io/minio/minio
    command: server http://minio{1...4}:9000/data --console-address ":9001"
    volumes:
      - minio2-data:/data

  minio3:
    image: quay.io/minio/minio
    command: server http://minio{1...4}:9000/data --console-address ":9001"
    volumes:
      - minio3-data:/data

  minio4:
    image: quay.io/minio/minio
    command: server http://minio{1...4}:9000/data --console-address ":9001"
    volumes:
      - minio4-data:/data

常见问题

Q1: MinIO 和 AWS S3 的兼容性如何?

几乎 100% 兼容 S3 API。已验证兼容的工具包括: - boto3 (Python)、aws-sdk (JS/Go/Java) 等官方 SDK - rclone、s3cmd、cyberduck 等第三方工具 - 大多数声称支持 S3 的应用可以无缝切换到 MinIO

Q2: 数据安全性如何保证?

  • 纠删码:分布式模式下,可以容忍 N/2 个磁盘故障
  • 加密:支持 SSE-S3、SSE-C、SSE-KMS 服务端加密
  • TLS:配置 HTTPS 传输加密
  • IAM:完整的用户和策略管理

Q3: 性能如何?

单节点 MinIO 在 NVMe SSD 上可以达到: - 读取:数 GB/s - 写入:数 GB/s - 适合生信数据这类大文件场景

Q4: 存储空间不够了怎么办?

  • 单节点:增加磁盘或扩容现有磁盘
  • 分布式:添加新的 Server Pool
  • 使用 Lifecycle 规则自动清理过期数据

Q5: 如何与 Nextflow/Snakemake 集成?

// Nextflow - nextflow.config
aws {
    accessKey = 'minioadmin'
    secretKey = 'minioadmin123'
    client {
        endpoint = 'http://minio:9000'
        s3PathStyleAccess = true
    }
}
# Snakemake 通过 S3 远程存储
from snakemake.remote.S3 import RemoteProvider as S3RemoteProvider
S3 = S3RemoteProvider(
    endpoint_url="http://minio:9000",
    access_key_id="minioadmin",
    secret_access_key="minioadmin123"
)

参考资源

资源链接
官方网站https://min.io
GitHub 仓库https://github.com/minio/minio
官方文档https://min.io/docs/minio/linux
Python SDKhttps://min.io/docs/minio/linux/developers/python/API.html
mc 命令参考https://min.io/docs/minio/linux/reference/minio-mc.html
部署指南https://min.io/docs/minio/linux/operations/installation.html

总结:MinIO 是自托管对象存储的标准选择。完全的 S3 API 兼容意味着你可以使用整个 S3 生态工具链,同时数据完全由你控制。对于生信研究者来说,用 MinIO 管理 TB 级的测序数据比 NFS/NAS 更灵活,比云端 S3 更经济。单二进制文件的部署方式也让运维负担降到最低。