首发于编程笔记
Minio:分布式数据存储搭建

Minio:分布式数据存储搭建

minio是目前githug上star最多的Object Storage框架,这里Object Storage我目前的理解就是数据存储。minio可以用来搭建分布式存储服务,可以很好的和机器学习相结合。

我使用docker来部署minio服务,有关docker的使用可以参考:

单机部署

docker run -p 9000:9000 \
  -e "MINIO_ROOT_USER=AKIAIOSFODNN7EXAMPLE" \
  -e "MINIO_ROOT_PASSWORD=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY" \
  minio/minio server /data

minio通过MINIO_ROOT_USER和MINIO_ROOT_PASSWORD这两个环境变量来设置用户名和密码,默认的端口是9000,所以需要把容器的端口映射一下。

这里使用了minio/minio官方镜像,在镜像中使用server命令。

运行上述命令后可以在本机9000端口查看网页端。

server命令的基础使用方法是指定数据存储的路径,这里是/data。不过要注意这是在容器中的路径,所以使用这个命令运行的话,一旦容器退出,数据会丢失。

以下是我修改后的运行命令

docker run \
        --network host \
	--user $(id -u):$(id -g) \
	--name minio_local \
	--env MINIO_ROOT_USER=root \
	--env MINIO_ROOT_PASSWORD=rootpwd \
	-v /home/user/minio-data:/data \
	minio/minio \
	server /data

这里主要有几点区别,首先使用--network host命令直接使用宿主机网络,这样无需端口映射,并且共享ip。第二行解决权限问题,这个问题在docker配置文章里有涉及,如果不修改,则所有文件在宿主机上为root权限。另外使用-v命令将宿主机文件夹挂载到容器,这样即使容器退出,重启即可恢复。

改变端口

server --address :port

这样会监听所有本机的ip包括localhost和公开的ip。

如果使用

server --address ip:port

这里ip可以为本机的任意ip,比如localhost,但是只会监听这个ip(所以外网无法访问)

两机部署

官方文档让人看得比较迷惑,很难看出来多机部署具体是怎么操作的。。。下面这个看起来好一点。

这里面官方文档给出的是

export MINIO_ROOT_USER=<ACCESS_KEY>
export MINIO_ROOT_PASSWORD=<SECRET_KEY>
minio server http://host{1...n}/export{1...m}

所以这个host{1...n}和export{1...m}是什么意思呢。。。

实际上每个server有三个主要的信息:ip地址,端口,以及路径。

例如xxx.xxx.xxx:9000/data

就是说在xxx.xxx.xxx这个ip地址的9000端口,存储的文件夹是/data

如果我们需要在本地开4个“伪”分布式的server,可以使用

http://localhost:9000/data{1...4}

这里面data{1...4}实际上是data1 data 2 data3 data4的简写。

如果要多机,则需要指定多个ip地址,例如

xxx.xxx.xx{1...4}:9000/data{1...4}

这就说明我们有四个ip(对应4台机器)分别为xxx.xxx.xx1,xxx.xxx.xx2。。。在每一个机器上都有4个server,存储在data1 - data4中。

由于minio是完全的分布式系统,所以我们只需要用同样的命令在所有机器上运行即可,这样每个机器都知道其他机器对应的ip地址,端口以及路径。

目前我使用如下命令,在两个机器运行即可

docker run \
        --network host \
        --user $(id -u):$(id -g) \
        --name minio_server \
        --env MINIO_ROOT_USER=root \
        --env MINIO_ROOT_PASSWORD=rootpwd \
        -v /data/user/minio-data/data1:/data1 \
        -v /data/user/minio-data/data2:/data2 \
        minio/minio \
        server http://210.28.135.{1...2}:9000/data{1...2}

这里需要注意的是minio默认使用数据校验,所以需要总的server数量是4的倍数,这也是为什么我只有两个服务器但是开了4个server的原因。不过由于在有校验的情况下数据存储量会减半,这样每个server仍然只存储一份数据的量。

理论上,每个机器有多个盘的话,可以把服务放在不同的物理硬盘上,这样即使有接近一半的硬盘或者服务器下线,依然可以使用。

结合网页客户端,可以实现网盘的基本功能。


多机部署需要分别设定多个ip:端口/路径,可以参考

例子如下

minio server --address :9001 http://localhost:9001/tmp/1 http://localhost:9002/tmp/2 http://localhost:9003/tmp/3 http://localhost:9004/tmp/4

启用本地cache

因为是网络存储,所以直接访问的速度会比直接访问硬盘慢很多很多。。。为了加快速度,尤其是机器学习的应用,必须开cache,这样就可以把访问过的数据存储到本地。具体命令如下

docker run \
	--network host \
	--user $(id -u):$(id -g) \
	--name minio_local \
	--env MINIO_CACHE="on" \
	--env MINIO_CACHE_DRIVES="/data" \
	--env MINIO_CACHE_EXCLUDE="" \
	--env MINIO_CACHE_QUOTA=80 \
	--env MINIO_CACHE_AFTER=1 \
	--env MINIO_CACHE_WATERMARK_LOW=70 \
	--env MINIO_CACHE_WATERMARK_HIGH=90 \
	--env MINIO_ROOT_USER=root \
	--env MINIO_ROOT_PASSWORD=rootpwd \
	-v /home/user/minio-cache:/data \
	minio/minio\
	gateway s3 http://xxx.xxx.xxx.xxx:port/

这里面docker相关的部分就不细说了,这里面本地cache文件夹是/home/user/minio-cache

其他环境变量的意义和配置方法见官方文档,

但是非常坑爹的是文档里面给出的命令是

export MINIO_ROOT_USER=aws_s3_access_key
export MINIO_ROOT_PASSWORD=aws_s3_secret_key
minio gateway s3

这里面s3默认是aws的s3服务,并没有给出自己搭建的服务怎么弄。

实际上我们自己搭建的默认就是s3服务,所以只用在后面加上ip配置即可。

minio gateway s3 http://ip:port

开启gateway以后,会在本地启动一个minio网页端,可以使用网页端下载一个文件,如果我们配置的MINIO_CACHE_AFTER=1的话,在访问两次以后就会存储在本地。这个计数机制和cache文件可以在我们配置的本地cache文件夹里面清楚的看到。

Linux系统下挂载文件系统

由于minio是符合AWS S3协议的,所以可以使用S3的挂载工具s3fs

默认的配置文件在${HOME}/.passwd-s3fs,自己新建一个就好。

配置文件其实只要一行内容

ACCESS_KEY_ID:SECRET_ACCESS_KEY

注意这个文件必须要修改权限

chmod 600 ${HOME}/.passwd-s3fs

不然会报错

由于我们是搭建的第三方S3服务,所以需要使用以下命令,指定ip:port,最后那个选项是必须的。

s3fs bucketname /mount/path -o passwd_file=${HOME}/.passwd-s3fs -o url=http://ip:port/ -o use_path_request_style

其他比较有用的选项

s3fs bucketname /mount/path \
-o passwd_file=${HOME}/.passwd-s3fs \
-o url=http://ip:port/ \
-o use_path_request_style \
-o use_wtf8 \ # for windows file name encoding
-o use_cache=/cache/path \ # 设定cache路径
-o check_cache_dir_exist \ # 检查cache路径是否存在,避免写错
-o umask=0007 \ # 解决文件读写的权限问题
-o uid=$(id -u) \ # 解决文件读写的权限问题
-o gid=$(id -g) # 解决文件读写的权限问题

取消挂载

umount /mount/path

注意这个命令是不需要在前面加s3fs的,很多人都踩了这个坑

在mac或者windows挂载可以参考

其中mac也可以使用s3fs,windows可以使用rclone

windows有一个简易的rclone图形界面

有关rclone的cache设置

总之建议直接用

--vfs-cache-mode full

并设置一个cache文件夹

--cache-dir string

使用Raidrive挂载minio

Raidrive目前增加了挂载minio服务的功能,但是免费版是只读的,读写功能需要付费。值得一提的是raidrive还提供了很多其他的挂载功能,比如sftp,读写均可。

基本的应用场景

  1. 有一个很大存储服务器,需要通过其他机器访问。可以在存储服务器上开一个单机的server,在其他机器上开启cache,然后使用api访问。
  2. 有很多机器,每个机器的存储容量不大。可以开分布式的server,每个机器都开server和cache,这样可以大大增加存储空间。同时还可以获得minio提供的数据校验和恢复能力:在一个集群中,只要有1/2以上的机器是正常运行的,就可以保证服务正常运行,数据不丢失。

2021.10.26更新:python API的一个坑

由于默认的Minio()的参数是secure=True,而在搭建服务器时默认参数是使用http,所以按照官网的api示例来连接的话会连不上。。。

Max retries exceeded with url: /

解决方法就是加上secure=False

client = Minio("xxxx:xxxx", 
    access_key="xxx", 
    secret_key="xxx",
    secure=False)

另外如果服务器和客户端的时间差距大于15分钟,会报错

The difference between the request time and the server's time is too large

这个把时间调整一下就行。

2021.10.28更新:版本控制

Minio提供了版本控制功能,可以备份我们上传文件的每一个版本,然后我们可以选择下载对应版本的文件。但是这个功能只能在硬盘数量为4的倍数的时候开启,这是一个坑,如果只用了一个硬盘则会报错(这个功能和数据校验以及文件锁是同时提供的)。

另外现在minio除了命令行以外还提供了一个浏览器界面,不同于原来的只能上传下载文件,目前版本控制以及权限等都可以在这个界面设置。可以说是很方便了。这个官方文档也已经更新,启动server的时候加一个console地址的参数即可。

--console-address ":9001"

测试速度

Minio官方提供了一个自动的测速工具,可以一键测试上传下载等性能。

上传文件夹

由于目前console没有这个功能,所以需要用命令行工具

.\mc.exe cp --recursive .\source\ alias/bucket/

注意这里复制的时候会带上文件夹名字,即会复制到alias/bucket/source下面,不需要重复一遍文件夹名。

使用tensorboard

export AWS_ACCESS_KEY_ID=<access key id>
export AWS_SECRET_ACCESS_KEY=<secret access key>
export AWS_REGION=us-west-2
export S3_REGION=us-west-2
export S3_ENDPOINT=s3.us-west-2.amazonaws.com
export S3_USE_HTTPS=1
export S3_VERIFY_SSL=0

tensorboard --logdir=s3://<path>

注意上面的方法存在一个问题, 由于tensorboard内部使用的是默认的s3 endpoint, 是AWS, 所以minio搭建的s3会有问题, 而tensorflow基于的boto3是无法使用环境变量更改endpoint_url的, 十分蛋疼....

所以需要安装这个版本的boto3

然后在环境变量里面设置AWS_ENDPOINT_URL=ip:port

然后就可以实现读写log都在s3上了

编辑于 2022-03-25 21:26