前面文章已经提到docker下对minio集群的搭建,小伙伴们用了都说好,但是有的小伙伴可能对Minio还不熟悉,等会咱们就一起学习一下。
上面文章Docker下minio集群的搭建,但是Minio集群已经搭建好了,怎样使用呢?
首先我们会想到用Nginx做负载均衡,还有一种Minio自家开源的产品sidekick,出入门的可能对Nginx不太了解(上篇文章总结的很详细哦),对sidekick更不知道(上篇文章能带你了解哦),下面咱么一起学只是,一起进步。
Minio是什么?MinIO 采用Golang语言开发实现,是在 Apache License v2.0 下发布的对象存储服务器。 是为了海量的数据存储、人工智能、大数据分析而设计,并且它完全兼容了 Amazon S3 云存储服务,有着完善的API。 Minio还非常适合存储非结构化数据,比如说照片,视频,日志文件,备份和容器/ 虚拟机(VM) 映像。 对单个对象的大小可以从几 KB 到最大 5TB。并且整个系统都在操作系统的用户态空间,客户端和服务器之间采用了HTTP/HTTPS的通信协议。
- Minio采用尽可能简单可靠的集群管理方案,减少风险因素和性能瓶颈,撇弃复杂的大规模集群调度管理,打造可靠的集群、灵活的扩展能力以及超高的性能。
- Minio支持跨数据中心将多个集群合成超大资源池,并没有直接采用大规模统一的分布式集群。这样方便管理集群。
Minio服务器通过其兼容AWS SNS / SQS的事件通知服务触发Lambda功能。支持的目标是消息队列,如Kafka,Webhooks以及Elasticsearch,Redis,Postgres和MySQL等数据库。
能和Docker Swarm、K8s编排系统良好的实现对接,实现灵活部署。
执行文件只有一个并且参数极少。本地部署只需要minio server /data,Docker下部署也是同样,部署极其简单方便。
MinIO使用纠删码、Checksum来防止硬件错误和静默数据污染。在最高冗余度配置下,即使丢失1/2的磁盘也能恢复数据。
对于大对象,可以通过SQL语句来加速大数据分析处理和人工智能。
避免元数据库成为整个系统的性能瓶颈,并将故障限制在单个集群当中,而不会影响到其它集群。
对高性能做过高度优化(尤其是算法指令对CPU做过特殊处理),在标准硬件条件下它能达到55GB/s的读、35GG/s的写速率。
Linux、Unix、Windows、MaxOS等主流操作。
javascript、java、Python、Golang、.Net等多种客户端SDK。
针对CPU进行汇编优化后的纠删码保护每一个对象。
支持多种成熟的服务端加密模式,且对性能的影响可以忽略不计。支持HashiCorp的密钥管理解决方案。
支持快速增量备份到NAS、公有云等。
可以作为多种公有云、NAS设置的网关,对外提供S3访问的服务。
支持与OpenID connect规范,支持临时密码,支持高度细化的、可配置的访问策略。
用户未知的情况下的静默错误/比特位衰减是磁盘的一个严重的问题。Minio使用高度优化的HighwayHash算法保证从不读取到错误数据。
一旦开启单写多读,Minio将禁止可能改变对象数据、元数据的所有API。
文件修复能够细到单个对象。
存储机制Minio使用纠删码erasure code和校验和checksum。 即便丢失一半数量(N/2)的硬盘,仍然可以恢复数据。
校验和
保护数据免受硬件故障和无声数据损坏。
纠删码
纠删码是一种恢复丢失和损坏数据的数学算法,目前,纠删码技术在分布式存储系统中的应用主要有三类,阵列纠删码(Array Code: RAID5等)、RS(Reed-Solomon)里德-所罗门类纠删码和LDPC(LowDensity Parity Check Code)低密度奇偶校验纠删码。
Erasure Code是一种编码技术,它可以将n份原始数据,增加m份数据,并能通过n+m份中的任意n份数据,还原为原始数据。即如果有任意小于等于m份的数据失效,仍然能通过剩下的数据还原出来。
Minio采用Reed-Solomon code将对象拆分成N/2数据和N/2 奇偶校验块。 这就意味着如果是12块盘,一个对象会被分成6个数据块、6个奇偶校验块,可以丢失任意6块盘(不管其是存放的数据块还是奇偶校验块),仍可以从剩下的盘中的数据进行恢复。
RS code编码数据恢复原理
RS编码以word为编码和解码单位,大的数据块拆分到字长为w(取值一般为8或者16位)的word,然后对word进行编解码。 数据块的编码原理与word编码原理相同,后文中以word为例说明,变量Di, Ci将代表一个word。
把输入数据视为向量D=(D1,D2,…, Dn), 编码后数据视为向量(D1, D2,…, Dn, C1, C2,.., Cm),RS编码可视为如下(图1)所示矩阵运算。
图1最左边是编码矩阵(或称为生成矩阵、分布矩阵,Distribution Matrix),编码矩阵需要满足任意n*n子矩阵可逆。为方便数据存储,编码矩阵上部是单位阵(n行n列),下部是m行n列矩阵。下部矩阵可以选择范德蒙德矩阵或柯西矩阵。
RS最多能容忍m个数据块被删除。 数据恢复的过程如下:
(1)假设D1、D4、C2丢失,从编码矩阵中删掉丢失的数据块/编码块对应的行。(图2、3)
(2)由于B' 是可逆的,记 B'的逆矩阵为 (B'^-1),则B' * (B'^-1) = I 单位矩阵。两边左乘B' 逆矩阵。 (图4、5)
(3)得到如下原始数据D的计算公式 。
(4)对D重新编码,可得到丢失的编码
技术架构数据组织结构
NAS系统把整个存储资源组织为目录树的形式。与此不同, 对象存储系统把存储资源组织为租户-桶-对象的形式。数据结构组织见下图:
去中心化架构
?Minio采用去中心化的无共享架构,对象数据被打散存放在不同节点的多块硬盘,对外提供统一命名空间访问,并通过负载均衡或者DNS轮询在各个服务器之间实现负载均衡
统一的命名空间
?Minio有两种集群部署方式,一种是常见的本地分布式集群部署,一种是联盟模式部署。本地分布式集群部署即在多个本地服务器节点部署Minio服务,并将其组成单套分布式存储集群,并提供统一命名空间和标注的S3访问接口。联盟部署则是将多个本地Minio集群在逻辑上组成了统一命名空间,实现近乎无线的扩展与海量的数据规模管理,这些集群都可以在本地或者分布在不同地域的数据中心。
分布式锁管理
?与分布式数据库类似,Minio也会存在面临数据一致性的问题:一个客户端在读取一个对象的同时,另一个客户端可能正在修改或者删除这个对象。为了避免出现不一致的情况。Minio专门设计并实现了dsync分布式锁管理器,来控制数据一致性。
统一域名访问
?Minio集群扩展加入了新的集群或者桶后,对象存储的客户端程序需要通过统一的域名/url来访问数据对象,这个过程涉及了etcd与CoreDns。
MinIO对象存储的某个客户端(比如mc),首先向某个MinIO服务发送创建桶的请求。MinIO服务把这个桶所在的MinIO集群的外部网址(一般为一个Nginx的IP地址,或者MinIO集群的每一台服务器的IP地址),写入到etcd集群中。
扩展方式
MinIO支持联盟部署模式,即将多个MinIO集群组成一个统一命名空间(一个ETCD集群,若干个CoreDNS服务)。其中ETCD集群相当于整个对象存储系统的配置数据库,很多重要的信息,比如桶IP地址等存储于其中。这种模式的MinIO的架构如下图:
同样,MinIO在扩展时也采用相同机制,而不是传统分布式存储的添加节点方式。MinIO主要通过添加新的集群来扩大整个系统,可用空间大幅增加且仍然保持统一命名空间。通过这种方式,MinIO对象存储系统几乎可以无限的扩展总体性能和容量。
存储机制
?Minio使用纠删码erasure code和checksum来保护数据免受硬件故障和无声数据损坏。即使丢失一半数量(N/2)的硬盘,仍然可以恢复数据。
?纠删码是一种恢复丢失和损坏数据的数学算法,目前纠删码技术在分布式存储系统中的应用分为三类,阵列纠删码(Array code:RAID5、RAID6等)、RS(Reed-solomon)里德-所罗门类纠删码和LDPC(LowDensity Parity Check Code)低密度奇偶检验纠删码。ErasureCode是一种编码技术,它可以将份原始数据,增加M份数据,并能通过N+M份中的任意N分数据,还原原始数据。即如果有任意小于等于M份的数据丢失,仍然能通过剩下的数据还原。
?Minio采用Reed-solomon code将对象拆分成N/2数据和N/2奇偶检验快,这就意味着如果是12块盘,一个对象将会被分成6个数据块、6个奇偶检验快,可以丢失任意6块盘(不管存放的数据快还是奇偶检验快),让然可以从剩下的盘中的数据恢复。
?在一个N节点的分布式Minio中,只要有N/2个节点在线,你的数据就是安全的。不过至少需要N/2+1个节点才能进行写操作。
?将一个文件上传至Minio后,对应磁盘上的信息如下:
其中xl.json为此对象的元数据文件。part.1为此对象的第一个数据分片。(分布式中每一个节点都会存在这两个文件分别是数据块和奇偶检验快)在读取数据时Minio会对编码快进行HighwayHash编码,然后进行校验,以确保每个编码的正确性。基于Erasure Code和Bit Rot Protection的HighwayHash这两个特性,所以Minio的数据可靠性很高。
lambda计算与持续备份
?Minio支持lambda计算通知机制,即桶中的对象支持事件通知机制。当前支持的事件类型有:对象上传、对象下载、对象删除、对象复制等。当前支持事件接受系统有:redis、NATS、AMQP、Kafka、mysql、elasticsearch等。
?对象通知机制增强了Minio的扩展性,可以让用户通过自行开发来实现某些Minio未实现的功能。比如基于元数据的检索、与用户业务相关的计算等。同时也可以通过这个机制进行快速有效的增量备份。
对象存储网关
?Minio除了可以作为存储系统服务外,还可以作为网关,后端可以与NAS系统、HDFS系统等分布式文件系统或者S3、OSS这样的第三方存储系统。有了Minio网关,就可以为这些后端系统添加S3兼容的API,便于管理和移植,因为S3API已经是对象存储界事实的标注。
用户通过统一的S3 API请求存储资源,通过S3 API Router将各个请求路由到对应的ObjectLayer,每个ObjectLayer对应实现了各个存储系统的对象操作的所有API。例如GCS(Google cloud storage)实现了ObjectLayer接口后,它对于后端存储的操作就是通过GCS的SDK实现。当终端通过S3 API获取存储桶列表,那么最终的实现会通过GCS的SDK访问GCS服务获取存储桶列表,然后包装成S3标准的结构返回给终端。
纠删码
在同一集群内,MinIO会自动生成若干纠删组,用于存放桶数据。一个纠删组中的一定数量的磁盘发生的故障(故障磁盘的数量小于等于校验盘的数量),通过纠删码算法可以恢复出正确的数据。MinIO集成了Reed-Solomon纠删码库,MinIO存储对象数据时,首先把它生成若干等长的片段(对于大对象,默认按5MB切片),然后每一个片段会纠删算法分成若干分片,包括数据分片与校验分片,每个分片放置在一个纠删组的某个节点上。对象的每一个数据分片、校验分片都被“防比特位衰减”算法所保护。
对于一个对象,MinIO是如何定位它所在的纠删组呢?
假定所有的纠删组都有一个序号(从0开始,直至纠删组个数减1)。MinIO会根据对象名(类似于文件系统的全路径名),使用crc32哈希算法计算出一个整数。然后使用这个整数除以纠删组的个数,得到一个余数。这个余数,可以作为纠删组的序号,这样就确定了这个对象所在的纠删组。MinIO采用CRC32哈希算法,与GlusterFs的Davies-Meyer哈希算法(性能、冲突概率与md4, md5相近)不一样的是, CRC32算法的哈希值分布较不均匀,但运算速度极快,高出md4数倍。相对于容量均衡,MinIO更看重数据的写入速度。
数据修复
比特位衰减(Bitrot)是指存在存储介质中的数据发生了缓慢的变化,如向存储介质写入一段比特流,一段时间后再读出来,二者并不一致。比特位衰减的原因大致有:磁记录磨损、磁盘幻象写(phantom writes)、磁盘指向错误(misdirectedreads/writes)、宇宙射线的辐射等。MinIO对象存储系统从设计之初即考虑到修复 静默错误, 从被修复的目标来说,按照大小可以分为以下三种类型的修复:某个对象、某个桶、整个集群。
在控制台上执行mc命令即开始进行数据修复。该命令一方面向minio发送数据修复的HTTP请求,另一方面不断地接收minio服务进程返回的修复进度信息,而后输出到控制台,直到修复工作完毕。
如前文所述,每个对象都被分成多个分片,然后存储于多台主机的磁盘上。数据修复可以分为正常、深度两种模式,正常模式下只是简单地检查分片状态信息,深度模式下会使用hash算法来校验分片的内容,找出比特位错误,同时也更耗费资源。
MinIO具体修复流程如下:
? mc命令作为MinIO对象存储的客户端软件、管理工具,它内部链接了minio软件(代码网址:https://github.com/minio/minio/ )的madmin软件模块,通过调用madmin中的修复函数,mc包装了mc命令的命令行参数,然后向minio服务进程发送HTTP消息。
?mc发送一个修复请求,在minio中被类healSequence所描述。 每一个healSequence可以启动、停止、查询状态。minio服务程序收到新的任务的时候,会检查是否跟原有的healSequence有重叠的任务,如果有重叠,则启动的修复任务失败。如果minio服务没有发现错误,则使用深度优先搜索的算法,按照磁盘元数据信息、桶、对象的顺序,不断地给后台修复线程推送任务。
?minio 后台修复线程修复对象的流程算法:对于对象的每一个block(默认大小为5M),从纠删组的各个主机读取各个分片,如果有错误的分片,就需要修复,有两种可能: 校验分片错误——minio使用各个数据分片重新计算缺失的校验片。 数据分片错误——使用纠删算法恢复数据(需要计算逆矩阵)。
性能测试MinIO已经为高性能做过高度优化,尤其是部分关键的算法已经使用SIMD指令对Intel(AVX2/AVX512)、Arm(NEON)的cpu做过特殊优化,主要包括:
1) 纠删码部分用到的伽罗瓦域的运算:加法、乘法、乘方等等;
2) 监测比特位衰减(bitrot)的哈希函数,如HighwayHash。
另外每一个MinIO集群都是无中心的,其中的每一个节点都是对等的,从而在性能上,不会存在单点瓶颈,也不会有单点故障。
如下的硬件配置之下:Intel Skylake CPU, NVMe磁盘,以及Mellanox CX5 dual 100-GbE网卡。下图是MinIO inc的测试结果:
Minio的优势上面说了这么多,总结一下优点吧
Docker下安装
docker pull minio/minio
docker run -p 9000:9000 --name minio -e "MINIO_ACCESS_KEY=admin" -e "MINIO_SECRET_KEY=admin123456" -v /home/data:/data -v /home/config:/root/.minio minio/minio server /data
登陆地址: http://ip:9000
分布式 Minio 可以让你将多块硬盘(甚至在不同的机器上)组成一个对象存储服务。由于硬盘分布在不同的节点上,分布式 Minio 避免了单点故障。
Minio 分布式模式可以搭建一个高可用的对象存储服务,你可以使用这些存储设备,而不用考虑其真实物理位置。
(1)数据保护
分布式 Minio 采用纠删码(erasure code)来防范多个节点宕机和位衰减(bit rot)。
分布式 Minio 至少需要 4 个节点,使用分布式 Minio 就自动引入了纠删码功能。
纠删码是一种恢复丢失和损坏数据的数学算法, Minio 采用 Reed-Solomon code 将对象拆分成 N/2 数据和 N/2 奇偶校验块。 这就意味着如果是 12 块盘,一个对象会被分成 6 个数据块、6 个奇偶校验块,你可以丢失任意 6 块盘(不管其是存放的数据块还是奇偶校验块),你仍可以从剩下的盘中的数据进行恢复。
纠删码的工作原理和 RAID 或者复制不同,像 RAID6 可以在损失两块盘的情况下不丢数据,而 Minio 纠删码可以在丢失一半的盘的情况下,仍可以保证数据安全。 而且 Minio 纠删码是作用在对象级别,可以一次恢复一个对象,而RAID 是作用在卷级别,数据恢复时间很长。 Minio 对每个对象单独编码,存储服务一经部署,通常情况下是不需要更换硬盘或者修复。Minio 纠删码的设计目标是为了性能和尽可能的使用硬件加速。
位衰减又被称为数据腐化 Data Rot、无声数据损坏 Silent Data Corruption ,是目前硬盘数据的一种严重数据丢失问题。硬盘上的数据可能会神不知鬼不觉就损坏了,也没有什么错误日志。正所谓明枪易躲,暗箭难防,这种背地里犯的错比硬盘直接故障还危险。 所以 Minio 纠删码采用了高速 HighwayHash 基于哈希的校验和来防范位衰减。
(2)高可用
单机 Minio 服务存在单点故障,相反,如果是一个 N 节点的分布式 Minio ,只要有 N/2 节点在线,你的数据就是安全的。不过你需要至少有 N/2+1 个节点来创建新的对象。
例如,一个 8 节点的 Minio 集群,每个节点一块盘,就算 4 个节点宕机,这个集群仍然是可读的,不过你需要 5 个节点才能写数据。
(3)限制
分布式 Minio 单租户存在最少 4 个盘最多 16 个盘的限制(受限于纠删码)。这种限制确保了 Minio 的简洁,同时仍拥有伸缩性。如果你需要搭建一个多租户环境,你可以轻松的使用编排工具(Kubernetes)来管理多个Minio实例。
注意,只要遵守分布式 Minio 的限制,你可以组合不同的节点和每个节点几块盘。比如,你可以使用 2 个节点,每个节点 4 块盘,也可以使用 4 个节点,每个节点两块盘,诸如此类。
(4)一致性
Minio 在分布式和单机模式下,所有读写操作都严格遵守 read-after-write 一致性模型。