这是本节的多页打印视图。 .
核心运维概念
MinIO 部署由哪些组件构成?
一个 MinIO 部署由一组存储和计算资源构成,这些资源运行一个或多个 minio server 节点,并共同作为单一对象存储库。
一个单机 MinIO 实例由单个 服务器池 和单个 minio server 节点组成。 单机实例最适合初期开发和评估。
MinIO 部署既可以直接运行在 裸金属 或非虚拟化基础设施中的物理设备上。 MinIO 也可以运行在云服务中的虚拟机上,例如使用 Docker、Podman 或 Kubernetes。 MinIO 可以运行在本地、私有云或市场上的众多公有云中。
你设计、架构和构建系统的具体方式称为系统的 拓扑。
MinIO 支持哪些系统拓扑?
MinIO 可以部署到以下三种拓扑:
-
单机单盘,单个 MinIO server,使用单个驱动器或文件夹存储数据
例如,在本地 PC 上使用硬盘中的一个文件夹进行测试。
-
单机多盘,单个 MinIO server,使用多个挂载驱动器或文件夹存储数据
例如,一个挂载了两个或更多卷的单容器。
-
多机多盘,多个 MinIO server,使用多个挂载驱动器或卷存储数据
对于裸金属 基础设施,你可以使用 Ansible、Terraform 或手动流程安装并管理分布式 MinIO 部署。
对于 Kubernetes 基础设施,请使用 MinIO Operator 来管理和部署分布式 MinIO Tenant。
分布式 MinIO 部署如何工作?
分布式部署会利用多台物理机或虚拟机的计算和存储资源。 在现代场景中,这通常意味着在私有云或公有云环境中运行 MinIO,例如 Amazon Web Services、Google Cloud Platform、Microsoft Azure 等。
MinIO 如何管理多个虚拟或物理服务器?
虽然测试 MinIO 可能只涉及一台计算机上的单个驱动器,但大多数生产级 MinIO 部署都会使用多个计算和存储设备来构建高可用环境。 服务器池 是一组 minio server 节点,它们汇聚各自的驱动器和资源,以支持对象存储写入和读取请求。
MinIO 支持向现有部署中添加一个或多个 服务器池,以实现横向扩容。 当 MinIO 拥有多个可用 服务器池 时,单个对象始终会写入同一个 服务器池 中的同一个纠删码集合。
如果某个 服务器池 发生故障,MinIO 会停止所有服务器池的 I/O,直到集群恢复正常运行。 你必须将该服务器池恢复到可工作状态,部署的 I/O 才能恢复。 在执行修复操作期间,写入其他服务器池的对象仍会安全保留在磁盘上。
传递给 minio server 命令的 HOSTNAME 参数表示一个 服务器池:
请看下面的启动命令示例。该命令会创建一个单独的 服务器池,其中包含 4 个 minio server 节点,每个节点有 4 块驱动器,总计 16 块驱动器。
在同一条 minio server 启动命令中启动多个 服务器池,可使各个 服务器池 对等节点彼此可感知。
有关完整语法和用法,请参阅 minio server。
MinIO 如何将多个 服务器池 连接为单一 MinIO 集群?
cluster 指由一个或多个 服务器池 组成的完整 MinIO 部署。
请看下面的命令。它创建了一个由两个 服务器池 组成的 cluster,每个服务器池都包含 4 个 minio server 节点,且每个节点有 4 块驱动器,总计 32 块驱动器。
每个 服务器池 根据其中的驱动器和节点数量,包含一个或多个 纠删码集合。
MinIO 强烈建议生产集群中的每个 服务器池 至少包含 4 个 minio server 节点,以获得恰当的高可用性和持久性保障。
我可以更改现有 MinIO 部署的大小吗?
MinIO 分布式部署 支持通过扩容和退役来增加或减少可用存储。
扩容是指向现有部署中添加一个或多个 服务器池。 每个 服务器池 都由专用节点和存储组成,并为部署的总体容量作出贡献。 服务器池 一旦创建,其大小便无法更改,但你可以随时通过添加或退役服务器池 来增加或移除容量。
有关在裸金属 和 Kubernetes 基础设施上进行扩容的更多信息,请分别参阅 裸金属:扩展 MinIO 部署 和 Kubernetes:扩展 MinIO Tenant。
对于包含多个 服务器池 的部署,你可以 退役 较旧的 pool,并将其中的数据迁移到部署中的较新 pool。 退役一旦开始就无法停止。 MinIO 将退役功能设计为移除硬件老旧的 pool,而不是在任何部署中定期执行的操作。
先下线再新增时保持 pool 顺序
如果你在多 pool 部署中下线了一个 pool,就不能在新 pool 中复用相同的节点编号序列。 例如,假设某个部署包含以下几个 pool:
如果你下线了 minio-{5...8} 这个 pool,就不能再用相同的节点编号新增一个 pool。你必须将新 pool 添加在 minio-{9...12} 之后:
如何管理一个或多个 MinIO 实例或集群?
你可以通过多种方式管理 MinIO 部署和集群:
- 使用命令行工具
mc和mc admin - 使用 MinIO Console 图形用户界面管理单个实例
MinIO 如何管理对象在部署中的分布?
MinIO 会根据各个服务器池 的空闲空间占所有可用 服务器池 总空闲空间的比例,将新对象(即没有现有版本的对象)写入空闲空间最多的 服务器池。 MinIO 不会执行将对象从旧服务器池重新平衡到新服务器池 这类成本高昂的操作。 相反,新对象通常会首先路由到新 pool,因为它拥有最多空闲空间。 随着该服务器池逐渐填满,新的写操作最终会在部署中的所有服务器池之间趋于平衡。 有关写入偏好计算逻辑的更多信息,请参阅下文 写入文件。
扩容后在所有服务器池之间重新平衡数据是一项昂贵操作,需要扫描整个部署并在服务器池之间移动对象。 完成所需时间取决于需要移动的数据量。
从 MinIO 客户端版本 RELEASE.2022-11-07T23-47-39Z 开始,你可以使用 mc admin rebalance 手动在所有 服务器池 之间发起重新平衡操作。
重新平衡不会阻塞现有操作,而是与其他 I/O 并行运行。 这可能导致常规操作性能下降。 建议在非高峰时段安排重新平衡操作,以避免影响生产工作负载。 你可以随时启动和停止重新平衡。
如何向 MinIO 上传对象?
你可以使用任何兼容 S3 的 SDK 向 MinIO 部署上传对象。 每个 SDK 都会执行等价于 PUT 的操作,将对象传输到 MinIO 进行存储。
MinIO 还支持 multipart uploads。 借助该机制,客户端可以将对象拆分为多个 part,以提高吞吐量和传输可靠性。 MinIO 会重组这些 part,直到对象完整,然后将其存储到指定路径。
MinIO 如何提供可用性、冗余性和可靠性?
MinIO 使用 纠删码 提供数据冗余和可靠性
MinIO 纠删码是一项数据冗余和可用性特性,可让具有多块驱动器的 MinIO 部署在集群中丢失多个驱动器或节点的情况下,仍然自动实时重建对象。 与 RAID 或复制等同类技术相比,纠删码以显著更低的开销提供对象级 自愈。
MinIO 通过 bit rot 自愈保护静态数据
bit rot 是一种可能发生在任何存储设备上的随机、静默数据损坏。 bit rot 损坏并非由用户活动触发,系统本身的操作系统通常也无法感知该损坏,因此无法通知用户或管理员数据已发生变化。
bit rot 的常见原因包括:
- 驱动器老化
- 电流尖峰
- 驱动器固件 bug
- 幻写
- 错误定向的读写
- 驱动程序错误
- 意外覆写
MinIO 使用哈希算法确认对象完整性。 该算法会在对象执行任何 GET 和 HEAD 操作时自动生效。 对于启用了版本控制的存储桶,如果 MinIO 识别到版本不一致,PUT 操作也可能触发自愈。 如果对象因 bit rot 而损坏,MinIO 可根据该对象校验分片的可用性,自动 自愈 该对象。
MinIO 还可以使用 MinIO 扫描器 执行 bit rot 检查和自愈。 不过,扫描器的 bit rot 检查默认 关闭。 与 bit rot 同时影响分布在多个驱动器和节点上的多个对象分片这一低概率事件相比,扫描期间主动执行 bit rot 自愈的性能影响较高。 正常操作期间的自动检查通常已足够应对 bit rot,MinIO 不建议将扫描器用于这类健康检查。
MinIO 将数据分布到 纠删码集合 中,以实现高可用性和韧性
纠删码集合是一组支持 MinIO 纠删码 的驱动器。 纠删码为存储在 MinIO 部署上的数据提供高可用性、可靠性和冗余性。
MinIO 会将对象拆分为称作 shards 的块,并将其均匀分布到纠删码集合中的各块驱动器上。 即使任意单块驱动器丢失,MinIO 也可以继续无缝响应读写请求。 在最高冗余级别下,即使部署中最多有一半 () 驱动器丢失,MinIO 仍能以很小的性能影响继续提供读取请求。
MinIO 会根据集合中的驱动器总数以及集合中的 minio server 数量,计算 服务器池 中纠删码集合的大小和数量。 更多信息请参阅 纠删码基础。
MinIO 自动实时自愈损坏或丢失的数据
自愈 是 MinIO 在某些事件导致数据丢失后恢复数据的能力。 数据丢失可能来自 bit rot、驱动器丢失或节点丢失。
如果对象只是部分丢失,纠删码 可继续提供读写访问。
磁盘独占访问
MinIO 要求 对用于对象存储的磁盘或卷拥有 独占 访问权限。 任何其他进程、软件、脚本或人员都不应直接对提供给 MinIO 的磁盘或卷, 或 MinIO 在其上放置的对象或文件执行 任何 操作。
除非得到 MinIO Engineering 的明确指示,否则不要使用脚本或工具直接修改、 删除或移动这些磁盘上的任何数据分片、校验分片或元数据文件,包括在磁盘或节点 之间迁移这些文件。 这类操作极有可能导致大范围损坏和数据丢失,超出 MinIO 的自愈能力。
MinIO 使用校验在对象级提供数据保护
包含多块驱动器的 MinIO 部署会将可用驱动器划分为数据驱动器和校验驱动器。 MinIO 纠删码会在写入对象时,将关于对象内容的附加哈希信息写入校验驱动器。 MinIO 使用这些校验信息确认对象完整性,并在必要时恢复某个驱动器或某组驱动器上丢失、缺失或损坏的对象分片。
即使丢失的驱动器总数达到纠删码集合中可用校验设备的数量,MinIO 仍可以继续提供对象的完整访问能力。
通过仲裁提供读写能力
仲裁指执行某项任务所必须可用的最少驱动器数量。 MinIO 为读取数据和写入数据分别定义了不同的仲裁值。
通常,为保持写入对象的能力,MinIO 所需的可用驱动器数量会高于读取对象所需的数量。
1 - 部署架构
本页从生产视角概述 MinIO 的部署架构。 有关具体硬件或软件配置的信息,请参阅:
分布式 MinIO 部署
生产级 MinIO 部署至少由 4 台具有同构存储和计算资源的 MinIO 主机构成。
MinIO 会将这些资源聚合为一个 pool,并以单一对象存储服务的形式对外提供。
![]()
该 服务器池中的每台 MinIO 主机都具有一致的计算、存储和网络配置
使用本地直连存储时,MinIO 可提供最佳性能,例如连接到主机 PCI-E 控制器板上的 NVMe 或 SSD 驱动器。
存储控制器应以 XFS 格式化驱动器并采用 “Just a Bunch of Drives” (JBOD) 配置呈现,不使用 RAID、池化或其他硬件/软件韧性层。 MinIO 不建议使用缓存,无论是在驱动器层还是控制器层。 任意一种缓存都会在填充和清空时导致 I/O 尖峰,从而带来不可预测的性能。
![]()
每块 SSD 都通过 SAS 连接到以 HBA 模式运行的 PCI-E 直连存储控制器
MinIO 会自动将 服务器池中的驱动器分组为 纠删码集合。
纠删码集合是 MinIO 可用性与韧性 的基础组件。 MinIO 会在 服务器池的各节点间对纠删码集合进行对称条带化,以保持纠删码集合驱动器分布均匀。 随后,MinIO 会根据部署的 校验 将对象拆分为数据分片和校验分片,并将其分布到纠删码集合中。
如需更完整地了解 MinIO 的冗余和自愈机制,请参阅 纠删码 和 对象自愈。
![]()
当校验值为最高的 EC:8时,MinIO 会将对象切分为 8 个数据块和 8 个校验块,并分布到纠删码集合中的各块驱动器上。 此 服务器池中的所有纠删码集合都具有相同的条带大小和分片分布。
MinIO 使用基于对象名称和路径的确定性哈希算法,为给定对象选择纠删码集合。
对于每个唯一对象命名空间
BUCKET/PREFIX/[PREFIX/...]/OBJECT.EXTENSION,MinIO 在读写操作中始终会选择相同的纠删码集合。 MinIO 会处理 服务器池和纠删码集合内部的所有路由,使选择、读取和写入过程对应用完全透明。![]()
MinIO 会在将对象返回给请求客户端之前,透明地从数据分片或校验分片重建对象。
每个 MinIO server 都完整掌握分布式拓扑,因此应用可以连接到部署中的任意节点并对其发起操作。
响应请求的 MinIO 节点会自动处理对部署中其他节点的内部路由,并将最终响应返回给客户端。
应用通常不应自行管理这些连接,因为部署拓扑的任何变化都可能要求应用随之更新。 生产环境应部署负载均衡器或类似网络控制平面组件,以管理到 MinIO 部署的连接。 例如,你可以部署 NGINX 负载均衡器,对部署中的可用节点执行 “least connections” 或 “round robin” 负载均衡。
![]()
负载均衡器会将请求路由到部署中的任意节点。 之后由接收请求的节点处理所有节点间请求。
你可以通过 pool 扩容 增加 MinIO 部署的可用存储。
每个 服务器池都是由自身纠删码集合组成的独立节点组。 MinIO 必须查询每个 服务器池,才能确定读写操作应定向到哪个纠删码集合,因此每增加一个 服务器池,每次调用的节点间流量都会相应增加。 包含目标纠删码集合的 服务器池随后会响应该操作,而这一过程对应用完全透明。
如果你通过 服务器池扩容修改了 MinIO 拓扑,可以通过更新负载均衡器,将新 服务器池的节点纳入应用流量。 应用仍可继续使用该 MinIO 部署的负载均衡器地址,而无需更新或修改。 这样既能保证请求在所有 服务器池之间均匀分布,又能让应用继续使用单一负载均衡器 URL 访问 MinIO。
![]()
PUT 请求需要检查每个 服务器池,以确定目标纠删码集合。 一旦识别完成,MinIO 就会切分对象,并将数据分片和校验分片分布到对应集合中。
客户端应用可以使用任意兼容 S3 的 SDK 或库与 MinIO 部署交互。
MinIO 也发布了专门面向兼容 S3 部署使用的 SDK。
![]()
使用不同兼容 S3 SDK 的客户端可以对同一个 MinIO 部署执行操作。 MinIO 严格实现 S3 API,包括要求客户端对所有操作使用 AWS Signature V4 或 legacy Signature V2 进行签名。 AWS 签名计算依赖客户端提供的 header,因此负载均衡器、代理、安全程序或其他组件若修改这些 header,就会导致签名不匹配错误并使请求失败。 请确保任何此类中间组件都支持将 header 从客户端到服务器原样透传。
虽然 S3 API 的所有操作都使用
GET和POST等 HTTP 方法,应用通常仍会使用 SDK 来执行 S3 操作。 特别是签名计算的复杂性,通常使通过curl或类似 REST 客户端直接交互变得不切实际。 MinIO 建议使用能够自动完成签名计算的兼容 S3 SDK 或库。
复制型 MinIO 部署
MinIO 站点复制 支持在彼此独立的部署之间进行同步。
你可以将对等站点部署在不同机架、数据中心或地理区域,以支持 BC/DR,或为全球分布式 MinIO 对象存储提供地理就近的读写性能。
![]()
一个包含三个对等站点的 MinIO 多站点部署。 写入某个对等站点的操作会自动复制到配置中的其他所有对等站点。
复制性能主要取决于各对等站点之间的网络延迟。
当对等站点跨地理区域分布时,站点间的高延迟可能导致显著复制滞后。 如果工作负载已经接近或达到部署的总体性能上限,这一问题会进一步放大,因为复制过程本身也需要足够的空闲 I/O 来同步对象。
![]()
在此对等配置中,站点 A 与其他对等站点之间的延迟为 100ms。 对象最早也要在 110ms 之后才能完成对所有站点的同步。
部署支持站点间故障切换协议的全局负载均衡器或类似网络设备,是多站点部署正常工作的关键。
负载均衡器应支持 health probe/check 设置,以检测某个站点故障,并自动将应用重定向到其他健康对等站点。
![]()
负载均衡器会根据配置逻辑(地理就近、延迟等)自动路由客户端请求。 写入某个站点的数据会自动复制到另一个对等站点。 在连接均衡和 header 保留方面,负载均衡器应满足与单站点部署相同的要求。 MinIO 复制会通过排队对象来处理瞬时故障。
2 - 可用性与韧性
本页从生产视角概述 MinIO 在可用性与韧性方面的设计和特性。
说明
本页内容旨在尽力帮助你理解 MinIO 在可用性与韧性方面的预期设计和理念。 它不能替代 MinIO SUBNET 的能力。使用 MinIO SUBNET 可以在规划 MinIO 部署时与 MinIO Engineering 协同。
社区用户可以通过 MinIO Community Slack 寻求支持。 社区支持仅为 best-effort,不提供关于响应时间的 SLA。
分布式 MinIO 部署
MinIO 将 纠删码 作为在驱动器级或节点级故障期间提供可用性与韧性的核心组件。
MinIO 会将每个对象拆分为数据分片和 校验 分片,并将这些分片分布到单个 纠删码集合 中。
![]()
这个小型单节点部署在一个纠删码集合中拥有 16 块驱动器。 假设使用默认 校验 EC:4,MinIO 会将对象拆分为 4 个校验分片和 12 个数据分片。 MinIO 会将这些分片均匀分布到纠删码集合中的各块驱动器上。
MinIO 使用确定性算法为给定对象选择纠删码集合。
对于每个唯一对象命名空间
BUCKET/PREFIX/[PREFIX/...]/OBJECT.EXTENSION,MinIO 在读写操作中始终会选择相同的纠删码集合。 这也包括同一对象的所有 版本。![]()
MinIO 使用完整对象命名空间来计算目标纠删码集合。
MinIO 需要满足 读写仲裁 才能对纠删码集合执行读写操作。
仲裁取决于部署配置的校验值。 读仲裁始终等于配置的校验值,因此只要某个纠删码集合丢失的驱动器数不超过校验值,MinIO 就可以对其执行读操作。
![]()
该节点有两块驱动器故障。 MinIO 会自动使用校验分片替换丢失的数据分片,并将重建后的对象返回给请求客户端。 当默认校验值为
EC:4时,部署中的每个纠删码集合最多可容忍 4 块驱动器丢失,同时仍能继续提供读操作。
写仲裁取决于配置的校验值和纠删码集合大小。
如果校验值小于纠删码集合驱动器数量的 1/2,则写仲裁等于校验值,其行为与读仲裁相似。
MinIO 会自动提高写入降级纠删码集合的对象校验值,以确保该对象能够满足与健康纠删码集合中对象相同的 SLA。 这种校验升级行为提供了额外的风险缓解层,但无法替代修复或更换损坏驱动器这一长期解决方案,后者才是让纠删码集合恢复到完全健康状态的根本方法。
![]()
该节点有两块驱动器故障。 MinIO 会以升级后的 EC:6校验值写入对象,以确保该对象满足与其他对象相同的 SLA。当默认校验值为
EC:4时,部署中的每个纠删码集合最多可容忍 4 块驱动器丢失,同时仍能继续提供写操作。
如果校验值等于纠删码集合驱动器数量的 1/2,则写仲裁等于校验值加 1,以避免因 “split brain” 场景导致数据不一致。
例如,如果纠删码集合中恰好一半驱动器因网络故障而被隔离,MinIO 会认为仲裁丢失,因为它无法为写操作建立一个 N+1 驱动器组。
![]()
该节点有 50% 的驱动器故障。 如果校验值为 EC:8,该纠删码集合就无法满足写仲裁,MinIO 会拒绝对此集合的写操作。 由于该纠删码集合仍然满足读仲裁,对现有对象的读操作仍可能成功。
纠删码集合如果永久丢失的驱动器数量超过配置校验值,就意味着已经发生数据丢失。
对于最高校验配置,如果驱动器丢失数量等于校验值,纠删码集合就会进入
read only模式。 对于最大纠删码集合大小 16 和最大校验值 8 的情况,需要丢失 9 块驱动器才会发生数据丢失。![]()
该纠删码集合丢失的驱动器数量超过了配置的 EC:4校验值,因此已经同时失去读仲裁和写仲裁。 MinIO 无法恢复存储在该纠删码集合中的任何数据。某些瞬时或临时驱动器故障,例如由存储控制器或连接硬件故障引起的情况,仍可能在该纠删码集合内恢复到正常运行状态。
MinIO 还会通过在 pool 的每个节点间对纠删码集合驱动器进行对称条带化,进一步降低纠删码集合故障风险。
MinIO 会根据节点数和驱动器数自动计算最佳纠删码集合大小,其中最大集合大小为 16。 随后,它会跨 pool 为每个纠删码集合从每个节点选择一块驱动器;如果纠删码集合条带大小大于节点数,则会循环选择。 这种拓扑可对单节点故障,甚至该节点上的单个存储控制器故障提供韧性。
![]()
在此 16 x 8 部署中,MinIO 会计算出 8 个纠删码集合,每个集合 16 块驱动器。 它会在所有可用节点上为每个纠删码集合分配每节点 1 块驱动器。 如果只有 8 个节点,则 MinIO 需要为每个纠删码集合从每个节点选择 2 块驱动器。 在上述拓扑中,该 pool 具有 8 个跨 16 个节点条带化的 16 驱动器纠删码集合。 每个节点都会为每个纠删码集合分配 1 块驱动器。 虽然丢失一个节点在技术上意味着丢失 8 块驱动器,但每个纠删码集合实际上只会各丢失 1 块驱动器。 这使得即使节点停机,系统仍能保持仲裁。
同一 pool 中的每个纠删码集合彼此独立。
即使一个纠删码集合完全降级,MinIO 仍可对其他纠删码集合执行读写操作。
![]()
一个 pool 中有一个降级纠删码集合。 虽然 MinIO 已无法对该纠删码集合执行读写操作,但它仍能继续对该 pool 中健康的纠删码集合提供服务。 不过,丢失的数据仍可能影响依赖 100% 数据可用性假设的工作负载。 此外,每个纠删码集合都与其他集合完全独立,因此你不能使用其他纠删码集合来恢复一个完全降级的纠删码集合中的数据。 你必须使用 站点 或 存储桶 复制,创建一个具备 BC/DR 能力的远端部署,用于恢复丢失的数据。
对于多 pool MinIO 部署,每个 pool 都至少需要有一个纠删码集合保持读写仲裁,才能继续提供操作能力。
如果某个 pool 丢失了全部纠删码集合,MinIO 就无法再判断某次读写操作原本是否应被路由到该 pool。 因此,即使其他 pool 仍然可用,MinIO 也会停止整个部署中的所有 I/O。
![]()
该部署中的一个 pool 已完全故障。 MinIO 无法再确定 I/O 应路由到哪个 pool 或纠删码集合。 如果继续操作,就可能产生不一致状态,使对象及其版本分布在不同纠删码集合中。 因此,MinIO 会暂停部署中的所有 I/O,直到该 pool 恢复。 要恢复对该部署的访问,管理员必须将该 pool 恢复到正常运行状态。 这可能需要根据故障严重程度执行磁盘格式化、硬件更换或节点更换。 更完整的文档请参阅 硬件故障恢复。
你可以使用复制远端将丢失数据恢复回该部署。 存储在健康 pool 中的所有数据仍会安全保留在磁盘上。
磁盘独占访问
MinIO 要求 对用于对象存储的磁盘或卷拥有 独占 访问权限。 任何其他进程、软件、脚本或人员都不应直接对提供给 MinIO 的磁盘或卷, 或 MinIO 在其上放置的对象或文件执行 任何 操作。
除非得到 MinIO Engineering 的明确指示,否则不要使用脚本或工具直接修改、 删除或移动这些磁盘上的任何数据分片、校验分片或元数据文件,包括在磁盘或节点 之间迁移这些文件。 这类操作极有可能导致大范围损坏和数据丢失,超出 MinIO 的自愈能力。
复制型 MinIO 部署
对于 MinIO 部署中发生的小规模或大规模数据丢失,MinIO 将 站点复制 作为保证业务连续性和灾难恢复 (BC/DR) 的主要手段。
![]()
每个对等站点都部署在独立数据中心,以防范大规模故障或灾难。 如果某个数据中心完全离线,客户端可以故障切换到另一个站点。
MinIO 复制可以在站点因瞬时或持续停机而发生部分或全部数据丢失时,自动 自愈 该站点。
![]()
Datacenter 2 曾经离线,Site B 需要重新同步。 负载均衡器会将操作路由到 Datacenter 1 中的 Site A。 Site A 会持续将数据复制到 Site B。 一旦所有数据同步完成,你就可以恢复对该站点的正常连接。 根据复制滞后量、站点间延迟以及整体工作负载的 I/O 情况,你可能需要临时停止写操作,让各站点完全追平。
如果某个对等站点彻底故障,你可以将其从配置中完全移除。 负载均衡器配置也应移除该站点,以避免将客户端请求路由到离线站点。
然后,你可以在修复原始硬件或完全更换硬件后,通过 将其重新加入站点复制配置 来恢复该对等站点。 MinIO 会在持续复制新数据的同时,自动开始重同步已有数据。
站点在重同步期间仍可通过将 GET/HEAD 请求代理到健康对等站点来继续处理操作
![]()
Site B 不具备所请求的对象,可能是由于复制滞后。 它会将 GET请求代理到 Site A。 Site A 返回对象后,Site B 再将其返回给请求客户端。客户端会收到首个返回所请求对象任意版本的对等站点结果。
PUT和DELETE操作通过常规复制流程进行同步。LIST操作不会代理,客户端必须只对健康对等站点发起这类请求。
3 - 纠删码
MinIO 将纠删码作为提供数据冗余和可用性的核心组件。 本页介绍 MinIO 的纠删码机制。
有关 MinIO 如何在生产部署中使用纠删码的更多信息,请参阅 可用性与韧性 和 部署架构。
纠删码基础
说明
本节中的图示和内容仅用于说明 MinIO 纠删码操作的简化视图,并不完整呈现 MinIO 纠删码实现的全部复杂性。
MinIO 会将每个 服务器池 中的驱动器分组为一个或多个相同大小的纠删码集合。
![]()
上述示例部署由 4 个节点组成,每个节点有 4 块驱动器。 MinIO 初始化后会生成一个纠删码集合,覆盖这 4 个节点上的全部 16 块驱动器。 MinIO 会在初始化 服务器池 时确定纠删码集合的最佳数量和大小。 初次设置完成后,便无法再修改这些参数。
对于每次写操作,MinIO 都会将对象切分为数据和校验分片。
纠删码集合的条带大小决定了部署可用的最大 校验 值。 生成数据分片和校验分片数量的公式如下:
![]()
上述示例部署的纠删码集合包含 16 块驱动器。 这意味着它支持从 EC:0到纠删码集合驱动器数量 1/2 的校验值,也就是最高EC:8。
你可以将校验值设置在 0 到纠删码集合大小的 1/2 之间。
![]()
MinIO 使用 Reed-Solomon 纠删码实现来切分对象,并将其分布到纠删码集合中。 上述示例部署的纠删码集合大小为 16,校验值为 EC:4。对象一旦按某个校验设置写入,即使之后修改校验值,也不会自动更新。
MinIO 至少需要 K 个任意类型的分片才能读取对象。
这里的
K构成部署的读仲裁。 因此,纠删码集合中至少要有K块健康驱动器,才能支持读操作。![]()
该部署中有一个节点离线,因此只剩下 12 块健康驱动器。 该对象按 EC:4写入,其读仲裁为K=12。 因此该对象仍满足读仲裁,MinIO 可以重建对象并响应读操作。对于已经失去读仲裁的对象,MinIO 无法进行重建。 这类对象可能需要通过其他方式恢复,例如 复制重同步。
MinIO 至少需要 K 块纠删码集合驱动器才能写入对象。
这里的
K构成部署的写仲裁。 因此,纠删码集合中至少要有K块可用驱动器在线,才能支持写操作。![]()
该部署中有一个节点离线,因此只剩下 12 块健康驱动器。 客户端按 EC:4校验设置写入对象,此时该纠删码集合的写仲裁为K=12。 该纠删码集合仍满足写仲裁,因此 MinIO 可以用它执行写操作。
当校验 EC:M 恰好等于纠删码集合大小的 1/2 时,写仲裁为 K+1。
这样可以防止 split-brain 场景,例如网络故障导致纠删码集合中的一半驱动器与另一半完全隔离。
![]()
该部署中有两个节点因临时网络故障而离线。 客户端按 EC:8校验设置写入对象,此时该纠删码集合的写仲裁为K=9。 该纠删码集合已经失去写仲裁,因此 MinIO 无法将其用于写操作。
K+1逻辑可确保客户端不会把同一个对象分别写入纠删码集合的两个“半边”,从而避免潜在的不一致。
对于仍满足读仲裁的对象,MinIO 可以使用任意数据分片或校验分片来 自愈 受损分片。
![]()
一个按 EC:4写入的对象由于驱动器故障,在 12 个数据分片中丢失了 4 个。 由于该对象仍满足读仲裁,MinIO 可以使用现有的校验分片对丢失的数据分片执行自愈。
你可以使用 MinIO 纠删码计算器,为计划中的拓扑探索可能的纠删码集合大小和分布方式。 如无特殊原因,建议使用偶数个节点和每节点偶数块驱动器,以简化拓扑规划以及驱动器和纠删码集合分布的理解。
磁盘独占访问
MinIO 要求 对用于对象存储的磁盘或卷拥有 独占 访问权限。 任何其他进程、软件、脚本或人员都不应直接对提供给 MinIO 的磁盘或卷, 或 MinIO 在其上放置的对象或文件执行 任何 操作。
除非得到 MinIO Engineering 的明确指示,否则不要使用脚本或工具直接修改、 删除或移动这些磁盘上的任何数据分片、校验分片或元数据文件,包括在磁盘或节点 之间迁移这些文件。 这类操作极有可能导致大范围损坏和数据丢失,超出 MinIO 的自愈能力。
纠删码校验与存储效率
为部署设置校验值,本质上是在可用性与总可用存储之间做平衡。 更高的校验值会提高对驱动器或节点故障的容忍度,但会减少可用存储;更低的校验值则提供更高的可用存储,但对驱动器或节点故障的容忍度也更低。 你可以使用 MinIO 纠删码计算器,查看不同校验值对计划中集群部署的影响。
下表列出了由 1 个节点和 16 块 1TB 驱动器组成的 MinIO 部署在不同纠删码校验级别下的结果:
| 校验 | 总存储 | 存储比例 | 读操作所需最少驱动器 | 写操作所需最少驱动器 |
|---|---|---|---|---|
EC: 4 (默认) |
12 Tebibytes | 0.750 | 12 | 12 |
EC: 6 |
10 Tebibytes | 0.625 | 10 | 10 |
EC: 8 |
8 Tebibytes | 0.500 | 8 | 9 |
位腐化防护
Bit rot 是一种静默数据损坏,由存储介质层面的随机变化引起。 对于数据驱动器而言,它通常来自表示数据的电荷衰减或磁取向变化。 成因可以从停电时的微小电流尖峰,到导致比特翻转的随机宇宙射线。 这种“bit rot”会在不触发监控工具或硬件告警的情况下,对数据介质造成细微错误或损坏。
MinIO 对 HighwayHash algorithm 的优化实现,确保其能够在运行时捕获并自愈受损对象。 它通过在 READ 时计算哈希并在 WRITE 时进行校验,确保从应用、网络到内存或驱动器的端到端完整性。 该实现专为速度设计,在 Intel CPU 上单核即可达到超过 10 GB/sec 的哈希速度。
4 - 对象自愈
什么是自愈?
自愈是 MinIO 恢复受损、损坏或部分丢失对象的能力。 这类丢失或损坏可能来自多种情况,包括但不限于:
- 驱动器级错误或故障
- 操作系统或文件系统错误或故障
- bit rot
自愈与纠删码
MinIO 恢复受损对象的能力,直接取决于以下因素:
-
对象所在 纠删码集合 的驱动器总数
-
保留对象完整分片的可用驱动器数量
-
该纠删码集合的 校验设置
Parity 指 MinIO 在写入对象时创建的专用恢复分片数量。 例如,一个纠删码集合可能总共有 8 块驱动器,其中 3 块用于校验。 在这种情况下,MinIO 会把对象拆分为 5 个数据分片和 3 个校验分片。 MinIO 会将这 8 个分片分布到纠删码集合中的各块驱动器上。 不会有某一块驱动器只包含校验分片或只包含数据分片。 相反,MinIO 会以随机化方式写入每个对象的分片,以便将读取均匀分散到各块驱动器上。
当 MinIO 需要返回该对象时,它会查找对象对应的数据分片。 如果某些数据分片丢失或损坏,MinIO 会使用一个或多个校验分片来恢复对象。 如果在查找校验分片时发现某些校验分片也丢失或损坏,只要仍有足够的其他分片可供返回对象,MinIO 也会一并恢复这些校验分片。 在上述场景中,即使最多有 3 个数据分片丢失或损坏,MinIO 仍然可以成功恢复并返回该对象。
保留对象完整数据分片或校验分片的可用驱动器数量,必须大于或等于该纠删码集合中用于数据分片的驱动器数量。 在上述场景中,至少需要 5 块保留完整分片的驱动器在线且可用,MinIO 才能成功返回该对象。
MinIO 何时对对象执行自愈?
MinIO 提供了一套健壮的对象自愈机制。
在 GET 请求期间自愈
每当你通过 GET 或 HEAD 请求对象时,MinIO 都会自动检查该对象数据分片的一致性。 对于启用了版本控制的存储桶,MinIO 在 PUT 操作期间也会执行一致性检查。
如果所有数据分片都完好无损,MinIO 会直接从数据分片返回对象,而不会检查对应的校验分片。
如果对象存在丢失或损坏的数据分片,MinIO 会先使用可用的校验分片对对象执行自愈,然后再作为本次操作的一部分返回。 每个丢失或损坏的数据分片都 必须 有一个完好的校验分片可用,否则对象无法恢复。 如果某些校验分片丢失或损坏,只要仍有足够的其他校验分片可用于返回对象,MinIO 也会恢复这些校验分片。
通过对象扫描器自愈
MinIO 使用 对象扫描器 执行多项与对象相关的任务。 其中一项任务就是检查对象完整性,并在发现损坏或损毁时执行自愈。
在每一轮扫描中,MinIO 会根据对象名称的哈希值,从每 1,024 个对象中选择 1 个进行检查。
如果发现对象存在分片丢失,MinIO 会使用可用分片对对象执行自愈。 默认情况下,MinIO 不会 使用扫描器检查 bit rot 损坏。 这类操作的成本较高,而多个磁盘同时发生 bit rot 的概率较低。
通过手动请求自愈
管理员可以使用 mc admin heal 发起一次全系统自愈。 该过程会大量消耗资源,通常并非必需。
在部署上手动启动自愈流程之前,请先与 MinIO 工程师沟通。
自愈指标
MinIO 提供了若干自愈指标(英文),用于监控部署中的自愈过程状态。
有关可用 endpoint 和配置的更多信息,请参阅 指标与告警。
5 - 对象扫描器
概览
MinIO 使用内置扫描器检查对象是否需要自愈,并执行任何已计划的对象操作。 这类操作可能包括:
扫描器在两个层级执行这些功能:集群层级和存储桶层级。 在集群层级,扫描器会将所有存储桶划分为多个组,并一次扫描其中一组。 扫描器会先处理自上次扫描以来新增的存储桶,然后再以随机顺序扫描其他存储桶。 在完成所有存储桶组的检查后,扫描器会重新开始新一轮扫描。
在存储桶层级,扫描器会对存储桶内条目分组,并从该存储桶中选择部分条目进行扫描。 扫描器会根据对象名称的哈希值来选择要扫描的对象。 在 16 轮扫描的周期内,MinIO 会检查命名空间中的每个对象。 对于自上次扫描以来确认新增的任何前缀,MinIO 会执行完整扫描。
扫描时长
影响一次扫描完成时间的因素有很多。
其中包括:
- 提供给 MinIO 的驱动器类型
- 可用吞吐量和 iops
- 对象数量和大小
- MinIO Server 上的其他活动
例如,默认情况下,MinIO 会暂停扫描器,以便将 I/O 资源让给读写请求。 这会拉长扫描完成所需的时间。
MinIO 在每次扫描之间的等待时间,会按本次扫描操作耗时乘以一个系数来计算。 默认情况下,该系数为 10.0,表示 MinIO 会在一次扫描完成后等待相当于该操作耗时 10 倍的时间,再开始下一次扫描。 这个系数会根据配置的 扫描器速度设置 发生变化。
扫描器性能
影响扫描器性能的因素有很多。 其中包括:
- 可用节点资源
- 集群规模
- 纠删码集合数量相对于驱动器数量的关系
- 存储桶层级结构的复杂度(对象和前缀)
例如,在相同硬件和工作负载条件下,一个从 100TB 数据增长到 200TB 数据的集群,扫描完整个存储桶和对象命名空间所需的时间会更长。 同样地,单个包含 16 块驱动器的纠删码集合,其扫描耗时会长于把相同数量驱动器拆分为两个 8 驱动器纠删码集合的情况。
MinIO 将扫描器视为后台任务,并会暂停它以优先完成集群中的读写请求。 随着集群规模或工作负载增长,为保证普通 S3 操作的优先级,扫描器会更频繁地让出资源,因此其性能会下降。
你可以使用 MINIO_SCANNER_SPEED 环境变量或 scanner speed 配置项, 调整 MinIO 在扫描器性能与读写操作之间的平衡方式。
扫描器指标
MinIO 提供了若干与扫描器相关的指标(英文)。
使用 mc admin scanner info 可以查看扫描器当前状态,以及距离上次完整扫描所经过的时间。 这有助于理解扫描器操作提供的各项指标。
扫描器指标(包括 usage 指标)反映的是最近一次完成的扫描结果。 自上次扫描以来发生的 PUT 或 DELETE 操作,不会在 usage 中体现,直到受影响的存储桶完成下一次扫描。
输出类似如下:
6 - 阈值与限制
本页列出了适用于 MinIO 的阈值与限制。
有关相关建议和要求,请参阅 hardware 和 software。
S3 API 限制
项目 |
规格 |
|---|---|
最大对象大小 |
50 TiB |
最小对象大小 |
0 B |
单次 PUT 操作的最大对象大小 |
非 multipart upload 为 5 TiB multipart upload 为 50 TiB |
每次上传的最大分片数 |
10,000 |
分片大小范围 |
5 MiB 到 5 GiB。最后一个分片可为 0 B 到 5 GiB |
每次 list parts 请求返回的最大分片数 |
10,000 |
每次 list objects 请求返回的最大对象数 |
1,000 |
每次 list multipart uploads 请求返回的最大 multipart upload 数 |
1,000 |
存储桶名称最大长度 |
63 |
对象名称最大长度 |
1024 |
对象名称中每个以 |
255 |
单个唯一对象允许的最大版本数 |
10000(可配置) |
纠删码限制
| 项目 | 规格 |
|---|---|
| 每个集群的最大服务器数 | 无限制 |
| 最小服务器数 | 1 |
| 当服务器数为 1 时,每台服务器的最少驱动器数 | 1(适用于 SNSD 部署,此类部署不提供额外可靠性或可用性) |
| 当服务器数为 2 或更多时,每台服务器的最少驱动器数 | 1 |
| 每台服务器的最大驱动器数 | 无限制 |
| 读仲裁 | |
| 写仲裁 |
对象名称限制
文件系统和操作系统限制
MinIO 中的对象名称主要受本地操作系统和文件系统限制。 Windows 和某些其他操作系统会限制包含特定特殊字符的文件系统名称,例如 ^、*、|、\、/、&、" 或 ;。
此列表并不完整,也不一定适用于你的操作系统和文件系统组合。
在类 Unix 操作系统上,路径名为 .、.. 或 / 的对象会返回 file access denied 错误。
请查阅你的操作系统供应商或文件系统文档,以获得适用于当前环境的完整列表。
MinIO 建议生产工作负载使用基于 XFS 文件系统的 Linux 操作系统。
冲突对象
应用必须为所有对象分配不冲突的唯一键。 这包括避免创建与父对象或同级对象名称发生冲突的对象。 当名称发生冲突时,MinIO 在该位置的 LIST 操作会返回空结果集。
例如,以下操作会创建命名空间冲突:
虽然你仍然可以对这些对象执行 GET 或 HEAD 操作,但名称冲突会导致在 /invoices/2024/january 路径上的 LIST 操作返回空结果集。