唐抉的个人博客

MinIO 配置及使用

字数统计: 2.5k阅读时长: 9 min
2024/07/01

前言

MinIO是一个对象存储系统,它适合用于存储大容量非结构化的数据。

对象存储对比传统文件存储方式的优点

  • 可扩展性和灵活性高:基于分布式架构设计,可以轻松地水平扩展存储容量,无需担心容量限制问题,适合数据量快速增长的场景
  • 高耐用性与容错性:通过数据复制或分布式冗余存储策略,提供高数据持久性和故障恢复能力
  • 简易管理:对象存储通过API接口访问,简化了数据的管理和访问过程,无需关心文件系统的层级结构
  • 支持元数据:每个对象都可以携带丰富的元数据信息,便于进行标签化管理和搜索

对象存储对比传统文件存储方式的缺点

  • 访问延迟较高:主要通过http协议读写,相比直接挂载的文件系统,对象存储的读写操作会有更高的延迟
  • 不支持文件系统语义:如文件锁定、目录级权限控制等传统文件系统特性,在对象存储中不直接提供
  • 不适合低延迟、高I/o操作:对于需要频繁修改和随机访问的应用场景,对象存储不是最佳选择,比如系统日志之类

适用场景:

  • 大数据存储与分析:面对PB级乃至EB级的数据存储需求,如历史日志存储、数据分析、机器学习训练数据等
  • 内容分发网络(CDN)与媒体存储:视频、图片等多媒体文件的存储与快速分发
  • 备份与归档:数据备份、灾难恢复和长期数据归档
  • Web应用与移动应用:特别是那些需要在全球范围内快速访问静态资源的应用
  • 云原生应用:微服务架构、容器化应用中,作为无状态服务的数据存储层

配置MinIO

本机可以通过地址+端口直接访问MinIO console管理页面

  • 登录管理页面,创建存储桶(create Bucket)

  • 进入桶内,点击Access Policy,将存储桶的设置为私有(Private)

  • 点击侧栏的Policies,点击Create Policy新建一个策略,例如这里的策略名叫testPolicy,具体的策略配置如下,只需要将testPolicy更换成对应的策略名即可:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    {
    "Version": "2012-10-17",
    "Statement": [
    {
    "Effect": "Allow",
    "Action": [
    "s3:*"
    ],
    "Resource": [
    "arn:aws:s3:::test"
    ]
    },
    {
    "Effect": "Allow",
    "Action": [
    "s3:*"
    ],
    "Resource": [
    "arn:aws:s3:::test/*"
    ]
    }
    ]
    }

  • 设置好管理策略后,设置ak(access_key)和sk(secret_key)。请记下这里的buckey_name,ak和sk,后续在config.yml里会用到这一部分信息:

1
2
3
4
5
minio:
buckey_name: 自定义的桶名称
endpoint: minio地址
access_key: 创建的ak
secret_key: 根据ak自动生成的sk
  • 在后端项目终端中输入pip install minio下载所需依赖

  • 在后端框架的services目录下创建fileUploader.py文件,完成Minio的基础配置:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    from config import config
    from minio import Minio

    __all__ = [
    'minioClient',
    ]

    minioClient=Minio(config['minio']['endpoint'],
    access_key=config['minio']['access_key'],
    secret_key=config['minio']['secret_key'],
    secure=False,
    cert_check=False
    )

  • 完成这个配置后,若需要用到该模块,只需要输入以下语句引用即可

    1
    from services.fileUploader import minioClient

MinIO用法

下面以几个常用语法为例,讲解MinIO语法的使用,除了下文列出来的函数,更多的MinIO语法请参照MinIO SDK文档:Minio SDKs - Python Client API文档 - 《Minio Cookbook 中文版》 - 书栈网 · BookStack

注意:MinIO使用文件名作为文件的唯一标识,上传同名文件时是直接覆盖文件而不是加后缀区分,因此在上传文件时,尽量使用uuid生成唯一的文件名。

put_object:将文件以二进制的形式上传到指定存储桶中-适用于请求次数较少的情况

1
2
3
4
5
6
7
8
  minioClient.put_object(bucket_name=config.config['minio']['buckey_name'], object_name=object_name, data=data,length=length)
# 参数详情如下:
# bucket_name:存储桶名称-(一般固定不变),string类型
# object_name:上传文件的名称,string类型(注:如果需要将文件上传到文件夹里,这里的文件名称可以填写 “文件夹名/文件名称”)
# data:文件的二进制数据,string类型。python中可以取request.files['file'].stream的值
# length:对象的总长度,int类型,如len(file.read())
# content_type:对象的content_type(选填,默认为"application/octet-stream"),string类型
# metadata:其他元数据(选填,默认为None),dict类型

fput_object:将本地文件上传到指定存储桶中-适用于请求次数较多、多并发的情况

1
2
3
4
5
6
7
  minioClient.fput_object(bucket_name=config.config['minio']['buckey_name'], object_name=object_name, file_path=file_path)
# 参数详情如下:
# bucket_name:存储桶名称-(一般固定不变),string类型
# object_name:上传文件的名称,string类型(注:如果需要将文件上传到文件夹里,这里的文件名称可以填写 “文件夹名/文件名称”)
# file_path:上传文件所在的路径,string类型
# content_type:对象的content_type(选填,默认为"application/octet-stream"),string类型
# metadata:其他元数据(选填,默认为None),dict类型

get_object:从指定存储桶中下载文件-适用于请求次数较少的情况

1
2
3
4
5
minioClient.get_object(bucket_name=config.config['minio']['buckey_name'], object_name=object_name)
# 参数详情如下:
# bucket_name:存储桶名称-(一般固定不变),string类型
# object_name:下载文件的名称,string类型。(注:如果需要从文件夹里下载文件,这里的文件名称可以填写 “文件夹名/文件名称”)
# request_headers: 额外的请求头信息(选填,默认为None),dict类型

fget_object:从指定存储桶中下载文件并保存到本地-适用于请求次数较多、多并发的情况

1
2
3
4
5
6
minioClient.fget_object(bucket_name=config.config['minio']['buckey_name'], object_name=object_name, file_path=file_path)
# 参数详情如下:
# bucket_name:存储桶名称-(一般固定不变),string类型
# object_name:下载文件的名称,string类型(注:如果需要从文件夹里下载文件,这里的文件名称可以填写 “文件夹名/文件名称”)
# file_path:下载文件保存到本地的路径,string类型
# request_headers: 额外的请求头信息(选填,默认为None),dict类型

list_objects:列出指定存储桶中所有文件

1
2
3
4
5
minioClient.list_objects(bucket_name=config['minio']['buckey_name'])
# 参数详情如下:
# bucket_name:存储桶名称-(一般固定不变),string类型
# prefix: 用来过滤的文件名前缀,默认为None,string类型
# recursive:是否递归查找,(选填,默认值为False),bool类型(True代表递归查找,False代表类似文件夹查找,以'/'分隔,不查子文件夹。)

remove_object:删除指定文件

1
2
3
4
minioClient.remove_object(bucket_name=config['minio']['buckey_name'],object_name=object_name)
# 参数详情如下:
# bucket_name:存储桶名称-(一般固定不变),string类型
# object_name:需要删除文件的名称,string类型(注:如果需要从文件夹里删除文件,这里的文件名称可以填写 “文件夹名/文件名称”)

remove_objects:删除存储桶中的多个文件

1
2
3
4
minioClient.remove_objects(bucket_name=config['minio']['buckey_name'],objects_iter)
# 参数详情如下:
# bucket_name:存储桶名称-(一般固定不变),string类型
# objects_iter:多个对象名称的列表数据,list, tuple or iterator类型

list_objects & remove_objects 组合:删除指定目录

1
2
3
4
5
6
7
8
# 导入DeleteObject类,用来表示在执行批量删除对象操作时单个对象删除的请求,包含了对象的key和版本id信息
from minio.deleteobjects import DeleteObject
delete_object_list = [DeleteObject(x.object_name) for x in minioClient.list_objects(bucket_name=config['minio']['buckey_name'], prefix=prefix, recursive=True)]
minioClientt.remove_objects(bucket_name=config['minio']['buckey_name'], delete_object_list)
# 参数详情如下:
# bucket_name:存储桶名称-(一般固定不变),string类型
# prefix: 用来过滤的文件名前缀,默认为None,string类型
# recursive:是否递归查找,(选填,默认值为False),bool类型(True代表递归查找,False代表类似文件夹查找,以'/'分隔,不查子文件夹。)

copy_object & remove_object 组合:移动文件

copy_object的作用是从存储桶A中复制指定文件到存储桶B里,通过先将文件复制到存储桶B,再把存储桶A中的文件删除,以达到在不同存储桶内迁移文件的目的

1
2
3
4
5
6
7
8
9
10
11
minioClient.copy_object(bucket_name=config['minio']['buckey_nameB'],object_name=object_name,object_source=object_source,copy_conditions=copy_conditions)
minioClient.remove_object(bucket_name=config['minio']['buckey_nameA'],object_name=object_name)
# copy_object中的参数详情如下:
# bucket_name:存储桶名称B-(一般固定不变),string类型
# object_name:文件粘贴到存储桶B后的名字,string类型(注:如果需要将文件粘贴到文件夹里,这里的文件名称可以填写 “文件夹名/文件名称”)
# object_source:需要复制的文件所在存储桶名称A+需要复制的文件名,string类型
# copy_conditions:复制文件操作时所应当满足的条件(选填,默认为None)

# remove_object中的参数详情如下:
# bucket_name:存储桶名称A-(一般固定不变),string类型
# object_name:需要删除的文件名,string类型(注:如果需要从文件夹里删除文件,这里的文件名称可以填写 “文件夹名/文件名称”)

文件上传示例

put_object:文件以二进制的形式上传

1
2
3
4
5
6
7
8
9
10
11
12
import os
import uuid
from io import BytesIO

file = request.files.get('file')
file_id=uuid.uuid1().hex
suffix=os.path.splitext(file.filename)[1].lower()
file_content=file.read()
file_size = len(file_content)
file_stream=BytesIO(file_content)
with file_stream as stream:
minioClient.put_object(bucket_name=config.config['minio']['buckey_name'], object_name=file_id+suffix, data=stream,length=file_size)

fput_object:上传本地文件

1
2
3
4
5
6
7
8
9
10
import os
from flask import request

# 文件保存在/files的路径下
path = os.path.join(os.path.dirname(os.getcwd()),'files')
file = request.files.get('file')
origin_name = file.filename
file_abolutepath = os.path.join(path, filename)
minipath = 'images/public/'+filename
minioClient.fput_object(bucket_name=config.config['minio']['buckey_name'], object_name=minipath, file_path=file_abolutepath)
CATALOG
  1. 1. 前言
  2. 2. 配置MinIO
  3. 3. MinIO用法
    1. 3.1. put_object:将文件以二进制的形式上传到指定存储桶中-适用于请求次数较少的情况
    2. 3.2. fput_object:将本地文件上传到指定存储桶中-适用于请求次数较多、多并发的情况
    3. 3.3. get_object:从指定存储桶中下载文件-适用于请求次数较少的情况
    4. 3.4. fget_object:从指定存储桶中下载文件并保存到本地-适用于请求次数较多、多并发的情况
    5. 3.5. list_objects:列出指定存储桶中所有文件
    6. 3.6. remove_object:删除指定文件
    7. 3.7. remove_objects:删除存储桶中的多个文件
    8. 3.8. list_objects & remove_objects 组合:删除指定目录
    9. 3.9. copy_object & remove_object 组合:移动文件
  4. 4. 文件上传示例