分布式文件系统 Minio 实战
分布式文件系统应用场景
互联网海量非结构化数据的存储需求
- 电商网站:海量商品图片
- 视频网站:海量视频文件
- 网盘:海量文件
- 社交网站:海量图片
Minio 介绍
Minio 是一个基于 Apache License v2.0 开源协议的对象存储服务。它兼容 AWS S3 云存储服务接口,非常适合存储大容量非结构化的数据,如图片、视频、日志文件、备份数据等,而一个对象文件可以是任意大小,从几 kb 到最大 5T 不等。
Minio 是一个非常轻量的服务,可以很简单的和其他应用结合。
官网:https://minio.io
中文官网:https://www.minio.org.cn
对象存储服务(OSS)是一种海量、安全、低成本、高可靠的云存储服务,适合存放任意类型的文件,容量和处理能力弹性扩展。
在中国:阿里巴巴、腾讯、百度、中国联通、华为、中国移动等9000多家企业都在使用 Minio。
Minio 优点
- 部署简单:一个二进制文件即是一切,还支持各种平台;
- 支持海量存储:支持单个对象最大 5TB;
- 兼容Amazon S3 接口
- 低冗余且磁盘损坏高容忍:标准且最高的数据冗余系数为2(即存储一个 1M 的数据对象,实际占用的磁盘空间为 2M),但在任意 n/2 块磁盘损坏的情况下依然可以读取数据(n 为一个纠删码集合中的磁盘数量)并且这种损坏恢复是基于单个对象的,而不是基于整个存储卷的
- 读写性能优异
Minio 的基本概念
- Oject:存储到 minio 的基本对象
- Bucket:用来存储 Object 的逻辑空间,每个 bucket 之间的数据是相互隔离的
- Drive:存储数据的磁盘,在 minio 启动时,以参数的方式传入
- Set:一组 Drive 的集合,分布式部署根据集群规模自动划分一个或多个 Set,每个 Set 中的 Drive 分布在不同的位置,一个对象存储在一个 Set 上。
- 一个对象存储在一个 Set 上
- 一个集群划分为多个 Set
- 一个 Set 包含的 Drive 数量是固定的,默认由系统根据集群规模自动计算得出
- 一个 Set 中的 Drive 尽可能分布在不同的节点上
纠删码 EC
Minio 使用纠删码机制来保证高可靠性,使用 highwayhash 来处理数据损坏(Bit Rot Protection)。简单来说就是通过数学计算,把丢失的数据进行还原,它可以将 n 份原始数据,增加 m 份数据,并能通过 n+m 份中的任意 n 份数据,还原为原始数据,即如果有任意小于等于 m 份的数据失效,仍然能通过剩下的数据还原出来。
存储形式
文件对象上传到 minio,会在对应的数据存储磁盘中,以 Bucket 名称为目录名,文件名称为下一级目录,文件名下是 part.1 和 xl.meta,前者是编码数据块及校验块,后者是元数据文件
Minio 环境搭建
官方文档:https://docs.min.io/docs/
中文文档:http://docs.minio.org.cn/docs/
单机部署
minio server 的 standalone 模式,即要管理的磁盘都在 host 本地,该启动模式一般用于实验环境学习使用,在 standalone 模式下,还可以分为 non-erasure code mode 和 erasure code mode。
- non-erasure code mode:在此启动模式下,对于每一份对象数据,minio 直接在 data 目录下存储这份数据,不会建立副本,也不会启用纠删码机制,因此,这种模式无论是服务实例还是磁盘都是单点,无任何高可用保障,磁盘损坏就表示数据丢失。
- erasure code mode:此模式为 minio server 实例传入多个本地磁盘参数,一旦遇到多于一个磁盘参数,minio server 会自动启用 erasure code mode。erasure code 对磁盘的个数是有要求的,如不满足要求,实例启动将失败。erasure code启用后,要求传给 minio server 的磁盘个数至少为 4 个。
基于Centos 7 部署
| |
基于 Docker 部署
| |
纠删码模式
minio 使用纠删码 erasure code 和校验和 check sum 来保护数据免受硬件故障和数据损坏,即使丢失一半数量(n/2)的硬盘,仍然可以恢复数据。
纠删码是一种恢复丢失和损坏数据的数学算法,Minio 采用 Reed-Solomon code 将对象拆分成 n/2 数据和 n/2 奇偶检验块,这就意味着如果是 12 块盘,一个对象会被分成6个数据块、6个奇偶校验块,可以丢失任意6块盘(不管是存放的数据块还是奇偶校验块),仍可以从剩下的盘中的数据进行恢复。
使用 Minio Docker 镜像,在8块盘中启动 Minio 服务:
| |
分布式集群部署
分布式 minio 可以让你将多块磁盘(可以在不同的机器上)组成一个对象存储服务,由于硬盘分布在不同的节点上,分布式 minio 避免了单点故障。
分布式 Minio 优势
数据保护
分布式 Minio 采用纠删码来防范多个节点宕机和位衰减 bit rot。
分布式 Minio 至少需要4块硬盘,使用分布式 Minio 自动引入了纠删码功能。
高可用
单机 Minio 服务存在单点故障,如果一个有 N 块硬盘的分布式 Minio,只要有 N/2 硬盘在线,数据就是安全的,不过需要至少 N/2+1 块硬盘来创建新的对象。
如:一个16节点的 Minio 集群,每个节点16块硬盘,就算有8个节点宕机,这个集群仍然是可读的,不过需要9个节点才能写数据。
一致性
Minio 在分布式和单机模式下,所有读写操作都严格遵守 read-after-write 一致性模型。
部署分布式 Minio
运行一个分布式 Minio 实例,只需要把硬盘位置做为参数传给 Minio server 命令即可,然后,需要在所有其他节点运行同样的命令。
- 分布式 Minio 里所有的节点都需要有同样的 access 秘钥和 secret 秘钥,这样这些节点才能建立联接,新版本使用 MINIO_ROOT_USER 和 MINIO_ROOT_PASSWORD。
- 分布式 Minio 使用的磁盘必须是干净的,里面没有任何数据。
- 分布式 Minio 里的节点时间相差不能超过3秒。
1个节点,4块硬盘
挂载磁盘
创建supervisor配置文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17vim /etc/supervisord.d/minio01.ini [program:minio01] environment = MINIO_ROOT_USER=minioadmin,MINIO_ROOT_PASSWORD=minioadmin command=/usr/local/bin/minio server --address 0.0.0.0:9001 --console-address 0.0.0.0:19001 --config-dir /etc/minio01 http://192.168.200.179:9001/data/minio01 http://192.168.200.179:9002/data/minio02 http://192.168.200.179:9003/data/minio03 http://192.168.200.179:9004/data/minio04 autostart=true startsecs=10 autorestart=true startretries=3 user=root priority=999 redirect_stderr=true stdout_logfile_maxbytes=20MB stdout_logfile_backups=20 stdout_logfile=/data/logs/stdout.log stopasgroup=false killasgroup=false1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17vim /etc/supervisord.d/minio02.ini [program:minio02] environment = MINIO_ROOT_USER=minioadmin,MINIO_ROOT_PASSWORD=minioadmin command=/usr/local/bin/minio server --address 0.0.0.0:9002 --console-address 0.0.0.0:29001 --config-dir /etc/minio02 http://192.168.200.179:9001/data/minio01 http://192.168.200.179:9002/data/minio02 http://192.168.200.179:9003/data/minio03 http://192.168.200.179:9004/data/minio04 autostart=true startsecs=10 autorestart=true startretries=3 user=root priority=999 redirect_stderr=true stdout_logfile_maxbytes=20MB stdout_logfile_backups=20 stdout_logfile=/data/logs/stdout.log stopasgroup=false killasgroup=false1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17vim /etc/supervisord.d/minio03.ini [program:minio03] environment = MINIO_ROOT_USER=minioadmin,MINIO_ROOT_PASSWORD=minioadmin command=/usr/local/bin/minio server --address 0.0.0.0:9003 --console-address 0.0.0.0:39001 --config-dir /etc/minio03 http://192.168.200.179:9001/data/minio01 http://192.168.200.179:9002/data/minio02 http://192.168.200.179:9003/data/minio03 http://192.168.200.179:9004/data/minio04 autostart=true startsecs=10 autorestart=true startretries=3 user=root priority=999 redirect_stderr=true stdout_logfile_maxbytes=20MB stdout_logfile_backups=20 stdout_logfile=/data/logs/stdout.log stopasgroup=false killasgroup=false1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17vim /etc/supervisord.d/minio04.ini [program:minio04] environment = MINIO_ROOT_USER=minioadmin,MINIO_ROOT_PASSWORD=minioadmin command=/usr/local/bin/minio server --address 0.0.0.0:9004 --console-address 0.0.0.0:49001 --config-dir /etc/minio04 http://192.168.200.179:9001/data/minio01 http://192.168.200.179:9002/data/minio02 http://192.168.200.179:9003/data/minio03 http://192.168.200.179:9004/data/minio04 autostart=true startsecs=10 autorestart=true startretries=3 user=root priority=999 redirect_stderr=true stdout_logfile_maxbytes=20MB stdout_logfile_backups=20 stdout_logfile=/data/logs/stdout.log stopasgroup=false killasgroup=false
4个节点,每个节点1块硬盘
启动分布式 Minio 实例,4个节点,每个节点1块硬盘,需要在4个节点上都运行下面的命令:
挂载磁盘
1mount /dev/sdb1 /data配置所有节点时钟同步
1ntpdate ntp.aliyun.com创建 supervisor 启动文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17vim /etc/supervisord.d/minio.ini [program:minio] environment = MINIO_ROOT_USER=minioadmin,MINIO_ROOT_PASSWORD=minioadmin command=/usr/local/bin/minio server --address 0.0.0.0:9000 --console-address 0.0.0.0:9001 --config-dir /etc/minio http://192.168.200.178:9000/data http://192.168.200.179:9000/data http://192.168.200.180:9000/data http://192.168.200.181:9000/data autostart=true startsecs=10 autorestart=true startretries=3 user=root priority=999 redirect_stderr=true stdout_logfile_maxbytes=20MB stdout_logfile_backups=20 stdout_logfile=/data/logs/stdout.log stopasgroup=false killasgroup=false
扩展现有的分布式集群
例如我们是通过分区的方式启动 Minio 集群,命令如下:
Minio 支持通过命令,指定新的集群来扩展现有集群(纠删码模式),命令如下:
现在整个集群就扩展了1024块磁盘,总磁盘变成了2048个,新的对象上传请求会自动分配到最少使用的集群上,通过以上扩展策略,就可以按需要扩展集群。重新配置后重启集群,会立即在集群中生效,对现有集群无影响。如上命令中,可以把原来的集群看作是一个区,新增的集群看作另一个区,新对象按每个区域中的可用空间比例放置在区域中,在每个区域内,基于确定性哈希算法确定位置。
说明:添加的每个区域必须具有与原始区域相同的磁盘数量大小,以便维持相同的数据冗余。例如,第一个区有8块磁盘,可以将集群扩展为16个、32个或1024个磁盘的区域,只需要确保部署的 SLA 是原始区域的倍数即可。
基于 docker-compose部署
4个节点,每个节点一块硬盘
| |
基于 Nginx 实现负载均衡
| |
S3客户端使用
Minio Client(mc)
命令
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16ls # 列出文件或目录 mb # 创建一个桶 cat # 显示文件和对象内容 pipe # 将一个 STDIN 重定向到一个对象或文件或 STDOUT share # 生成用于共享的 URL cp # 拷贝文件或对象 mirror # 给桶做镜像 find # 查找文件 diff # 比较两个文件或桶的差异 rm # 删除文件或对象 events # 管理对象通知 watch # 监视文件或对象事件 policy # 管理访问策略 config # 管理 mc 配置文件 update # 检查软件更新 version # 查看版本信息配置 mc
上传下载文件
Bucket 管理
mc admin 使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16mc 提供了 admin 子命令来对 minio 部署执行管理任务 service # 管理 minio 服务 update # 更新 minio 服务 info # 显示 minio 服务器信息 user # 管理用户 group # 管理组 policy # 管理策略 config # 管理 minio 服务器配置 heal # 修复 minio 服务器上的磁盘、桶或对象 profile top # 查看 minio 的统计信息 trace # 显示 minio 的http 跟踪信息 console # 显示 minio 控制台日志 prometheus # 管理 prometheus 配置 kms用户管理
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18# 创建用户 mc admin user add minio-server test01 mc admin user add minio-server test02 123456789 # 查看用户 mc admin user list minio-server # 禁用用户 mc admin user disable minio-server test01 # 启用用户 mc admin user enable minio-server test01 # 查看用户信息 mc admin user info minio-server test01 # 删除用户 mc admin user remove minio-server test01策略管理