MinIO服务搭建和使用
MinIO 是一个基于Apache License v2.0开源协议的对象存储服务,采用Go语言开发的软件。它兼容亚马逊S3云存储服务接口,非常适合于存储大容量非结构化的数据,例如图片、视频、日志文件、备份数据和容器/虚拟机镜像等,而一个对象文件可以是任意大小,从几kb到最大5T不等。MinIO是一个非常轻量的服务,可以很简单的和其他应用的结合,类似 NodeJS, Redis 或者 MySQL。
官网:https://docs.min.io/cn/minio-quickstart-guide.html
Docker搭建:
docker run -p 9000:9000 --name minio1 \
-e "MINIO_ACCESS_KEY=admin" \
-e "MINIO_SECRET_KEY=admin" \
-v /mnt/data:/data \
-v /mnt/config:/root/.minio \
docker.io/minio/minio:latest server /data
注意:前提需要创建好对应的本地映射文件目录,搭建好后,访问本级IP:9000端口,输入设置的密码可以访问其中的文件,该服务常常在项目中用来搭建一些文件共享平台。
简单实例
根据官网的第一个例子,可能会出现如下问题:minio.error.InvalidXMLError:raise InvalidXMLError('"Error" XML is not parsable.),这个原因是没有写端口。
from minio import Minio
from minio.error import (ResponseError, BucketAlreadyOwnedByYou,
BucketAlreadyExists)
# 使用endpoint、access key和secret key来初始化minioClient对象。
minioClient = Minio('10.2.1.111:9000',
access_key='admin1234',
secret_key='admin1234',
secure=False)
# 调用make_bucket来创建一个存储桶。
try:
minioClient.make_bucket("maylogs", location="us-east-1")
except BucketAlreadyOwnedByYou as err:
pass
except BucketAlreadyExists as err:
pass
except ResponseError as err:
raise
# Put an object 'pumaserver_debug.log' with contents from 'pumaserver_debug.log'.
try:
minioClient.fput_object('maylogs', 'pumaserver_debug.log', './requirements.txt')
except ResponseError as err:
print(err)
使用python操作Minio的上传下载
# -*- coding: utf-8 -*-
"""
@Time : 2020/8/4 2:59 下午
@Auth : wangli
"""
from minio import Minio
import os
def urljoin(*args) -> str:
"""
Joins given arguments into a url. Trailing but not leading slashes are
stripped for each argument.
"""
url = "/".join(map(lambda x: str(x).rstrip('/'), args))
return url
class MinioImp:
def __init__(self, host, acc_key, sec_key, cache_loc):
"""
:param host: Minio host:port
:param acc_key: user key
:param sec_key: secret key
:param cache_loc: localtion path
"""
# Initialize Minio instance
self._s3_client = Minio(host, access_key=acc_key, secret_key=sec_key, secure=False)
self.cache_location = cache_loc
def get_cachefile_path(self, bucket_name, object_name):
# Create the destination filepath
cachefile_path = self.cache_location + "/" + bucket_name + "/" + object_name
return cachefile_path
def get_partial(self, bucket_name, object_name, start, size):
# Gets data from offset to length of an object
return self._s3_client.get_partial_object(bucket_name, object_name, start, size)
def object_exists(self, bucket_name, object_name):
"""
Check whether the object actually exists
"""
try:
_ = self._s3_client.stat_object(bucket_name, object_name)
return True
except BaseException:
return False
def download(self, bucket_name, object_name):
"""
Download the object to the cache as a file.
If it already exists then check whether the object on the object store is newer than the file on the disk.
:return: string filename in the cache
"""
# get the path in the cache
dest_path = self.get_cachefile_path(bucket_name, object_name)
# First check whether the file exists
if os.path.exists(dest_path):
# these exceptions shouldn't really happen but I'm writing particularly defensive code!
try:
object_stats = self._s3_client.stat_object(bucket_name,
object_name)
# get object information and metadata of an object.
except BaseException:
raise "Error: " + dest_path + " not found."
# get the date of the corresponding file on the file system
try:
file_stats = os.stat(dest_path)
except BaseException:
raise IOError("Error: " + dest_path + " not found.")
# the object on the object store is newer than the one on the disk
if object_stats.last_modified > file_stats.st_mtime:
# Redownload the file
try:
self._s3_client.fget_object(bucket_name, object_name, dest_path)
except BaseException:
raise "Error: " + dest_path + " not found."
else:
# Does not exist so we have to download the file
# first create the destination directory, if it doesn't exist
dest_dir = os.path.dirname(dest_path)
if not os.path.isdir(dest_dir):
os.makedirs(dest_dir)
# now try downloading the file
try:
self._s3_client.fget_object(bucket_name, object_name, dest_path)
except BaseException:
raise "Error: " + dest_path + " not found."
return dest_path
def create_bucket(self, bucket_name):
"""
Create a bucket on S3 storage
"""
# full url for error reporting
full_url = urljoin(self.cache_location, bucket_name)
# check the bucket exists
if not self._s3_client.bucket_exists(bucket_name):
try:
self._s3_client.make_bucket(bucket_name)
except BaseException as e:
raise "Error: " + full_url + " cannot create bucket."
def delete_bucket(self, bucket_name):
self._s3_client.remove_bucket(bucket_name)
def delete(self, bucket_name, object_name):
"""Delete a single object"""
self._s3_client.remove_object(bucket_name, object_name)
def uploadload(self, bucket_name, object_name):
"""
Write a file in the cache to the s3 storage
"""
# full url for error reporting
full_url = urljoin(self.cache_location, bucket_name, object_name)
# get the path in the cache
s3_cache_filename = self.get_cachefile_path(bucket_name, object_name)
# check the file exists in the cache
if not (os.path.exists(s3_cache_filename)):
raise "Error: " + s3_cache_filename + " file not found in cache."
# create the bucket if necessary
self.create_bucket(bucket_name)
try:
self._s3_client.fput_object(bucket_name, object_name, s3_cache_filename)
except BaseException as e:
raise "Error: " + full_url + " cannot write S3 object: " + str(e)
if __name__ == '__main__':
minio = MinioImp('10.2.1.1:9000', 'admin4', 'admin', '.')
# 下载
# minio.download('maylogs', 'pumaserver_debug.log')
# 上传
# minio.uploadload('maylogs', 'test.py')

浙公网安备 33010602011771号