引言:我为什么要写这篇文档,因为MinIO在国内的资料比较少,但是在国外社区还是比较活跃的。从刚开始接触MinIO是因为集团要搭建文件服务系统供整个集团大大小小几百个项目组去使用,所以最终肯定奔着高可用目标去掉的。刚开始接触MinIO的时候,第一步肯定是进行一个环境的搭建,不管是测试环境,还是开发环境,甚至于生产环境,要求是一个比一个高,从单集群到多集群再到两地三中心、三地五中心。但是国内搭建的资料很少,且在CSDN上,保守来说至少50%的搭建是错误的(比如:用mkdir来充作Drive,用CI=true来忽略minio对于磁盘的检查等等),所以这里给大家看看我是如何搭建一个标准的MinIO最小集群。
看过官网的快速开始文档的应该知道,MinIO高可用集群至少满足四个节点才能开启纠删码模式,所以今天我的目标是用vm搭建一个四节点十六个Drive的最低配高可用MinIO集群。(这边我默认咱们都有MinIO基础知识了啊,比如纠删码、Set、node、drive等等)
首先,我会用虚拟机创建四个节点,每个节点20G的初始流量,在创建了四个初始节点后,会根据标准的磁盘挂载的方式去对每个节点挂载四块5G总共20G的磁盘(因为minio要求作为存储的磁盘一定是要干净的,所以这边选择磁盘挂载的方式进行,我司也是这么做的),这样子我我们可以得到四个节点总共80G的底层存储空间
| ip | 名称 |
|---|---|
| 192.168.192.163 | minio-1 |
| 192.168.192.164 | minio-2 |
| 192.168.192.165 | minio-3 |
| 192.168.192.166 | minio-4 |
| 192.168.192.167 | minio-nginx(负载) |



这边我内存稍微选大一点,这样操作的时候会更流畅,你们生产肯定是怎么高怎么来呗,我们测试环境单节点至少都是64G内存起步,生产更高(高得多)



等待初始系统安装

这边就安装好了,然后我们选择克隆的方式(我偷懒)克隆出另外三台机器,minio-2、minio-3、minio-4





重复整个克隆操作,克隆出minio-3、minio-4

这样我们四台机器就创建好了
这边启动四台机器,使用ip addr命令分别获取机器的ip地址,使用命令行工具进行连接,我这边使用的Xshell7个人版

具体的ip可以开头的表格
这一步其实看情况啦,公司的防火墙肯定不给关的,顶多开放固定端口,我这边直接用开放固定端口的形式了,虽然这样会麻烦一点,因为你不知道涉及哪些端口的话,后面容易出问题,minio主要是9000和9001端口,这是官方默认的端口。9000是minio-server的端口,9001是minio-cosole的端口,console空就是一个web可视化界面啦。这边把怎么开放端口的命令贴出来
## 查看防火墙状态
systemctl status firewalld

我这边是开启的哈
## 给9000添加永久开放端口
[root@localhost ~]# firewall-cmd --zone=public --add-port=9000/tcp --permanent
success
## 给9001添加永久开放端口
[root@localhost ~]# firewall-cmd --zone=public --add-port=9001/tcp --permanent
success
[root@localhost ~]#
## 重启防火墙
[root@localhost ~]# firewall-cmd --reload
success
## 检查是否添加成功
[root@localhost ~]# firewall-cmd --zone=public --list-port
9000/tcp 9001/tcp
以上操作在另外三台机器也运行

关闭四台虚拟机,依然会用minio-1为例子来进行挂载演示








这样就给这台minio-1添加一块磁盘,但是整个时候并没有挂载到目录上哦,我们先不急,先把剩下的三块盘装完,依旧是重复上面的动作


这样minio-1的四块磁盘就先准备好了
然后分别把minio-2、minio-3、minio-4也创建出四块预先分配的磁盘



现在我们的四台机器都已经创建好资源了,我们接下来要做的就是把这些创建的磁盘挂载到文件目录上去
打开四台虚拟机,使用xshell,我们开始要敲命令了
输入fdisk -l命令查看当前系统磁盘分区。

这块就是我们额外增加的四个磁盘,名称为sdb、sdc、sdd、sde
我们首先分别将这四块盘格式化为xfs格式
[root@localhost ~]# mkfs.xfs /dev/sdb -L DISK1
meta-data=/dev/sdb isize=512 agcount=4, agsize=327680 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0, sparse=0
data = bsize=4096 blocks=1310720, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
[root@localhost ~]# mkfs.xfs /dev/sdc -L DISK1
meta-data=/dev/sdc isize=512 agcount=4, agsize=327680 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0, sparse=0
data = bsize=4096 blocks=1310720, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
[root@localhost ~]# mkfs.xfs /dev/sdd -L DISK1
meta-data=/dev/sdd isize=512 agcount=4, agsize=327680 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0, sparse=0
data = bsize=4096 blocks=1310720, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
[root@localhost ~]# mkfs.xfs /dev/sde -L DISK1
meta-data=/dev/sde isize=512 agcount=4, agsize=327680 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=0, sparse=0
data = bsize=4096 blocks=1310720, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0 ftype=1
log =internal log bsize=4096 blocks=2560, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =none extsz=4096 blocks=0, rtextents=0
创建文件夹作为挂载源
mkdir /minio1
mkdir /minio2
mkdir /minio3
mkdir /minio4

使用mount进行挂载
[root@localhost /]# mount /dev/sdb /minio1
[root@localhost /]# mount /dev/sdc /minio2
[root@localhost /]# mount /dev/sdd /minio3
[root@localhost /]# mount /dev/sde /minio4
输入df -h命令检查挂载状态

mount挂载有风险,如果节点宕机重启或者因为其他因素重启,挂载就会消失,所以我们需要设置开机自动挂载
vim /etc/fstab

/dev/sdb /minio1 xfs defaults,noatime 0 2
/dev/sdc /minio2 xfs defaults,noatime 0 2
/dev/sdd /minio3 xfs defaults,noatime 0 2
/dev/sde /minio4 xfs defaults,noatime 0 2
输入reboot重启

重启之后依然是ok的
根据上面挂载的步骤,将其他三个节点的挂载一一配置好
题外话:这种挂载由很多种方式,有的是UUID,有的用LABEL=DISK1这种,只要你能挂的上,都没问题
paas:写到这里突然想到一个问题,我这刚安装的系统的时间肯定不对,到时候minio-console的上面显示的时间肯定不对,你们生产环境肯定有ntp同步时间啦,我这边就懒得做了,知道就行。
## 普通x86的机器
wget https://dl.min.io/server/minio/release/linux-amd64/archive/minio-20230210184839.0.0.x86_64.rpm -O minio.rpm
## 苹果m1 m2的
wget https://dl.min.io/server/minio/release/linux-arm64/archive/minio-20230210184839.0.0.aarch64.rpm -O minio.rpm
如果是离线操作,直接去官网下载二进制文件安装就好了

等待下载完成
下载完成
rpm -i minio.rpm
文件安装的位置默认是/usr/local/bin

我信了官网个鬼

这个老外毒奶粉玩家这条命令不行,还是我的好用(毒奶粉玩家我猜的)
这一步是为了让我们后面可以直接使用systemctl start minio这样的方式启动
如果你是跟我我上面安装的,会自动生成minio.servie文件的
vim /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=1048576
# 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})
官网版本:
[Unit]
Description=MinIO
Documentation=https://min.io/docs/minio/linux/index.html
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})
如果是二进制版本安装的兄弟,把自己去创建这个文件/etc/systemd/system/minio.service,然后把上面这段复制进去
上面这些参数信息,我们只需要关注几个
我好像还没有创建运行的用户,现在创建一个把,也不晚
[root@localhost bin]# groupadd -r minio-user
[root@localhost bin]# useradd -M -r -g minio-user minio-user
[root@localhost bin]# chown minio-user:minio-user /minio1 /minio2 /minio3 /minio4
同样,如果是根据我上面安装的,这个变量文件会自己生成,如果是二进制安装包安装的,需要自己去创建这个文件,然后补充信息(根据安装包的版本,也会有差异,我目前遇到过,就算不是二进制这个文件也不存在的情况,到时候兄弟们遇上了就直接把下面的配置copy进去就好了)
vim /etc/default/minio
我先把官网的贴出来,二进制安装的兄弟们,直接把这个内容复制到自己创建的文件就好了
# Set the hosts and volumes MinIO uses at startup
# The command uses MinIO expansion notation {x...y} to denote a
# sequential series.
#
# The following example covers four MinIO hosts
# with 4 drives each at the specified hostname and drive locations.
# The command includes the port that each MinIO server listens on
# (default 9000)
MINIO_VOLUMES="https://minio{1...4}.example.net:9000/mnt/disk{1...4}/minio"
# Set all MinIO server options
#
# The following explicitly sets the MinIO Console listen address to
# port 9001 on all network interfaces. The default behavior is dynamic
# port selection.
MINIO_OPTS="--console-address :9001"
# Set the root username. This user has unrestricted permissions to
# perform S3 and administrative API operations on any resource in the
# deployment.
#
# Defer to your organizations requirements for superadmin user name.
MINIO_ROOT_USER=minioadmin
# Set the root password
#
# Use a long, random, unique string that meets your organizations
# requirements for passwords.
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:9000"
接下来我们对这个文件进行一些变动
# Set the hosts and volumes MinIO uses at startup
# The command uses MinIO expansion notation {x...y} to denote a
# sequential series.
#
# The following example covers four MinIO hosts
# with 4 drives each at the specified hostname and drive locations.
# The command includes the port that each MinIO server listens on
# (default 9000)
## 这块是文件磁盘的位置 因为我们是集群节点是163-166 这边是一种池化写法
MINIO_VOLUMES="http://192.168.192.16{3...6}:9000/minio{1...4}"
# Set all MinIO server options
#
# The following explicitly sets the MinIO Console listen address to
# port 9001 on all network interfaces. The default behavior is dynamic
# port selection.
## minio-console的地址 就是web界面控制台
MINIO_OPTS="--console-address :9001"
# Set the root username. This user has unrestricted permissions to
# perform S3 and administrative API operations on any resource in the
# deployment.
#
# Defer to your organizations requirements for superadmin user name.
# console的登陆账号
MINIO_ROOT_USER=minioadmin
# Set the root password
#
# Use a long, random, unique string that meets your organizations
# requirements for passwords.
# console的登陆密码
MINIO_ROOT_PASSWORD=minioadmin
# 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="http://192.168.192.163:9000"
然后在其他三台机器依次安装,并修改/etc/default/minio环境变量文件
如果你们公司有自己的域名映射的话,你们就走域名咯,如果域名不连贯的话(建议还是连贯),可以分开配置
MINIO_VOLUMES="http://192.168.192.163:9000/minio{1...4} http://192.168.192.155:9000/minio{1...4}"
参考以上格式,用空格分隔,我只写了两个节点
systemctl start minio
四个节点依次运行




不吹不黑,一条龙通关
浏览器访问任意一节点的9001端口

密码:minioadmin/minioadmin

查看下监控信息,确保所有服务已启动

四个节点总共16快挂载的磁盘,

每块盘5GB,没错
这里选用nginx来作为负载均衡,会另外使用一台机器,提供统一的入口,然后将请求分发到这四个节点的9000端口
nginx版本:nginx-1.20.2.tar.gz
够用就行




嘿,哥们电脑配置还行,随便奢侈一把,我32G 三星DDR5内存

等待安装
一会我们会监听nginx的机器的9000端口 转发到四台服务上

安装成功了,我先配置一下Xshell

传输nginx安装包
解压
tar -zxvf nginx-1.20.2.tar.gz

安装一下
//一键安装上面四个依赖
yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel

进入nginx目录,使用nginx默认配置
./configure
完成!
编译安装
make
make install
查找安装路径
whereis nginx

修改ngix配置文件
vim /user/loal/nginx/conf/nginx.conf
worker_processes 1;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
sendfile on;
keepalive_timeout 65;
upstream minio_server {
server 192.168.192.163:9000;
server 192.168.192.164:9000;
server 192.168.192.165:9000;
server 192.168.192.166:9000;
}
upstream minio_console {
server 192.168.192.163:9001;
server 192.168.192.164:9001;
server 192.168.192.165:9001;
server 192.168.192.166:9001;
}
server {
listen 9000;
server_name localhost;
location / {
proxy_pass http://minio_server;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
server {
listen 9001;
server_name localhost;
location / {
proxy_pass http://minio_console;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
}
访问192.168.192.167:9001端口

哦对了,这个负载均衡的机器记得把9000和9001端口打开,参考上面



关于ng配置这块,因为涉及到文件上传下载等,还需要配置文件流以及大小的配置哦。
我在app/helpers/sessions_helper.rb中有一个帮助程序文件,其中包含一个方法my_preference,它返回当前登录用户的首选项。我想在集成测试中访问该方法。例如,这样我就可以在测试中使用getuser_path(my_preference)。在其他帖子中,我读到这可以通过在测试文件中包含requiresessions_helper来实现,但我仍然收到错误NameError:undefinedlocalvariableormethod'my_preference'.我做错了什么?require'test_helper'require'sessions_hel
我的rails3.1.6应用程序中有一个自定义访问器方法,它为一个属性分配一个值,即使该值不存在。my_attr属性是一个序列化的哈希,除非为空白,否则应与给定值合并指定了值,在这种情况下,它将当前值设置为空值。(添加了检查以确保值是它们应该的值,但为简洁起见被删除,因为它们不是我的问题的一部分。)我的setter定义为:defmy_attr=(new_val)cur_val=read_attribute(:my_attr)#storecurrentvalue#makesureweareworkingwithahash,andresetvalueifablankvalueisgiven
有没有办法在liquidtemplate中输出(用于调试/信息目的)可用对象和对象属性??也就是说,假设我正在使用jekyll站点生成工具,并且我在我的index.html模板中(据我所知,这是一个液体模板)。它可能看起来像这样{%forpostinsite.posts%}{{post.date|date_to_string}}»{{post.title}}{%endfor%}是否有任何我可以使用的模板标签会告诉我/输出名为post的变量在此模板(以及其他模板)中可用。此外,是否有任何模板标签可以告诉我post对象具有键date、title、url、摘录、永久链接等
我尝试在我的应用中只使用:symbols作为关键词。我尝试在:symbol=>logic或string=>UI/languagespecific之间做出严格的决定但我也得到了每个JSON的一些“值”(即选项等),因为JSON中没有:symbols,所以我调用的所有哈希都具有“with_indifferent_access”属性。但是:数组是否有相同的东西?像那样a=['std','elliptic',:cubic].with_indifferent_accessa.include?:std=>true?编辑:将rails添加到标签 最佳答案
我进行了一些谷歌搜索,似乎缺少用于jRuby的IDE。我读过TextMate和Sublime,但它们不提供调试或代码完成功能。有人可以提出建议吗(或者这项技术还处于起步阶段)? 最佳答案 有几个选项;我更喜欢JetBrains'IntelliJ(RubyMine).AptanahasanEclipseplugin.NetBeansusedtohaveofficialsupport,不确定currentstate是什么是。 关于ruby-哪些IDE可用于jRuby?,我们在StackOve
我将guard与rspec和cucumber一起使用。要连续运行选定的规范,我只需使用focus标记来确定我要处理的内容。但问题是,如果没有带有该标签的规范,我想运行所有规范。我该怎么做?注意::我知道所有RSpec选项。因此,请仅在阅读问题后回复。 最佳答案 我通过以下配置实现了您描述的行为:#torunonlyspecificspecs,add:focustothespec#describe"foo",:focusdo#OR#it"shouldfoo",:focusdoconfig.treat_symbols_as_metada
我从事Rails已有一段时间,并且刚刚开始深入研究Ruby元编程,Rails从中获得了强大的力量。我真的想不通这个,这让我发疯。Controller中的实例变量如何提供给Rails中的View(与View共享)?我知道它背后有一些元编程魔法,但我无法弄明白。在此先感谢您的所有帮助。 最佳答案 更新:原来接受的答案是错误的我现在将它留在下面以证明我错了。在获得足够多的反对票后,我决定研究这实际上是如何工作的。我最初的回答是在我对Rails还很陌生之后写的,并且是基于我使用过的其他MVC库(特别是:CodeIgniter)的工作方式的假
对于最近的一个项目,我有几个View是这样的代码:这在开发模式下工作得很好......我将它推出到生产模式并且它爆炸了,说count不是Array的有效方法。我将每个实例都改为使用Array#length,它似乎可以正常工作。1)这种行为差异的原因是什么?2)我应该注意开发模式和生产模式之间的任何其他令人兴奋的差异吗?道德:确保您的生产托管环境使用与本地开发环境相同的Ruby版本。:)谢谢汤姆 最佳答案 count方法仅在Ruby1.9及更高版本中可用。我建议您使用与服务器相同版本的Ruby以避免此类问题-1.9中发生了很多变化
开门见山|拉取镜像dockerpullelasticsearch:7.16.1|配置存放的目录#存放配置文件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/config#存放数据的文件夹mkdir-p/opt/docker/elasticsearch/node-1/data#存放运行日志的文件夹mkdir-p/opt/docker/elasticsearch/node-1/log#存放IK分词插件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/plugins若你使用了moba,直接右键新建即可如上图所示依次类推创建
谁能告诉我如何在ruby中获取可用磁盘驱动器的列表?我正在创建一个打开的文件对话并且需要知道!提前致谢,嗯。 最佳答案 Brian给出的文章正确地陈述了以下代码:require'win32ole'file_system=WIN32OLE.new("Scripting.FileSystemObject")drives=file_system.Drivesdrives.eachdo|drive|puts"Availablespace:#{drive.AvailableSpace}"puts"Driveletter:#{drive.D