分布式存储学习2-Minio部署
分布式存储学习2-Minio部署
前言
上一章大致说明了应用场景与软件的选型与介绍,下面来实际操作,部署下Minio
做为一个高可用的分布式对象存储,Minio支持包括单机,集群,Docker,Kubernates等多种部署方式。
单机模式适合早期的开发与评估,实际生产推荐集群模式部署
实战示例
Minio支持离线部署(二进制)、在线部署(Homebrew)、容器化部署(Docker/K8s)。部署中具体启动参数放在后面的注意要点一起集中说
单机模式
单机模式的部署方式比较简单,以Mac为例,其他平台也基本相同
下载可执行文件
Mac可通过
Homebrew
安装brew install minio/stable/minio
开发环境建议下载可执行文件
wget https://dl.min.io/server/minio/release/darwin-amd64/minio
启动服务
/data
参数可根据需要替换成实际希望Minio存储的目录,例如/test
,/dist1
等等
注意! 如果是个人开发环境建议加上./
当前目录,方便多次测试,重新搭建环境把现有的目录删除就可以了
chmod +x minio
./minio server ./data
离线部署可以根据 Release Download 按照实际环境下载。如果没有指定,Minio默认的用户密码为minioadmin/minioadmin
,部署后可以通过两种方式测试
- Minio Console
Minio Console是一个内嵌在Minio服务的Web管理客户端,通过默认用户密码即可登录,默认为随机端口。通过浏览器里可以方便直观的操作,比如创建存储Bucket
, 上传文件Upload
,查看Minio服务状态Status
等等
- Minio Clinet
可以通过任何S3的兼容工具,比如mc
Minio CommandLine Tool 或者 SDK,mc
的具体命令如下,更详细的可以参考 MinIO | MinIO Client Quickstart Guide
cli可能使用的不会特别多,因为有Console,还是比较方便的。可能在维护方面会使用cli操作
S3这个我也不是很熟悉,这块不展开
启动完成
会看到如下输出信息,默认启动Minio会输出警告日志并建议修改Console的端口与默认的Root用户的用户名与密码
# 连接地址
API: http://127.0.0.1:9000
RootUser: minioadmin
RootPass: minioadmin
# Console地址,默认启动Console监听为随机地址
Console: http://127.0.0.1:61422
RootUser: minioadmin
RootPass: minioadmin
# 命令行
Command-line: https://docs.min.io/docs/minio-client-quickstart-guide
$ mc alias set myminio http://127.0.0.1:9000 minioadmin minioadmin
# 文档
Documentation: https://docs.min.io
# 警告,具体参数下文详细说明
WARNING: Console endpoint is listening on a dynamic port (61422), please use --console-address ":PORT" to choose a static port.
WARNING: Detected default credentials 'minioadmin:minioadmin', we recommend that you change these values with 'MINIO_ROOT_USER' and 'MINIO_ROOT_PASSWORD' environment variables
所以我们将启动参数稍作修改
./minio server ./data --console-address=":9001"
登录Console
浏览器访问 http://127.0.0.1:9001, 可以看到Minio的基本概览,下图是本机的一些信息
功能测试
进入Buckets,点击右上角Create Bucket
,创建存储。可以看到版本控制,对象锁,配额。都是在分布式模式才可以开启
这里我们创建一个名为minio-test
的桶
Bucket为了方便理解的,可以假设是创建一个文件夹/目录
剩余的就是对Bucket的操作,上传,下载,创建目录path
, 删除等操作。总体来说还是比较方便的
SDK连接测试
具体的SDK文档请参考 MinIO | The MinIO Quickstart Guide 找到左侧的Minio SDKS
以Node示例
Webpack
# javascript
npm install --save minio
# typescript
npm install --save-dev @types/minio
代码示例
/**
* Minio 示例代码
* @author shadow
* @date 2021-12-21 15:57:00
*/
// 依赖模块
const Minio = require('minio')
const Path = require('path')
// 创建客户端连接
const minioClient = new Minio.Client({
endPoint: '127.0.0.1',
port: 9000,
useSSL: false,
accessKey: 'minioadmin',
secretKey: 'minioadmin'
})
// 上传文件
const objectname = 'README.md'
const file = Path.join(__dirname, objectname)
// 桶名称
const bucket = 'minio-test'
/**
* 判断bucket是否存在
* 不存在先创建然后上传
*/
minioClient.bucketExists(bucket, (err, exists) => {
if (err) {
return console.log(err)
}
if (!exists) {
// zh-cn的参数为region,官方没有具体的解释,猜测是标注服务区域,默认是 us-east-1
minioClient.makeBucket(bucket, 'zh-cn', err => {
if(err){
return console.log(err)
}
putObject()
})
} else {
putObject()
}
})
const putObject = () => {
// 这里对中文对象名进行测试,Minio-Console下载有乱码, 其他没有乱码情况
minioClient.fPutObject(bucket, '文件名.md', file, {}, (err, objInfo) => {
if (err) {
return console.log(err)
}
console.log('Success', objInfo.etag, objInfo.versionId)
})
}
集群模式
假设现在我们准备4台服务器,每台服务器4个磁盘并且分别挂载在data1...4
上,同时所有服务器都在内部网络的172.16.1.x
网段
准备工作
- 准备一台负载均衡服务器(比如Nginx)
- 所有服务节点网络双向互通
- 所有节点的配置尽量保持一致(操作系统,CPU,内存,磁盘)
- 节点尽可能使用TLS通信(内部网路会好一些,如果节点有外部网络,比如互联网访问权限。TLS可以保证安全性)
- 对所有服务器定义域名,然后写入服务器的
host
内
172.16.1.1 minio.example1.com
172.16.1.2 minio.example2.com
172.16.1.3 minio.example3.com
172.16.1.4 minio.example4.com
启动集群
在每台服务器上启动Minio
./minio http://minio.example{1..4}.com/data{1..4}
观测结果,minio检测到域名对应的服务器与磁盘
然后配置负载均衡,简单示例如下:
upstream minio {
server: 172.16.1.1:9000;
server: 172.16.1.2:9000;
server: 172.16.1.3:9000;
server: 172.16.1.4:9000;
}
upstream minio-console {
server: 172.16.1.1:9001;
server: 172.16.1.2:9001;
server: 172.16.1.3:9001;
server: 172.16.1.4:9001;
}
server {
listen 80;
location ~ ^/minio/ {
proxy_pass http://minio;
rewrite: ^/minio/(.*)$ /$1 break;
}
location ~ ^/minio-console/ {
proxy_pass http://minio-console;
rewrite: ^/minio-console/(.*)$ /$1 break;
}
}
是的,服务器保持网络通常就好,启动和单机基本一致
创建服务
刚刚是手动创建集群,现在我们将minio做成系统服务
chmod +x minio
sudo mv minio /usr/local/bin/
手动创建安装/etc/systemd/system/minio.service
服务文件,官方示例如下
[Unit]
Description=MinIO
Documentation=https://docs.min.io
Wants=network-online.target
After=network-online.target
AssertFileIsExecutable=/usr/local/bin/minio
[Service]
WorkingDirectory=/usr/local
# 执行用户,可以更改
User=minio-user
Group=minio-user
ProtectProc=invisible
EnvironmentFile=-/etc/default/minio
ExecStartPre=/bin/bash -c "if [ -z \"${MINIO_VOLUMES}\" ]; then echo \"Variable MINIO_VOLUMES not set in /etc/default/minio\"; exit 1; fi"
ExecStart=/usr/local/bin/minio server $MINIO_OPTS $MINIO_VOLUMES
# Let systemd restart this service always
Restart=always
# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=65536
# Specifies the maximum number of threads this process can create
TasksMax=infinity
# Disable timeout logic and wait until process is stopped
TimeoutStopSec=infinity
SendSIGKILL=no
[Install]
WantedBy=multi-user.target
# Built for ${project.name}-${project.version} (${project.name})
minio示例使用minio-user
的用户、组启动服务,一般为了安全也会给软件单独指定用户与组,命令如下
# 创建组,然后将用户加入组
groupadd -r minio-user
useradd -M -r -g minio-user miniouser
# data1...4 请根据实际路径填写,这里我用的测试路径就是1~4
chown minio-user:minio-user /data1 /data2 /data3 /data4
按照准备工作中写的配置好host,负载均衡,tls等,但是不要启动,接下来创建/etc/default/minio
的服务配置文件,同样,官方实例如下
# minio 数据卷
MINIO_VOLUMES="https://minio{1...4}.example.net/mnt/disk{1...4}/minio https://minio{5...12}.example.net/mnt/disk{1...8}/minio"
# minio 配置参数
MINIO_OPTS="--console-address :9001"
# 用户名密码
MINIO_ROOT_USER=minioadmin
MINIO_ROOT_PASSWORD=minio-secret-key-CHANGE-ME
# 有负载均衡设置负载均衡,没有的话可以设置一台服务器做为临时方案
# Set to the URL of the load balancer for the MinIO deployment
# This value *must* match across all MinIO servers. If you do
# not have a load balancer, set this value to to any *one* of the
# MinIO hosts in the deployment as a temporary measure.
MINIO_SERVER_URL="https://minio.example.net"
重要: 如果是扩容的话,需要停掉所有的minio,然后再启动,minio不支持滚动重启
sudo systemctl stop minio.service
启动所有minio
sudo systemctl start minio.service
sudo systemctl status minio.service
纠删码
纠删码的内容大部分是解读官方文档和其他资料进行的理解和汇总,难免有信息偏差和误解
再者,我对这块的了解仅限于知道,具体的细节就不做深入了
纠删码通过算法对数据进行恢复, 其实是通过CPU和网络的开销换存储空间
纠删码又称作擦除编码,是一种数据保护技术,其他的有Raid、副本。纠删码算是Raid的一种延伸,解决的Raid、副本存储空间过于浪费的问题,同时恢复的代价更小
目前主流使用Reed-Solomon(下文简称RS)类纠删码,主要有n
个数据快 + m
个校验块组成。数据块和校验块按照一定的规则设定、存放。
这样可以保证
- 在一定范围内数据块或者校验块损坏的情况下,整体数据可以根据剩余的数据块计算得出,数据不会丢失,存储是可用状态的
- 丢失的数据块/校验块是可以做恢复,保证高可用
- 数据块和校验块的比例可调整,比如
12+4
,6+3
Minio的纠删码允许最多支持一半的磁盘(drives)和校验块(N/2-1)的丢失,仍然可以支持读写操作,最少需要4个磁盘。
纠删集(Erasure Sets)
纠删集就是Minio支持纠删码的一组驱动器,Minio通过GCD(最大公约数)来划分所有的驱动器组。这样做是为了更均匀,不重复的分配数据块与校验块分配在各个纠删集上。
加入一个集群有5个服务器,各8个驱动器。通过GCD得出4 * 10
这样的配置,这样数据分配会不均匀,不能保证每台服务器有均衡的数据块与校验块,所以MInio会调整为5*8
重点:
- 纠删集部署Minio时就会开始计算
- 如果整体驱动器数量为奇数, Minio会抛出错误
- 每个纠删集的驱动器数量最小4,最大16
ERROR Invalid command line arguments: Incorrect number of endpoints provided
所以服务器数量尽量保证为偶数,保证每个服务器(节点)的数据块和校验块都是均匀的
注意要点
文档有两处,两份有时候可能要串着看,个人觉得老文档写的相对清晰一点。比如SDK,我在裸金属这块的文档中就没找到
MinIO High Performance Object Storage — MinIO Baremetal Documentation 新文档
MinIO | The MinIO Quickstart Guide — MinIo Legacy Docuemnt 历史文档
参数解释
按照我的个人习惯,一般执行前除了文档(特别是文档不是很友好的那种)。都会看看--help
看看具体命令和参数,下面让我们看看分别是有哪些信息
环境变量
示例为Mac/LInux,Windows可将EXPORT
替换为SET
,设置用户名与密码
EXPORT MINIO_ROOT_USER=minioadmin
EXPORT MINIO_ROOT_PASSWORD=minioadmin
minio --help
# 命令格式
USAGE:
minio [FLAGS] COMMAND [ARGS...]
# 启动命令,gateway模式或者server模式
COMMANDS:
server start object storage server
gateway start object storage gateway
# 参数
FLAGS:
# TLS证书目录,可以自定义,默认读取当前用户目录的.mino/certs
--certs-dir value, -S value path to certs directory (default: "/Users/shadow/.minio/certs")
# 静默启动,不打印启动信息
--quiet disable startup information
# 匿名模式,不打印敏感信息
--anonymous hide sensitive information from logging
# 日志打印json格式,这个非常适配filebeat之类的日志抽取工具,方便对日志进行分析
--json output server logs and startup information in json format
# 帮助和版本
--help, -h show help
--version, -v print the version
minio server --help
节选常用与较重要的一些信息,部分和minio --help
重复的不再贴出
需要注意的是目录不存在会自动创建,建议先按照磁盘和规划预先创建好目录,特别是一机多磁盘。预先做好挂载
# 命令格式
USAGE:
minio server [FLAGS] DIR1 [DIR2..]
minio server [FLAGS] DIR{1...64}
minio server [FLAGS] DIR{1...64} DIR{65...128}
# DIR的解释信息,Minio推荐每个服务有最少4个硬盘,所以通过DIR的参数指定,可以不断追加,或者根据...的规则自动新增
# 比如目录没有连续性,像/mnt/disk-north /mnt/disk-south,就可以携程
# minio server /mnt/dist-north /mnt/dist-south
# 如果连续可以使用...缩写目录,例如4个磁盘分别挂载在/mnt/disk1,2,3,4. 就可以这样写:
# minio server /mnt/disk{1...4}
#
DIR:
DIR points to a directory on a filesystem. When you want to combine
multiple drives into a single large system, pass one directory per
filesystem separated by space. You may also use a '...' convention
to abbreviate the directory arguments. Remote directories in a
distributed setup are encoded as HTTP(s) URIs.
# 参数
FLAGS:
# 服务监听端口,默认:9000
--address value bind to a specific ADDRESS:PORT, ADDRESS can be an IP or hostname (default: ":9000")
# Console的监听地址,如果不指定会随机
--console-address value bind to a specific ADDRESS:PORT for embedded Console UI, ADDRESS can be an IP or hostname
--listeners value bind N number of listeners per ADDRESS:PORT (default: 1)
EXAMPLES:
1. Start minio server on "/home/shared" directory.
$ minio server /home/shared
2. Start single node server with 64 local drives "/mnt/data1" to "/mnt/data64".
$ minio server /mnt/data{1...64}
3. Start distributed minio server on an 32 node setup with 32 drives each, run following command on all the nodes
$ export MINIO_ROOT_USER=minio
$ export MINIO_ROOT_PASSWORD=miniostorage
$ minio server http://node{1...32}.example.com/mnt/export{1...32}
4. Start distributed minio server in an expanded setup, run the following command on all the nodes
$ export MINIO_ROOT_USER=minio
$ export MINIO_ROOT_PASSWORD=miniostorage
$ minio server http://node{1...16}.example.com/mnt/export{1...32} \
http://node{17...64}.example.com/mnt/export{1...64}
其他
- Minio-Console 文件下载中文名乱码
该问题为Minio-Console的Bug,社区已有修复提交记录,后续版本应该会更新 Solve the problem of garbled file names when downloading Chinese files
- region参数是干什么的?
不清楚,官方文档中没有明细的说明,有可能只是做一个区分。因为Minio也没有做类似HDFS的机架感知机制,可能后续要看一下源码。此问题后续看情况更新
引用资料
MinIO | The MinIO Quickstart Guide
Expand a Distributed MinIO Deployment — MinIO Baremetal Documentation
下章预览
- JuiceFS环境搭建
- Minio纠删码详解
- Minio元数据处理机制解析
- 其他