引言:自托管时代的对象存储

自Amazon S3(Simple Storage Service)于2006年问世以来,对象存储已成为现代基础设施的核心组件。在存储和管理图像、视频、备份数据、日志文件等非结构化数据方面,S3 API已成为事实上的标准(de facto standard),众多应用程序和工具都默认支持S3兼容接口。

然而,对公有云的依赖带来了成本暴涨数据主权问题厂商锁定(Vendor Lock-in)等根本性挑战。因此,在本地服务器或个人服务器上自行运营S3兼容存储的自托管需求持续增长。曾经的代表性方案MinIO凭借其高性能和简便部署赢得了大量用户,但转向AGPLv3+商用双重许可模式后,开源阵营出现了转移趋势,最近其GitHub仓库也转入维护模式,替代方案的关注度急剧上升。

在此背景下备受瞩目的项目正是Garage。由法国非营利组织Deuxfleurs开发的Garage,以"在数据中心之外也能稳定运行的S3对象存储"为目标,提出了专为小规模自托管环境优化的独特方案。本文将全面解析Garage的核心理念、内部架构、安装运维指南、性能调优,以及与竞品方案的对比。

1. 什么是Garage?

1.1 Garage的设计哲学与目标

Garage是自2020年首次发布以来,由法国小型非营利托管服务商Deuxfleurs持续开发的S3兼容分布式对象存储。Deuxfleurs实际在其生产环境中使用Garage,运营着分布在3个物理位置、由9个节点组成的多站点集群。

Garage的设计基于四大核心原则:

  • 互联网友好(Internet-enabled):为通过普通互联网连接(如FTTH)互联的数据中心、办公室、家庭等多站点环境设计。无需高速专线,普通家用宽带即可满足需求。
  • 自包含且轻量(Self-contained & Lightweight):不依赖任何外部服务(etcd、ZooKeeper、PostgreSQL等),以单一二进制文件即可在任何环境运行。
  • 高弹性(Highly Resilient):对网络故障、网络延迟、磁盘故障,甚至管理员误操作都具有高度的恢复能力。
  • 简单性(Simple):追求易于理解、易于运维、易于调试的系统。

尤其值得关注的是,Garage通过欧盟(EU)资助确保了至2025年的稳定开发资金,这在开源项目可持续性经常成为问题的背景下,提升了对Garage长期愿景的信心。

1.2 核心功能概览

  • S3兼容API:支持GetObject、PutObject、DeleteObject、ListObjects、Multipart Upload等核心S3操作。但对象版本控制(Versioning)和对象锁定(Object Lock)等高级功能尚未支持。
  • 地理分布式复制:识别各节点的物理位置,将数据副本进行地理分散部署。在灾难恢复(DR)场景中具有显著优势。
  • 静态网站托管:无需额外Web服务器,Garage本身即可将存储桶内容作为静态网站提供服务。域名直接映射到存储桶名称。此功能是MinIO和Ceph均不支持的Garage独有特性。
  • Admin REST API:提供完整的REST API用于编程化集群管理。
  • 监控支持:支持Prometheus格式的内部指标和OpenTelemetry格式的追踪导出。
  • K2V(实验性):用于存储和检索大量小型Key-Value对的实验性API,作为S3 API的补充。
  • Zstd压缩和数据去重:可对所有存储数据选择性应用Zstd压缩,相同数据块自动去重。

同时,Garage明确声明了若干非目标(Non-goals):不追求超越S3 API的功能扩展;不实现纠删码(Erasure Coding)等存储优化(仅使用副本复制);不提供POSIX文件系统兼容性。

2. Garage架构深度分析

2.1 分布式系统理论基础

  • Amazon Dynamo模式:借鉴高可用Key-Value存储的设计原则。即使部分节点发生故障,数据的读写仍可继续进行。
  • CRDT(无冲突复制数据类型):即使多个节点同时修改数据,也能在无需额外协调的情况下收敛到一致的最终状态。
  • Maglev负载均衡:利用Google开发的Maglev哈希算法高效分配请求。通过一致性哈希确保节点增减时仅需最少的数据重新分配。

2.2 数据复制与一致性模型

Garage采用最终一致性(Eventual Consistency)模型,同时提供实用性强的保障:

  • 基于仲裁的读写:当replication_factor = 3时,写入操作发送至3个节点,2个节点确认即返回成功,第三个节点异步完成。
  • 自动修复机制:发生不一致时,自动修复(repair)机制恢复一致性。
  • Tombstone标记:分布式环境中的删除操作使用Tombstone(逻辑删除标记)处理,防止"已删除的数据在其他节点复活"的问题。

2.3 节点通信与集群管理

  • Gossip协议:无需中央协调器(etcd、ZooKeeper等),通过节点间的P2P通信共享集群状态。消除单点故障(SPOF)。
  • Rust单一二进制:整个系统用Rust编写,编译为单一二进制文件。在Raspberry Pi级别的低配置硬件上也能运行。
  • 异构硬件支持:可以混合使用不同规格的机器组建集群。根据各节点的存储容量和物理位置自动制定最优的数据分布计划。

3. Garage安装与集群部署指南

3.1 前置要求

  • 节点数量:使用replication_factor = 3时至少需要3台机器。
  • 网络:各节点间需能进行IP通信。NAT环境下优先推荐使用IPv6
  • VPN方案:NAT环境下无法使用IPv6时,可配置NebulaYggdrasilWireGuard等网状VPN。
  • 存储:将元数据存储用SSD和数据存储用HDD分离有利于提升性能。

3.2 安装方式指南

Docker容器部署:

# docker-compose.yml 示例
version: '3'
services:
  garage:
    image: dxflrs/garage:v1.0
    ports:
      - "3900:3900"   # S3 API
      - "3901:3901"   # RPC
      - "3902:3902"   # Admin API
      - "3903:3903"   # Web(静态站点)
    volumes:
      - ./garage.toml:/etc/garage.toml
      - ./meta:/var/lib/garage/meta
      - ./data:/var/lib/garage/data
    restart: unless-stopped

Systemd服务注册:

[Unit]
Description=Garage S3-compatible object store
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
ExecStart=/usr/local/bin/garage server
Environment=GARAGE_CONFIG_FILE=/etc/garage.toml
Restart=always
RestartSec=5
StateDirectory=garage

[Install]
WantedBy=multi-user.target

3.3 配置文件(garage.toml)核心项

# 元数据存储路径(推荐SSD)
metadata_dir = "/var/lib/garage/meta"

# 数据块存储路径(可用HDD)
data_dir = "/var/lib/garage/data"

# 数据库引擎选择
db_engine = "lmdb"

# RPC通信设置
rpc_bind_addr = "[::]:3901"
rpc_public_addr = "192.168.1.10:3901"
rpc_secret = "在此输入32字节HEX密钥"

# 复制设置
replication_factor = 3

# 块大小(默认1MB)
block_size = 1048576

# S3 API端点
[s3_api]
api_bind_addr = "[::]:3900"
s3_region = "garage"
root_domain = ".s3.garage.localhost"

# S3 Web(静态站点托管)
[s3_web]
bind_addr = "[::]:3903"
root_domain = ".web.garage.localhost"

# Admin API
[admin]
api_bind_addr = "[::]:3902"
admin_token = "管理员令牌"
metrics_token = "指标令牌"

配置文件创建后,通过garage CLI进行集群配置:

# 查看集群状态
garage status

# 为节点分配存储容量
garage layout assign -z dc1 -c 100G -t node1 <node-id>

# 应用布局变更
garage layout apply --version 1

# 创建存储桶
garage bucket create my-bucket

# 创建访问密钥
garage key create my-app-key

# 为密钥授予存储桶权限
garage bucket allow --read --write my-bucket --key my-app-key

4. Garage调优与运维优化

4.1 元数据引擎选择

引擎 特点 推荐环境
LMDB(默认) 最高性能,测试最充分。但架构相关且不支持32位 replication_factor >= 2的生产集群
SQLite 可移植性好,异常关机恢复能力强。比LMDB慢 单节点或异构架构环境
Fjall(实验性) 基于LSM树,理论上具有更高的写入吞吐量 仅限测试环境(禁止生产使用)

4.2 性能调优

  • block_size调整:默认1MB。大文件为主的环境可增大该值以减少分块数量。
  • 写缓冲区:默认256MiB。在写负载较高的环境中,可增大该值以提升吞吐量。
  • SSD/HDD分离策略:将元数据(metadata_dir)放在SSD上,数据块(data_dir)放在HDD上,这是性价比最优的组合。
  • 文件系统选择:元数据存储推荐使用BTRFSZFS

4.3 监控与日志

  • 日志级别:通过RUST_LOG环境变量控制。可用级别:errorwarninfo(默认)、debugtrace
  • Prometheus指标:可通过Admin API的/metrics端点以Prometheus格式收集指标。
  • OpenTelemetry追踪:可与Jaeger或Zipkin集成,分析性能瓶颈。

5. Garage vs 竞品对比

5.1 Garage vs MinIO

  • 资源需求:Garage可在Raspberry Pi上运行,超级轻量。MinIO需要中高配置硬件。
  • 性能:在原始吞吐量基准测试中MinIO占优,但Garage在资源效率方面提供更好的性价比。
  • 地理分布:Garage最大的差异化因素。MinIO的多站点部署需要复杂的架构设计,而Garage原生支持地理分布。
  • 许可证:两者都是AGPLv3,但MinIO已转向附加商业许可的双重许可模式。

5.2 Garage vs Ceph RGW

  • 复杂度:Ceph需要理解OSD、MON、MDS、CRUSH算法等众多组件。Garage仅需单一二进制文件和一个配置文件。
  • 存储效率:Ceph支持纠删码(Erasure Coding),可以比副本复制更少的开销保护数据。Garage目前仅支持简单副本复制。
  • 多租户:Ceph RGW提供命名空间隔离、资源配额等企业级多租户功能。Garage使用按存储桶-按密钥的简单权限模型。

5.3 对比总结表

项目 Garage MinIO Ceph RGW
开发语言RustGoC++
许可证AGPLv3AGPLv3+商用LGPL(完全开源)
部署复杂度非常低低~中
S3兼容性核心功能为主最完整广泛
纠删码不支持(3x副本)支持支持(灵活K+M)
地理分布核心功能需复杂配置支持(复杂)
资源需求非常低中~高
静态站点托管内置支持不支持不支持
最佳适用场景中小规模自托管高性能单集群大规模统一存储

6. 实战应用案例与集成

  • Nextcloud外部存储:通过Nextcloud的"External Storage"应用,可将Garage作为S3兼容后端连接。
  • Mastodon/Misskey媒体存储:将用户上传的图片、视频等媒体文件存储在Garage中。Mastodon默认提供S3兼容存储配置,集成简便。
  • 静态网站托管:Garage的独有功能,无需Nginx或Apache即可直接将存储桶内容作为网站提供服务。适合部署Hugo、Jekyll、Astro等静态站点生成器的构建结果。
  • Peertube视频存储:可作为分布式视频托管平台Peertube的视频文件存储后端。
  • 备份存储:与rcloneresticDuplicity等备份工具集成,作为远程备份存储使用。得益于地理分布式复制功能,非常适合作为灾难恢复(DR)策略的核心组件。
  • GitLab/Gitea制品存储:将CI/CD流水线生成的构建制品存储在Garage中,减轻Git托管服务器的本地磁盘压力。

结论:何时选择Garage

Garage并非适用于所有场景的万能方案。但在特定条件下,它可以成为比任何其他替代方案都更优秀的选择。Garage最能发挥优势的场景包括:在中小规模自托管环境中希望最小化运维复杂性时;希望将分布在多个物理位置的设备整合为一个存储集群时;希望利用异构硬件(二手PC、Raspberry Pi、NAS等)时;以及需要零外部依赖的简单而稳固的对象存储时。

同时,Garage当前的局限性也很明确。对象版本控制尚未支持;因不支持纠删码,3倍副本复制时存储效率较低;S3 API实现不完整,依赖高级S3功能的工作流可能遇到兼容性问题。此外,在原始性能方面不及MinIO,不适合对高吞吐量有严格要求的AI/ML流水线或大规模数据分析工作负载。

总之,存储方案的选择不应仅凭功能列表来决定。需要综合考虑工作负载特征故障模型运维约束条件。如果需要大规模企业级统一存储,选择Ceph;如果在单集群中需要最大性能,选择MinIO;如果在小规模自托管环境中需要简单稳固的地理分布式存储,请选择Garage。