对象存储
我们最常用的文件存储系统, 实际上相当复杂。文件系统不仅需要展示目录树, 和每个文件夹中的文件, 还需要支持对文件中的一小段进行修改的操作。
显然, 这些功能对于互联网应用来说并不需要用到, 我们基本不会有修改某张图片的部分字节的需求。
因此专门针对互联网应用的存储场景, 发展出了对象存储。将传统文件存储的很多功能进行特化, 从而得到支持更多文件, 访问速度更快的对象存储服务。
什么是对象存储
我们介绍对象存储的时候, 不得不把 块存储, 文件存储, 对象存储 这三个概念介绍全。
最容易理解的说法是, 他们的用户不同。
- 块存储是由硬件厂商实现的, 把数据按照固定大小的块进行划分, 并提供访问。
- 文件存储的使用对象是自然人, 本来计算机中的所有数据都是 0/1, 不方便用户理解。而通过文件这个概念对数据进行组织, 可以方便大家使用。
- 对象存储进一步优化了文件存储对于文件的组织方式, 比如之前读取一个文件需要访问很多块, 记录某个文件被存储在哪些块中本身也比较复杂。
总之, 对象存储是进入互联网时代不得不了解的存储服务, 对它的了解应该越早越好。
MinIO
之前没想到有这样一个需要, 我们其实是用得到对象存储服务的.
直接从服务器上请求图像会很慢,
有一些开源的存储方案
- moosefs、glusterfs
- MinIO
- fastdfs
- 网易的Curve
我在服务器上成功部署了 MinIO, 实现了文件分享和缩略图的功能.
首先部署 MinIO 本身需要花费一些精力, 我本来是想要通过 PodMan 这个较为先进的文件管理工具进行部署的, 但是非常可惜.
我选择用的 Ubuntu18 系统不被 Podman 所支持, 所以只好选择了 docker 进行部署, 所幸还比较顺滑.
启动执行的命令为:1
2docker run -dt -p 9000:9000 -p 9090:9090 --name minio_v4 -v ~/minio_v4:/data -v ~/.minio:/root/.minio -e "MINIO_ROOT_USER=***" -e "MINIO_ROOT_PASSWORD=***" \
quay.io/minio/minio server /data --console-address ":9090"
其中
-p
表示将 HOST 于 docker container 的端口进行映射,:
前面是 HOST 的端口, 后面是容器的端口.-v
表示将本地的文件夹挂在到容器的某个位置. 注意~/.minio:/root/.minio
-e
表示添加一些环境变量, 其中MINIO_ROOT_USER
等表示的是 admin 平台的用户名和密码--console-address
这个是运行参数, 表示 minio 控制台的端口在 9090--certs-dir
这个运行参数用来指定证书所在的位置. 这里要注意两点- 注意把 HOST 的某个目录挂载到容器的
${HOME}/.minio/certs
位置, 因为这是--certs-dir
的默认值 - 注意 MinIO 对证书的命令是有要求的. 要把
private.key
public.crt
这两个文件放在/root/.minio
目录下. - 参考 MinIO 配置 https
但是这样运行之后会出现新的问题: 我的 minio-client 也放在服务器上, 我填的
Minio.endpoint
就是localhost
. 为了使用 ssl 同时要令Minio.secure = True
. 不过此时会出现报错, 原因是我们提供的 https 证书是和我们的域名绑定的, 和localhost
这个名字不匹配. 最简单的想法就是, 我可以通过直接把localhost
填写成域名来避免这个问题. 但是这样会导致上传的速度很慢, 你用的是公网带宽, 而 localhost 用内网带宽上传就快很多. 如何既能享受 https, 又能快速上传文件呢.答案如下
1
2
3
4
5
6
7
8
9
10from minio import Minio
import urllib3
httpClient = urllib3.PoolManager(cert_reqs="CERT_NONE")
minio_client = Minio(
endpoint=MinioConfig.MyBucket,
access_key=MinioConfig.AccessKey,
secret_key=MinioConfig.SecretKey,
secure=MinioConfig.Secure,
http_client=httpClient,
)可以看到, Minio 允许我们定制自己的 httpclient, 而我们可以在这个过程中指定它不要检查证书.
这个接近 hack 的方法让我心惊胆战, 回头仔细研究一下有什么更好的方法, 至少要知道 httpclient 的这个 hack 的原理是什么.
- 注意把 HOST 的某个目录挂载到容器的
当然, 还存在一个问题, 就是如果用户上传了很大的文件, 会直接让服务器卡顿. 因此我们可以在 nginx 中设置代理文件的最大体积.
docker搭建minio及永久有效链接配置
Entity too large
在上传文件的时候, 会遇到一个 ‘Entity Too Large’ 的错误, 也就是说不允许我们上传太大的图片到服务器上.
这个限度测试下来大概是 1M, 但是绝大多数应用都不可能对用户提出这种要求. 那么如何取消对于上传文件的大小限制呢.
要进行两个操作
- 对于 nginx 服务器的配置, 取消对于
max_body_size
的约束 - 对于 flask app 的配置, 对
app.config['MAX_CONTENT_LEN']
进行修改
1 | http { |