分布式存储学习1-JuiceFS与Minio
分布式存储学习日志 介绍JuiceFs + Minio
前言
最近做的项目需要大量的处理图片,视频,文件之类的资源,同时网络也比较复杂,分为好几个网络区块。
本来的处理方式是将大容量磁盘的服务器做磁盘映射,然后进行存储,这样其实没有问题,但是服务器的磁盘没有办法无限的进行扩容,有一个物理上限
并且所有的资源都在一台服务器也会有各种问题:
- 数据安全问题,比如磁盘坏道,服务器硬件损坏。
- 并发问题,这块主要看磁盘的IO读写速度。
扩展难,逻辑盘虽然可以动态扩容。但是一台服务器可以安装的磁盘有上限
4块500G的磁盘组的2T的raid,一年已经用掉一半了
所以考虑是不是使用分布式的存储来解决上面碰到的几个问题,选型主要考虑的是下面几点:
- 无侵入性,对于资源直接写入磁盘的方式支持比较友好,能支持磁盘挂载
- 容器化友好,方便与K8S或者Docker整合。
- 搭建简单部署便捷,这个很重要,因为我比较笨
- 支持ARM架构,这块是必须的,别问为什么...😢
做为一个分布式存储的小白,这块也不是很了解,于是就百度 + Google + Github混合搜索模式
除了大名鼎鼎的Hadoop,还了解到例如GFS,FastDFS,Ceph等等存储软件。顺便也学习了一下分布式存储的相关知识
相关知识
分布式存储的特性是数据规则分散,冗余的。用磁盘空间换取安全与高可用。分布式存储一般有以下几个组件/概念
- CAP
- 元数据管理(MetaServer/Storage)
- 数据存储节点(DataNode)
- 客户端(Client)
CAP
CAP就不做赘述了,具体可见这篇文章 CAP定义的含义-阮一峰 简单的一句话就是软件保证数据的实时一致性还是最终一致性
元数据管理
举个例子
有一个1MB的文件需要写入,假设分布式存储按照512Kb进行拆分2个冗余,分成两个切片(chunk),然后冗余2份加上原本的一份。既1 * 2 * 3 = 6,就是有6个切片(chunk)
这6个切片分别存储在不同的服务器/存储上,那怎么知道取那一份呢?如果其中一个节点损坏怎么获取正确的数据块呢?
元数据管理一般会存储文件的大小
,备份数量
,系统节点状态
,权重等等信息
个人理解的是元数据服务MetaServer做为中央管理节点,告知客户端(Client)应该从哪里去,而元数据存储MetaStorage将从哪里取的责任交给了客户端。大概下面这个意思吧
数据存储节点
存储节点存放数据,不同的软件实现方式不同,有的存储完整的文件,有的存储block,以Minio为例
Minio对文件名进行hash处理,通过集群内所有节点取余,得到具体的存放位置,然后将数据进行拆分与冗余处理,分布到各存储节点,在分布式场景中,存储的节点可以能是跨中心的,比如我们在购买云Ecs一般会选择在哪个大区(华东,华南,华北)。存取数据都通过网络传输,服务器物理具体的损耗也应该考虑在其中。
比如HDFS的机架感知,为了提高容错,尽可能的把数据副本分散在不同机架,同时通信尽可能保证在一个机架内。这里不做展开
下图是Minio官网的一张架构设计图,可以看到不同的节点通过网络连接,基于Restful规范通信
在硬件和内核方面,Minio是一个由软件定义的分布式存储服务器,可以运行在标准的硬件与操作系统上。下面是官方给出支持的内核列表
linux
Minio 推荐 RHEL8+ or Ubuntu 18.04+. 也支持以下架构的操作系统
- AMD64
- ARM64
- PowerPC 64 LE
- S390X
macOS & Microsoft Windows
Minio均推荐使用没有停止维护的官方版本,比如macOS 10.14+, Win10, Window Server 2016+
需要注意的是官方特别标注了windows平台的分布式模式为experimental 实验版本
客户端
一般分布式存储都有搭配有客户端,不同的架构对于客户端的实现也有不同,大部分对于主流语言有较好的支持,支持开箱即用。
采用中心化的架构方式,客户端基于TCP/HTTP的一层封装,不会有太多的额外功能。
反之,客户端端不仅需要封装网络操作,提供便捷的api,还需要嵌入例如负载均衡等机制。一般客户端分为CLi与SDK的形式
以Minio举例,MinioSDK支持的语言共有6中,分别是6个sdk,根据官方文档配置即可使用
MinIO | MinIO Client Quickstart Guide
MinIO | Java Client Quickstart Guide
Juicefs与Minio简介
Minio去中心化没有元数据库是很好的一种选择,但是它没有办法直接挂载的硬盘上,因为很多时候我们的代码对文件的操作是基于操作系统的
比如存在C盘(window), /usr/home/attachment(linux)之类的目录下,在已经运行的项目想要使用分布式存储,需要对原有代码进行适配改造,加入客户端。
如果维护过老项目的肯定知道,这很多东西不敢改啊,改一个地方出来10个BUG。甚至有的购买的软件产品,连源代码都没有。
这时候就需要增加一个虚拟文件系统来支持,个人目前比较看好用Golang开发的Juicefs。主要有两点
- 安装简单,配置方便
- 支持挂载在已有目录上,且不对原有数据造成影响
- 可扩展性强,基本主流的分布式对象存储都支持(HDFS,AWS S3,阿里云存储等等)
缺点也有:
- Juicefs需要一个元数据库存储元信息,支持Redis,Mysql,Sqllite
- 文档略少,用户基数不多,可能要排坑(可能...)
- 与Minio的去中心略有冲突,两套元数据管理机制会导致Minio写入的Juicefs无法获取,反向同理
总体来说,以我目前的用量,还是很不错的一个选择。
相关资料
JuiceFS is a distributed POSIX file system built on top of Redis and S3
Minio Multi-Cloud Object Storage
下章预览
- 如何部署Minio(单机/集群模式)
- Minio的一些特性,纠删码等
- 其他...