17

使用minio搭建高性能对象存储-第一部分:原型 | Tony Bai

 4 years ago
source link: https://tonybai.com/2020/03/16/build-high-performance-object-storage-with-minio-part1-prototype/?
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

使用minio搭建高性能对象存储-第一部分:原型

近期参与了一个项目,该项目有存储大量图片、短视频、音频等非结构化数据的需求。于是我优先在Go社区寻找能满足这类需求的开源项目,minio就这样进入了我的视野。

img{512x368}
图:minio logo

其实三年前我就知道了minio,并还下载玩(研)耍(究)了一番,但那时minio的成熟程度与今天相比还是相差较远的(当时需求简单,于是选择了较为熟悉的weedfs)。而如今的minio在github上收获了广泛的关注,小星星也是蛮多的(20k+ star)。它不仅被Go社区使用,在其他语言社区也有着广泛应用。我可以不负责任的说:在对象存储领域,minio大有kafka(java技术栈)在消息队列领域舍我其谁的气概:)。

2019年gopherchina大会上,探探工程师分享了“基于MINIO的对象存储方案在探探的实践”。虽然探探目前是否在生产中使用minio暂不得而知,但这又一次证明了minio在对象存储领域的强大影响力。

img{512x368}
图:探探工程师在gopherchina2019大会上分享minio实践

minio出品自一个有着多年网络文件系统开发经验的团队,其初始创始团队都来自于原Glusterfs团队,该团队二次创业的产品minio的设计广泛吸取了glusterfs的经验和教训:

  • 部署简单:一个single二进制文件即是一切,还可支持各种平台。(托了go语言的福)

  • minio支持海量存储,可按zone扩展(原zone不受任何影响),支持单个对象最大5TB;

  • 兼容Amazon S3接口,充分考虑开发人员的需求和体验;

  • 低冗余且磁盘损坏高容忍,标准且最高的数据冗余系数为2(即存储一个1M的数据对象,实际占用磁盘空间为2M)。但在任意n/2块disk损坏的情况下依然可以读出数据(n为一个纠删码集合(Erasure Coding Set)中的disk数量)。并且这种损坏恢复是基于单个对象的,而不是基于整个存储卷的。

  • 读写性能优异

img{512x368}
图:来自minio技术白皮书中的benchmark数据

鉴于上述minio的“优点”,我打算在这个项目中基于minio实现非结构化数据的对象存储方案。本篇文章将介绍方案的原型设计与初始minio验证环境搭建。

一. 原型方案

基于minio的非结构化数据对象存储方案都大同小异,下面的图示就是根据我们的需求简单设计的原型方案:

img{512x368}
图:原型方案
  • 我们基于minio提供的distributed mode,将位于多个host上的多块磁盘组成一个逻辑存储池,通过运行于不同host上的minio server实现一个高可用的对象存储方案;

  • 数据通过一个独立的上传服务(基于minio提供的sdk与minio集群通信)写入minio;

  • 通过minio的mc工具创建bucket,并将bucket的policy设置为”download”,以允许外部用户直接与minio通信,获取对象数据。中间不再设置除lb之外的中间层;

  • 通过job或定时任务利用mc工具统一对minio中的数据进行维护,比如定期删除7天前的数据(如果数据默认过期时间设定为7天)。

二. minio server启动模式

minio支持多种server启动模式:

img{512x368}
图:minio server启动模式

minio server的standalone模式,即要管理的磁盘都在host本地。该启动模式一般仅用于实验环境、测试环境的验证和学习使用。在standalone模式下,还可以分为non-erasure code modeerasure code mode

所谓non-erasure code mode,即minio server启动时仅传入一个本地磁盘目录参数:比如:

$minio server data

Endpoint:  http://10.10.126.88:9000  http://127.0.0.1:9000
AccessKey: minioadmin
SecretKey: minioadmin

Browser Access:
   http://10.10.126.88:9000  http://127.0.0.1:9000           

Command-line Access: https://docs.min.io/docs/minio-client-quickstart-guide
   $ mc config host add myminio http://10.10.126.88:9000 minioadmin minioadmin

... ...

在这样的启动模式下,对于每一份对象数据,minio直接在data下面存储这份数据,不会建立副本,也不会启用纠删码机制。因此,这种模式无论是服务实例还是磁盘都是“单点”,无任何高可用保障,磁盘损坏就表示数据丢失。

同样在单minio server的情况下,erasure code mode即为minio server实例传入多个本地磁盘参数。一旦遇到多于一个磁盘参数,minio server会自动启用erasure code modeerasure code对磁盘的个数是有要求的,如不满足要求,实例启动将失败:

$minio server data1 data2
ERROR Invalid command line arguments: Incorrect number of endpoints provided [data1 data2]
      > Please provide an even number of endpoints greater or equal to 4
      HINT:
        For more information, please refer to https://docs.min.io/docs/minio-erasure-code-quickstart-guide

erasure code启用后,要求传给minio server的endpoint(standalone模式下,即本地磁盘上的目录)至少为4个。minio server启用纠删码机制后,会自动将传入的disk drive划分为多个erasure coding set,每个erasure coding set中的disk drive的数量可以是:4, 6, 8, 10, 12, 14 和16。minio server会根据传入disk drive的数量自动计算set个数和每个set中的disk drive数量。比如下面例子中,我们传入四个endpoint(disk drive)给minio server:

$minio server data1 data2 data3 data4

Formatting 1 zone, 1 set(s), 4 drives per set.
WARNING: Host local has more than 2 drives of set. A host failure will result in data becoming unavailable.
Status:         4 Online, 0 Offline.
Endpoint:  http://10.10.126.88:9000  http://127.0.0.1:9000
AccessKey: minioadmin
SecretKey: minioadmin

Browser Access:
   http://10.10.126.88:9000  http://127.0.0.1:9000           

Command-line Access: https://docs.min.io/docs/minio-client-quickstart-guide
   $ mc config host add myminio http://10.10.126.88:9000 minioadmin minioadmin

... ...

从minio server的输出日志来看,minio server将这些drive放入了一个erasure coding set了。在输出日志中,我们还看到一行WARNING: Host local has more than 2 drives of set. A host failure will result in data becoming unavailable.,即minio server警告我们:这个erasure coding set中有多于两个的drive都在local host上,这样一旦host宕机,那么数据将无法获取。(每个set 有4个drive,根据纠删码的机制,这个set的最大允许失效的disk数量为4/2=2)。

我们再来看minio server启动的一个“语法糖” – “省略号”语法:

$minio server data{1...18}

Formatting 1 zone, 3 set(s), 6 drives per set.
WARNING: Host local has more than 3 drives of set. A host failure will result in data becoming unavailable.
WARNING: Host local has more than 3 drives of set. A host failure will result in data becoming unavailable.
WARNING: Host local has more than 3 drives of set. A host failure will result in data becoming unavailable.
Status:         18 Online, 0 Offline.
Endpoint:  http://10.10.126.88:9000  http://127.0.0.1:9000
AccessKey: minioadmin
SecretKey: minioadmin

Browser Access:
   http://10.10.126.88:9000  http://127.0.0.1:9000           

Command-line Access: https://docs.min.io/docs/minio-client-quickstart-guide
   $ mc config host add myminio http://10.10.126.88:9000 minioadmin minioadmin

... ...

minio server data{1...18}等价于minio server data1 data2 data3 data4 data5 data6 data7 data8 data9 data10 data11 data 12 data13 data14 data15 data16 data17 data18。minio server会自行扩展省略号代表的内容。我们看到:当我们传入18个disk drive后,minio server创建了3个erasure coding set,每个set中有6个disk drive。同样,minio server还针对每个set输出了一行WARNING:每个Set中有三个以上的disk drive都位于同一台host上。

这些WARNING我们可以通过distributed mode来解决。顾名思义,distributed mode下,minio server实例和其管理的disk drive分布在多台host上,这种模式可以避免minio server实例单点,数据也将分布在不同host上的不同disk中,实现了高可用,提升了整体的容灾能力。由于处理多个host上的disk,distribute mode默认就会启动erasure coding set机制。

在distributed mode下,minio server后面的远程的endpoint采用http url编码格式:

export MINIO_ACCESS_KEY=<ACCESS_KEY>
export MINIO_SECRET_KEY=<SECRET_KEY>
$minio server http://host{1...4}:9000/minio/data{1...4}

上面例子中的minio server命令相当于4个host,每个host上启动一个minio server实例,每个实例都管理16的disk drive(包括本地和远程的)。上述命令等价于:

$minio server http://host1:9000/minio/data1 http://host1:9000/minio/data2 http://host1:9000/minio/data3 http://host1:9000/minio/data4 http://host2:9000/minio/data1 http://host2:9000/minio/data2 http://host2:9000/minio/data3 http://host2:9000/minio/data4 http://host3:9000/minio/data1 http://host3:9000/minio/data2 http://host3:9000/minio/data3 http://host3:9000/minio/data4 http://host4:9000/minio/data1 http://host4:9000/minio/data2 http://host4:9000/minio/data3 http://host4:9000/minio/data4

minio同样会自动将这些disk drive划分为若干个erasure coding set。每个endpoint用http://address/disk-drive-path的形式编码。注意:这条命令在host1、host2、host3和host4上都要执行

minio有一个zone的概念,比如下面这个例子:

$minio server data{1...8} data{9...16}

Formatting 1 zone, 1 set(s), 8 drives per set.
WARNING: Host local has more than 4 drives of set. A host failure will result in data becoming unavailable.
Formatting 2 zone, 1 set(s), 8 drives per set.
WARNING: Host local has more than 4 drives of set. A host failure will result in data becoming unavailable.
Status:         16 Online, 0 Offline.
Endpoint:  http://10.10.126.88:9000  http://127.0.0.1:9000
AccessKey: minioadmin
SecretKey: minioadmin

Browser Access:
   http://10.10.126.88:9000  http://127.0.0.1:9000           

Command-line Access: https://docs.min.io/docs/minio-client-quickstart-guide
   $ mc config host add myminio http://10.10.126.88:9000 minioadmin minioadmin

... ...

我们在命令行中给minio server传入两组采用“省略号”语法的参数,minio认为每组就是一个“zone”,这里有两组,因此minio创建了两个zone。在每个zone内,minio创建了一个erasure coding set,每个set中有8个disk drive。对于外部的写数据请求,minio server会首先查找可用空间多的zone,然后再在zone内选择set和disk drive。

如果不用“省略号”语法,那么minio server会将后面传入的所有disk drive放入一个zone中。

三. 原型验证环境搭建与配置

1. 单机上部署distributed minio集群

我们的验证环境采用最小的distributed minio模式:单机、one zone, one erasure coding set, 4 disk drive。下面是部署的示意图:

img{512x368}
图:单机上部署distributed minio集群

我们没有使用“省略号”语法,在单机上不是很好模拟。我们通过下面脚本来启动该minio集群:

# cat startup_minio.sh
#!/bin/bash

export MINIO_ACCESS_KEY="minio"
export MINIO_SECRET_KEY="minio123"

for i in {01..04}; do
    nohup minio server --address ":90${i}" http://127.0.0.1:9001/root/minio-install/data1 http://127.0.0.1:9002/root/minio-install/data2  http://127.0.0.1:9003/root/minio-install/data3 http://127.0.0.1:9004/root/minio-install/data4 > "/root/minio-install/90${i}.log"& 2>&1
done

启动该minio集群,并查看启动状态:

# bash startup_minio.sh

# ps -ef|grep minio

root      1218     1 11 21:58 pts/5    00:00:01 minio server --address :9001 http://127.0.0.1:9001/root/minio-install/data1 http://127.0.0.1:9002/root/minio-install/data2 http://127.0.0.1:9003/root/minio-install/data3 http://127.0.0.1:9004/root/minio-install/data4
root      1219     1 11 21:58 pts/5    00:00:01 minio server --address :9002 http://127.0.0.1:9001/root/minio-install/data1 http://127.0.0.1:9002/root/minio-install/data2 http://127.0.0.1:9003/root/minio-install/data3 http://127.0.0.1:9004/root/minio-install/data4
root      1220     1  3 21:58 pts/5    00:00:00 minio server --address :9003 http://127.0.0.1:9001/root/minio-install/data1 http://127.0.0.1:9002/root/minio-install/data2 http://127.0.0.1:9003/root/minio-install/data3 http://127.0.0.1:9004/root/minio-install/data4
root      1221     1 11 21:58 pts/5    00:00:01 minio server --address :9004 http://127.0.0.1:9001/root/minio-install/data1 http://127.0.0.1:9002/root/minio-install/data2 http://127.0.0.1:9003/root/minio-install/data3 http://127.0.0.1:9004/root/minio-install/data4

root@instance-cspzrq3u:~/minio-install# ls
9001.log  9002.log  9003.log  9004.log  data1  data2  data3  data4  startup_minio.sh
root@instance-cspzrq3u:~/minio-install# tail -100f 9001.log

Formatting 1 zone, 1 set(s), 4 drives per set.
Attempting encryption of all config, IAM users and policies on MinIO backend
Status:         4 Online, 0 Offline.
Endpoint:  http://192.168.16.4:9001  http://172.17.0.1:9001  http://172.18.0.1:9001  http://127.0.0.1:9001       

Browser Access:
   http://192.168.16.4:9001  http://172.17.0.1:9001  http://172.18.0.1:9001  http://127.0.0.1:9001       

.... ...

2. mc配置与管理

minio官方提供了mc命令行工具,用于对minio server进行管理。我们首先要为mc创建一个管理本地minio server(:9001)的配置:

# mc config host add myminio http://localhost:9001 minio minio123
Added `myminio` successfully.

这里我们使用mc添加了一个所谓”host”,指向上面创建的minio server(:9001)。上面的命令实质上是在~/.mc/config.json中写入了如下配置:

# cat ~/.mc/config.json
{
    "version": "9",
    "hosts": {
        "myminio": {
            "url": "http://localhost:9001",
            "accessKey": "minio",
            "secretKey": "minio123",
            "api": "s3v4",
            "lookup": "auto"
        }
    }
}

接下来,我们通过mc命令在minio集群中添加三个bucket:

root@instance-cspzrq3u:~# mc mb myminio/image
Bucket created successfully `myminio/image`.
root@instance-cspzrq3u:~# mc mb myminio/video
Bucket created successfully `myminio/video`.
root@instance-cspzrq3u:~# mc mb myminio/audio
Bucket created successfully `myminio/audio`.
root@instance-cspzrq3u:~# mc ls myminio
[2020-03-16 15:19:55 CST]      0B audio/
[2020-03-16 15:19:48 CST]      0B image/
[2020-03-16 15:19:52 CST]      0B video/

新创建的bucket默认的访问policy是none,即外部无访问权限:

root@instance-cspzrq3u:~# mc policy get myminio/image
Access permission for `myminio/image` is `none`

根据我们的设计,我们需要给这三个bucket添加外部可读取权限,以image这个bucket为例:

root@instance-cspzrq3u:~# mc policy set download myminio/image
Access permission for `myminio/image` is set to `download`
root@instance-cspzrq3u:~# mc policy get myminio/image
Access permission for `myminio/image` is `download`

3. load balancer设置

这里我们使用一个nginx前置在minio集群外部,下面是为minio创建的nginx配置文件(/etc/nginx/conf.d/minio.conf):

// /etc/nginx/conf.d/minio.conf

 upstream minio_cluster {
    server localhost:9001;
    server localhost:9002;
    server localhost:9003;
    server localhost:9004;
 }

server {
 listen 9000;
 server_name myminio.tonybai.com;

 # To allow special characters in headers
 ignore_invalid_headers off;
 # Allow any size file to be uploaded.
 # Set to a value such as 1000m; to restrict file size to a specific value
 client_max_body_size 0;
 # To disable buffering
 proxy_buffering off;

location / {

   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   proxy_set_header X-Forwarded-Proto $scheme;
   proxy_set_header Host $http_host;

   proxy_connect_timeout 300;
   # Default is HTTP/1, keepalive is only enabled in HTTP/1.1
   proxy_http_version 1.1;
   proxy_set_header Connection "";
   chunked_transfer_encoding off;

   proxy_pass http://minio_cluster;
}

location /image/ {
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   proxy_set_header X-Forwarded-Proto $scheme;
   proxy_set_header Host $http_host;

   proxy_connect_timeout 300;
   # Default is HTTP/1, keepalive is only enabled in HTTP/1.1
   proxy_http_version 1.1;
   proxy_set_header Connection "";
   chunked_transfer_encoding off;
   client_max_body_size 1000m;
   proxy_buffering off;

   proxy_pass http://minio_cluster;
 }
}

重启nginx(nginx -s reload)。

我们使用浏览器访问一下http://myminio.tonybai.com:9000/,登录后,你将看到如下页面:

img{512x368}
图:浏览器访问minio web

选择左侧的”image” bucket,点击右下角的”+”号,我们可以上传一张图片:gopher-daily-logo.png,上传后,我们退出登录。然后通过地址http://myminio.tonybai.com:9000/image/gopher-daily-logo.png访问该图片。你也可以通过wget命令下载该图片:

$wget -c http://myminio.tonybai.com:9000/image/gopher-daily-logo.png
--2020-03-16 15:40:20--  http://myminio.tonybai.com:9000/image/gopher-daily-logo.png
正在解析主机 myminio.tonybai.com (myminio.tonybai.com)... 106.12.69.83
正在连接 myminio.tonybai.com (myminio.tonybai.com)|106.12.69.83|:9000... 已连接。
已发出 HTTP 请求,正在等待回应... 200 OK
长度:59736 (58K) [image/png]
正在保存至: “gopher-daily-logo.png”

gopher-daily-logo.png        100%[============================================>]  58.34K   253KB/s  用时 0.2s   

2020-03-16 15:40:20 (253 KB/s) - 已保存 “gopher-daily-logo.png” [59736/59736])

4. 对象清除

我们的需求中,bucket中的数据对象的生命周期是7天,我们可以使用定时工具或一个job通过mc工具对这些过期对象进行清除,比如我们每隔5分钟执行一次下面的命令:

$mc rm --recursive --force --newer-than 7d myminio/image/

该命令将递归删除image bucket下早于7天前创建的数据对象。rm命令支持各种条件组合,具体可参考一下mc rm的manual。

至此,使用minio搭建高性能对象存储的第一步:原型算是顺利搭建ok了。相信在后续对minio的深入使用和了解后,会有更多关于minio的内容和大家分享。


我的网课“Kubernetes实战:高可用集群搭建、配置、运维与应用”在慕课网上线了,感谢小伙伴们学习支持!

我爱发短信:企业级短信平台定制开发专家 https://51smspush.com/
smspush : 可部署在企业内部的定制化短信平台,三网覆盖,不惧大并发接入,可定制扩展; 短信内容你来定,不再受约束, 接口丰富,支持长短信,签名可选。

著名云主机服务厂商DigitalOcean发布最新的主机计划,入门级Droplet配置升级为:1 core CPU、1G内存、25G高速SSD,价格5$/月。有使用DigitalOcean需求的朋友,可以打开这个链接地址:https://m.do.co/c/bff6eed92687 开启你的DO主机之路。

Gopher Daily(Gopher每日新闻)归档仓库 – https://github.com/bigwhite/gopherdaily

我的联系方式:

微博:https://weibo.com/bigwhite20xx
微信公众号:iamtonybai
博客:tonybai.com
github: https://github.com/bigwhite

微信赞赏:

img{512x368}

商务合作方式:撰稿、出书、培训、在线课程、合伙创业、咨询、广告合作。

© 2020, bigwhite. 版权所有.

Related posts:


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK