SeaweedFS使用 Last updated: 2022-09-22 15:19:12
之所以使用SeaweedFS,原因其实也很简单,看下面的主流产品对照表:
名称 | 开源协议 | 开发语言 | star数量 | 官网地址 | 分布式 | 图片缩略图 | TTL | 加密 | 支持Unix-like | 支持Windows | 其他信息 |
---|---|---|---|---|---|---|---|---|---|---|---|
SeaweedFS | Apache 2.0 | Golang | 15.4k | seaweedfs | √ | √ | √ | √ | √ | √ | 2014年创立,新一代文件系统 |
HDFS | Apache 2.0 | Java | 12.9k | hadoop | √ | × | × | × | √ | √ | Apache旗下的重型武器,但已显老旧,是Hadoop一部分,需要安装Hadoop才能使用,是上一代程序员们的最爱。 |
GlusterFS | LGPL 3.0 | C | 3.8k | glusterfs | √ | × | × | × | √ | × | 号称一分钟就可以部署起来的一套文件系统 |
Ceph | GPL v2.0、LGPL v2.1、LGPL v3.0等多重协议 | C++ | 3.8k | ceph | √ | × | × | × | √ | 乄 | 对Unix-like系统支持的很好,只支持Windows Server 2019和2016 |
MooseFS | GPL v2.0 | C | 1.3k | moosefs | √ | × | × | × | √ | × | 号称支持PB级数据 |
MinIO是 | AGPL v3.0、MinIO Commercial License | Golang | 35.4k | minio | √ | √ | √ | √ | 有挺有很不错的UI管理台,不要在你的产品中集成它的mc,否则你就得开源 | ||
FastDFS | GPL v3.0 | C | 8.2k | fastdfs | √ | × | × | × | √ | × | 国内用的人挺多的,据说还是个中国人开发的 |
前后左右看了一圈,只能是SeaweedFS了。
SeaweedFS简介
SeaweedFS是一个分布式文件存储系统,基于Apache 2.0协议开源(可以基于其上开发商业闭源软件)。
Seaweed似乎可以翻译为海藻。但是请注意,这个当年的《蜗居》没什么关系。
SeaweedFS官方号称能够存储数十亿个文件,而且能够非常快速的存取。
SeaweedFS有两个服务器组成,一个是Master服务器,主要职责是管理文件卷,另外一个是卷服务器,主要用于存储文件元数据。这大大减轻了Master服务器的并发压力,因为这使得只需要一个磁盘进行读操作,另一个磁盘去完成写操作。
SeaweedFS的官方地址:SeaweedFS
SeaweedFS特性
- 可配置的复制级别
- 自动主服务器故障转移,即:没有单点故障
- 自动对文件进行gzip压缩,当然,压缩情况依赖于文件的具体类型
- 自动压实存储,即:删除或更新的文件空出来的磁盘空间会及时回收
- 自动TTL,即:自动过期机制
- 支持多磁盘存储空间向总存储空间添加,即:将零散空闲的磁盘空间聚集起来做成FS
- 添加删除服务器不会导致数据重新负载均衡,当然,管理员可以手动触发此操作
- 图片缩略图
- 支持为文件设置ETag、Accept-Range、Last-Modified等信息
- 可以在内存模式、存储模式、只读模式之间切换以达到性能最大化的要求
- 支持对可写卷和只读卷进行再平衡
- 可定义多个存储层和磁盘类型,以达到平衡性能和成本的目的
- 支持扩展第三方云存储让数据回暖
- 为热存储而实现的可擦除代码使得感知机架机制(Rack-Aware 10.4)能够降低存储成本并提高可用性
文件功能特性
- 文件服务器,通过HTTP协议访问文件和目录
- 文件TTL,文件的元数据和文件的实体数据都支持自动过期机制
- 通过FUSE直接访问存储在磁盘上的本地文件
- 同步复制功能,HA高可用
- 异步单路或多路复制以提升集群的可用性
- 支持S3
- 支持从Hadoop、Spark、Flink上访问文件甚至直接运行HBase
- 异步复制到云,使用专业化的手段异步复制到S3、Google Cloud、Azure、BackBlaze
- WebDAV,访问Mac和Windows或移动设备上的映射驱动器
- 支持加密存储,使用AES256-GCM加密
- 支持大文件,据说支持TB级
- 将通过云存储驱动挂载到本地集群中的方式,可以实现数据快速回写到云存储中
- 对挂载到本地的云存储中的对象进行远程操作, 对于上一点来说是可选的
Seaweed部署
Seaweed分为Master服务器和卷服务器。它是一种分布式文件存储系统,有多种集群部署方式。本例中,我们使用下面的部署拓扑图:
使用入门
启动Master服务器
./weed master
启动卷服务器
./week volumn -dir="/data/dir1" -max=5 -mserver="192.168.0.1:9333" -port=8080
./week volumn -dir="/data/dir2" -max=10 -mserver="192.168.0.1:9333" -port=8081
如果条件允许,你可以将Master服务器、各卷服务器分别部署在不同的服务器上,至少部署时指向到不同的磁盘上,就能实现性能最大化。
文件操作
上传文件
先发一个请求,获得一个文件ID(fid):
> curl http://localhost:9333/dir/assign
{"count":1,"fid":"3,01637037d6","url":"127.0.0.1:8080","publicUrl":"localhost:8080"}
再发送一个基于HTTP协议的multi-part的POST请求上传文件(请求的URL后面要加上文件ID):
curl -F file=@/home/chris/myphoto.jpg http://127.0.0.1:8080/3,01637037d6
{"name":"myphoto.jpg","size":43234,"eTag":"1cc0118e"}
删除文件
> curl -X DELETE http://127.0.0.1:8080/3,01637037d6
💡 说明:
此处的示例中返回的文件ID(fid)是3,01637037d6
,3
是存储文件的所在卷,逗号后面的01
是文件的Key,再后面的637037d6
是文件的cookie:
- 存储文件的卷ID(此处是3
),是一个32位的无符号整数
- 文件的Key(此处是01
)是一个64位的无符号整数,以16进制形式返回
- 文件的cookie(此处是637037d6
)是一个32位的无符号整数,以16进制形式返回
使用这些,是为了防止URL猜测。你可以以<volume id, file key, file cookie>
的元组形式保存和使用这些数据,也可以统一存储为一个字符串去使用,如果要以字符串存储和使用,需要8+1+16+8=33个字节,所以在数据库中定义一个char(33)
型的字段就够用了。
获取文件
首先,根据卷ID获得卷信息:
> curl http://localhost:9333/dir/lookup?volumeId=3
{"volumeId":"3","locations":[{"publicUrl":"localhost:8080","url":"localhost:8080"}]}
现在,就可以使用URL访问文件了:
http://localhost:8080/3,01637037d6.jpg
💡 说明:
1. 第一步查询卷ID时可能会返回多个卷(这表明文件存储在多个卷上),但是通常卷不会移动,所以你可以不必每次都来获取,你可以在你自己的业务系统中第一步请求的卷信息。
2. 第二步请求文件时,URL后面的.jpg
是你加上去的(回顾一下前面上传文件时得到的文件ID是3,01637037d6
,并没有.jpg
),你加上去了,返回时就会再返回来,这样你就可以灵活便捷地指定文件类型了。
还可以以一种美化了的URL的形式获取文件:
http://localhost:8080/3/01637037d6/my_preferred_name.jpg
http://localhost:8080/3/01637037d6.jpg
http://localhost:8080/3,01637037d6.jpg
http://localhost:8080/3/01637037d6
http://localhost:8080/3,01637037d6
还可以通过在URL上传递参数实现对图片文件获取缩略图(这个功能是非常有用的):
http://localhost:8080/3/01637037d6.jpg?height=200&width=200
http://localhost:8080/3/01637037d6.jpg?height=200&width=200&mode=fit
http://localhost:8080/3/01637037d6.jpg?height=200&width=200&mode=fill
高级特性
文件自动过期(TTL)机制
假定我们想要上传一个文件,让它3分钟内有效,如前所述,先获取文件ID:
curl http://localhost:9333/dir/assign?ttl=3m
{"count":1,"fid":"5,01637037d6","url":"127.0.0.1:8080","publicUrl":"localhost:8080"}
现在,用这个文件ID上传一个文件:
curl -F "file=@./main.go" http://127.0.0.1:8080/5,01637037d6?ttl=3m
💡 说明:
1. 在有效期内,使用获取文件的方式请求时,会返回文件内容,如果在有效期之外了,会返回404(Not Found)并提示文件已丢失。
2. 您可能已经注意到两次请求都传了ttl=3m
这个时间参数,第一次获取文件ID时传ttl=3m
是让Master服务器选择匹配的卷,第二次上传文件时传ttl=3m
是将这个过期时间和文件一起写入服务器保存起来。这种机制有一个好处是可以更加灵活的微调文件的TTL,同时减少卷的TTL变化量,最终简化了管理TTL卷。
3. 这些情况对你来说没有什么影响,它们也不一定要完全相同,只要第二次的时间大于第一次的时间就可以了。
4. 支持的TTL格式示例:3m(3分钟)、4h(4小时)、5d(5天)、6w(6周)、7M(7个月)、8y(8年)。
额外的技术细节(仅供了解):
- TTL似乎很容易实现,因为如果时间超过了TTL,Seaweed只需要报告文件不存在了即可。但是,真正的困难是从过期的文件中有效地回收磁盘空间,类似于JVM内存垃圾收集,这是一项精致的工作,并进行了许多人的努力。
- 最开始分配文件ID时,Master将会去寻找与TTL相匹配的卷,如果找到了,就直接返回,如果没找到,会先自动创建。
- 卷服务器会记录文件的过期时间,如果文件过期了,会报告文件不存在。
- 文件存入带有TTL的卷中后,如果该卷过期了,卷中的所有文件就都消失了。
- 如果试图将文件写入一个已经因为TTL过期而不存在的卷,将会报告404(Not Found),所以,请对文件上传操作的HTTP协议层状态进行判断,以确保结果是符合预期的。
- 卷服务器会追踪每个卷的最大过期时间,如果过期了,将不会再向Master服务器报告卷过期信息。
- 卷服务器如果发现卷过期之后又过了总过期时间的10%,或者已经过了10分钟,就会彻底删除该卷。
- 在生产环境下,如果TTL很长又有很多的文件使用这些过期时间,请注意分配好你的磁盘空间以防止出现磁盘满的错误,因为这些长时间不过期的却又带着过期时间的卷将会一直占用着磁盘空间。
- 建议不要将带和TTL和卷和不带TTL的卷混合部署在一个集群中,这是因为Master服务器默认指定集群中最大大小为30GB。
- 我们可以为每个TTL都指定一个最大配置,只不过这样做会比较麻烦,也许在以后我们会碰到这方面的强烈需求,到时候我们再进行优化。
其他补充
存取速度、数据热度,它们之间通常是有关联的,一般情况下是这样的:
NVME > SATA SSD > Fast HDD > Slow HDD > Cloud
Critical > Hot > Less Hot > Warm > Cold
从左往右,第一行是存储类型的速度由快到慢排列,第二行是数据状态排列。我们可以在启动Seaweed时通过命令行参数去设置。
其他内容正在研究中,有新的进展了再来补充。