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地址,端口,以及路径。
例如http://xxx.xxx.xxx:9000/data
就是说在http://xxx.xxx.xxx这个ip地址的9000端口,存储的文件夹是/data
如果我们需要在本地开4个“伪”分布式的server,可以使用
http://localhost:9000/data{1...4}
这里面data{1...4}实际上是data1 data 2 data3 data4的简写。
如果要多机,则需要指定多个ip地址,例如
http://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,读写均可。
基本的应用场景
- 有一个很大存储服务器,需要通过其他机器访问。可以在存储服务器上开一个单机的server,在其他机器上开启cache,然后使用api访问。
- 有很多机器,每个机器的存储容量不大。可以开分布式的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=http://ip:port
然后就可以实现读写log都在s3上了