前言
seaweedfs是一个非常优秀的由 golang 开发的分布式存储开源项目。它是用来存储文件的系统,并且与使用的语言无关,使得文件储存在云端变得非常方便,很适合做图片服务器,性能很好,安装操作都很简单,并且可兼容挂载提供路径访问的方式,可以较为便捷的将nginx+nfs此类的文件服务器转换成nginx+seweedfs并提供api接口并不影响原有访问url的模式
在逻辑上Seaweedfs的几个概念:
Node 系统抽象的节点,抽象为DataCenter、Rack、DataNode
DataCenter 数据中心,对应现实中的不同机房
Rack 机架,对应现实中的机柜
Datanode 存储节点,用于管理、存储逻辑卷
Volume 逻辑卷,存储的逻辑结构,逻辑卷下存储Needle
Needle 逻辑卷中的Object,对应存储的文件
Collection 文件集,可以分布在多个逻辑卷上
首先我们下载weed
在https://github.com/chrislusf/seaweedfs/releases/我们可以看到已有版本及历史,写此文档时最新的长期支持版本为1.34,我们下载解压后可以看见一个可执行文件weed,因为是golang编译好的,我们可以直接使用它
https://github.com/chrislusf/seaweedfs/releases/download/2.82/linux_arm64.tar.gz
tar -zxf linux_amd64.tar.gz
./weed -h # 查看帮助

一、启动服务
SeaweedFS服务端启动顺序:先启动
master,再启动卷volume
master的作用仅仅是管理文件卷与服务器磁盘的映射,连文件的元数据也不管理,因此不需要额外的磁盘存储,性能上也是极好的
1、启动master
[root@seaweedfs-bj-zw-vm1 ~]# /root/weed master -mdir=/data/seaweedfs -port=9333 -peers=172.16.100.107:9333,172.16.100.111:9333,172.16.100.106:9333 -defaultReplication="000" -ip="172.16.100.107" -garbageThreshold=0.3 -maxCpu=0 -pulseSeconds=5 -ip.bind=0.0.0.0 -volumeSizeLimitMB=30000 >>/root/master.out &
[root@seaweedfs-bj-zw-vm1 ~]# tree /data/ # 这个目录里其实没啥东西
/data/
└── seaweedfs
├── conf
├── log
└── snapshot
[root@seaweedfs-bj-zw-vm1 ~]# netstat -tpln|grep 9333
tcp6 0 0 :::19333 :::* LISTEN 770/weed
tcp6 0 0 :::9333 :::* LISTEN 770/weed
#这样我们一个master节点就起来,当然如果你需要高可用的时候要将另外的master节点也起来,master节点是奇数,他们之间会选举leader,剩下的成为从节点以备不时之需,我们的参数-peers就是指定所有的master节点ip及port,如果是测试只是用单机那就不用加这个参数了
参数
-cpuprofile String Cpu profile输出文件
-defaultReplication String 如果没有指定默认备份类型。默认”000”
-garbageThreshold String 清空和回收空间的阈值(默认”0.3”)
-ip String Master 服务器ip地址(默认”localhost”)
-ip.bind String 需要绑定的ip地址(默认”0.0.0.0”)
-maxCpu Int 最大cpu数量。0表示所有可用的cpu
-mdir String 存储元数据的数据目录(默认”/tmp”)
-memprofile String 内存配置文件输出文件
-peers String 代表服务器集群,逗号分隔所有主节点ip:端口,示例127.0.0.1:9093,127.0.0.1:9094
-port Int http监听端口(默认9333)
-pulseSeconds Int 心跳检测的时间间隔单位为秒(默认5)
-secure.secret String 加密json web token方法
-volumePreallocate 无 为volumes预先分配磁盘空间
-volumeSizeLimitMB Uint Master停止指向过量的volumes写的限定(默认30000)
-whiteList String 逗号分隔具有写权限的Ip地址。如果是空的,没有限制。即白名单
defaultReplication说明
000 不备份, 只有一份数据
001 在相同的rackj里备份一份数据
010 在相同数据中心内不同的rack间备份一份数据
100 在不同的数据中心备份一份数据
200 在两个不同的数据中心各复制2次
110 在不同的rack备份一份数据, 在不同的数据中心备份一次
如果数据备份类型是 xyz形式 各自的意义
x 在别的数据中心备份的份数
y 不相同数据中心不同的racks备份的份数
z 在别的服务器相同的rack的备份份数
2、挂载卷volume
volume很明显就是存储数据的真实节点了,它保留了文件的元数据及文件,通过卷的模式将磁盘分割,每个卷都有一个索引文件,每个元数据只有40字节,读取时间O(1),效率极高,速度极快
首先我们先将底层磁盘挂载上,我是2个1T的磁盘(测试可不挂载)
[root@seaweedfs-bj-zw-vm5 ~]# mkdir -p /data/seaweedfs/volume{1..2}
[root@seaweedfs-bj-zw-vm5 ~]# mount /dev/vdb /data/seaweedfs/volume1
[root@seaweedfs-bj-zw-vm5 ~]# mount /dev/vdc /data/seaweedfs/volume2
[root@seaweedfs-bj-zw-vm5 ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/vda1 40G 2.3G 38G 6% /
devtmpfs 1.9G 0 1.9G 0% /dev
tmpfs 1.9G 12K 1.9G 1% /dev/shm
tmpfs 1.9G 17M 1.9G 1% /run
tmpfs 1.9G 0 1.9G 0% /sys/fs/cgroup
tmpfs 379M 0 379M 0% /run/user/0
/dev/vdb 1.0T 369G 656G 36% /data/seaweedfs/volume1
/dev/vdc 1.0T 185G 840G 18% /data/seaweedfs/volume2
/root/weed volume -dir=/data/seaweedfs/volume1 -mserver=172.16.100.107:9333,172.16.100.111:9333,172.16.100.106:9333 -ip="172.16.100.136" -max=100 -dataCenter=zw -rack=openstack-bj-zw-bgp5 -idleTimeout=30 -images.fix.orientation=true -ip.bind=0.0.0.0 -maxCpu=0 -port=8081 -read.redirect=true >>/root/volume1.out &
/root/weed volume -dir=/data/seaweedfs/volume2 -mserver=172.16.100.107:9333,172.16.100.111:9333,172.16.100.106:9333 -ip="172.16.100.136" -max=100 -dataCenter=zw -rack=openstack-bj-zw-bgp5 -idleTimeout=30 -images.fix.orientation=true -ip.bind=0.0.0.0 -maxCpu=0 -port=8082 -read.redirect=true >>/root/volume2.out &
参数:
参数 类型 说明-cpuprofile string Cpu profile输出文件
-dataCenter string 当前volume服务的数据中心名称
-dir string 存储数据文件的目录dir[,dir]…(默认”/tmp”)
-idleTimeout Int 连接空闲时间秒数(默认30)
-images.fix.orientation (true/false) 上传时调整jpg方向
-index string 选择内存~性能平衡模式[memory|leveldb|boltdb|btree]。(默认”memory”)
-ip string Ip地址或服务器名称
-ip.bind string 需要绑定的ip地址(默认”0.0.0.0”)
-max string Volumes的最大值,count[,count]…(默认”7”)
-maxCpu Int 最大cpu数量。0表示所有可用的cpu
-memprofile string 内存配置文件输出文件
-mserver string 用逗号分隔的master服务器列表(默认”localhost:9333”)
-port Int http监听端口号(默认8080)
-port.public Int 端口对外开放
-publicUrl string 公开访问地址
-pulseSeconds Int 心跳之间的秒数,必须小于或等于master 服务器设置(默认5)
-rack string 当前volume服务器的rack 名称
-read.redirect (true/false) 重新定向转移或非本地 volumes
-whiteList string 逗号分隔具有写权限的Ip地址。如果是空的,没有限制。
du -sh /data/seaweedfs/volume1/*
30G /data/seaweedfs/volume1/23.dat
4.9M /data/seaweedfs/volume1/23.idx
30G /data/seaweedfs/volume1/29.dat
5.5M /data/seaweedfs/volume1/29.idx
30G /data/seaweedfs/volume1/33.dat
5.5M /data/seaweedfs/volume1/33.idx
30G /data/seaweedfs/volume1/34.dat
5.5M /data/seaweedfs/volume1/34.idx
30G /data/seaweedfs/volume1/35.dat
5.5M /data/seaweedfs/volume1/35.idx
30G /data/seaweedfs/volume1/36.dat
4.8M /data/seaweedfs/volume1/36.idx
30G /data/seaweedfs/volume1/41.dat
4.9M /data/seaweedfs/volume1/41.idx
30G /data/seaweedfs/volume1/42.dat
4.9M /data/seaweedfs/volume1/42.idx
30G /data/seaweedfs/volume1/43.dat
3.0M /data/seaweedfs/volume1/43.idx
30G /data/seaweedfs/volume1/50.dat
3.5M /data/seaweedfs/volume1/50.idx
30G /data/seaweedfs/volume1/51.dat
3.5M /data/seaweedfs/volume1/51.idx
30G /data/seaweedfs/volume1/53.dat
3.5M /data/seaweedfs/volume1/53.idx
8.1G /data/seaweedfs/volume1/58.dat
2.0M /data/seaweedfs/volume1/58.idx
7.9G /data/seaweedfs/volume1/62.dat
2.0M /data/seaweedfs/volume1/62.idx
我们可以看错,每个索引文件最大5M,数据文件30G,磁盘被分割成了很多的卷(idx+dat)
访问:
http://IP:9333

测试
现在的模式是master+ volume这种标准模式
[root@seaweedfs-bj-zw-vm5 ~]# curl http://172.16.100.107:9333/dir/assign
{"fid":"3,57f4e1898d66","url":"172.16.100.136:8082","publicUrl":"172.16. 100.136:8082","count":1}
[root@seaweedfs-bj-zw-vm5 ~]# curl -F file=@/root/9ee6c1c5d88b0468af1a3280865a6b7a.png http://172.16.100.136:8082/3,57f4e1898d66
[root@seaweedfs-bj-zw-vm5 ~]# wget 172.16.100.136:8082/3,57f4e1898d66
[root@seaweedfs-bj-zw-vm5 ~]# ls # 新下载下来的资源会被命名为fid
3,57f4e1898d66
[root@seaweedfs-bj-zw-vm5 ~]# curl -X DELETE 172.16.100.136:8082/3,57f4e1898d66
我们可以看出流程是,找master节点申请ip:port及fid,自己拼接ip:port/fid,然后post上传,此时该资源到服务器上了,我们可以对ip:port/fid进行get等请求
这里面有2点比较麻烦
1. 要先申请,再拼接,再上传
2. 要记录返回的ip:port/fid才能对该资源进行以后的操作,也就是3个信息
相对应的解决方式也是有的
1. curl -F file=@/root/9ee6c1c5d88b0468af1a3280865a6b7a.png http://172.16.100.107:9333/submit这样会直接上传(申请fid+上传)
2. wget 172.16.100.107:9333/3,57f4e1898d66我们就直接访问master节点ip:port/fid,这样也是可以操作资源的,因为内部默认是开启了内部代理功能,我们只需要记录fid就可以了
Seaweedfs基本操作命令: https://blog.youkuaiyun.com/ichen820/article/details/122083745
它的缺点主要还是来源于规模带来的一些问题
1.不是接口形式,所以项目需要直接操作磁盘,本身只支持get请求,其他请求需要代码来协助完成
2.权限问题,因为项目必须能操作磁盘,那么该目录的权限需要管理以及相关的安全问题
3.容量问题,随着时间的推移,我们的大磁盘需要扩容,可是每次扩容前我们需要备份(以防万一),而这个磁盘已经几个T了,备份时间过长
4.高可用问题,nfs的底层磁盘应该是某台机器组成的raid,那么这台机器挂了怎么办,当然有人说有备机,但是nfs挂载自动切换还有有点慢
5.所有需要落盘操作的机器都必须要挂载nfs,nfs的挂载连接数,磁盘io及网络开销随着挂载机器增多也在增大
6.Nfs是文件存储,随着文件的增多,文件的索引层级也会越来越深影响速度
7.逼格不够,哈哈哈哈
解决方式
我们自然是使用本次的seaweedfs作为图片服务器了,这样就可以对应解决我们上述的问题
1.默认提供restful api,不需要代码层级再度实现
2.有了接口走的是http协议,只需要网络通就可以,不需要到处挂载文件系统了
3.容量不足了我们加机器、加磁盘进集群即可
4.本身实现了多种备份方式,可根据实际情况来选择
5.本质还是对象存储,索引文件5M,操作速度极快
引出的问题
1.现有阶段的代码都是以url/文件路径,这种模式进行操作的,而seaweedfs是url/fid,改动量太大,不好实现
2.因为是restful api,所以大家都能直接delete,很危险……
解决方式
1.使用filer功能
2.对内网提供不同的域名,对外域名在Nginx上只允许get请求
filer节点
filer节点是可以在任何地方执行的,它再次打开了一个http服务,并且也对外提供restful api,只是我们可以使用url/文件路径的模式进行访问了(之前的url/fid依然生效),filer节点提供的http服务可以如同一个文件系统一样被挂载,在挂载点,我们可以直观的看见目录层级(也是对象),及操作各个文件
[root@seaweedfs-bj-zw-vm1 ~]# /root/weed filer -master=172.16.100.111:9333,172.16.100.107:9333,172.16.100.106:9333 -ip=172.16.100.107 -defaultReplicaPlacement='000' -disableDirListing >>/root/filer.out &
[root@seaweedfs-bj-zw-vm1 ~]# /root/weed mount -filer=172.16.100.107:8888 -dir=/mnt >>/dev/null &
[root@seaweedfs-bj-zw-vm1 ~]# netstat -tpln|grep 8888
tcp 0 0 172.16.100.107:8888 0.0.0.0:* LISTEN 771/weed
tcp6 0 0 :::18888 :::* LISTEN 771/weed
[root@seaweedfs-bj-zw-vm1 ~]# df -h|grep mnt
SeaweedFS 1.3T 1.2T 48G 97% /mnt
访问的流程其实还是,以路径模式操作—根据路径获取fid—以fid模式操作----seaweedfs,也就是路径跟fid之间filer节点帮你做了一次转换

在默认情况下这种对应关系是存放在内存当中,实际情况下,我们需要安装一个记录关系的服务,以下是官方推荐的服务及其功能,我们果断使用了熟悉的redis,redis的记录也很简单,就是最简单的string的kv对应关系,key是路径,value是fid(转义过的),当然其他存储的关系大概也能想来,数据库类的自然就是有一个表(这个表的sql在配置文件里都有),然后就是两个记录的字段即可

[root@seaweedfs-bj-zw-vm1 ~]# mkdir -p /etc/seaweedfs
[root@seaweedfs-bj-zw-vm1 ~]# cd /etc/seaweedfs
[root@seaweedfs-bj-zw-vm1 seaweedfs]# /root/weed scaffold filer -output=" filer.toml "
[root@seaweedfs-bj-zw-vm1 ~]# vim /etc/seaweedfs/filer.toml # 把redis的信息填好,如果使用其他后端,将其enabled改成true并填写相关信息即可
[redis]
enabled = true
address = "xxx:6379"
password = ""
db = 0
我们重启filer服务后再次挂载,此时对应关系就会存在redis里了,个人已经放入1.T数据,大概1.5亿个key,在性能上完全没问题
后期我们不论是使用restful api,还是在mount的目录直接进行操作,还是在redis的库里直接操作,这三者操作都是一致的。例如我们在redis上删除了某个路径的key,那么这个文件就会直接消失,因此保存关系的后端也要维护好哦,当然,如果redis挂了,那么filer功能就会崩溃,只能直接使用url/fid的模式
配置运行Filer并挂载到本地目录
master执行
1.启动filer节点
yum install -y fuse
/root/weed filer -master=10.191.72.112:9333 -ip=10.191.72.112 -port=8888 -defaultReplicaPl
acement=000 &>>/data/seaweedfs/status/filer.log &
参数 类型 说明
collection String 所有数据将存储在这个集合中
dataCenter String 首选在此数据中心写入volumes
defaultReplicaPlacement String 如果没有指定默认复制类型(默认“000”)
dirListLimit Int 限制子目录列表大小
disableDirListing 无 关闭目录清单
ip String Filter服务器http监听ip地址
master String 用逗号分隔的master服务器(默认“localhost:9333”)
maxMB Int 分割文件大于限制(默认32)
port Int Filer服务器htp监听端口(默认8888)
port.grpc Int Filer grpc服务器监听端口,默认为 http的端口+10000
port.public Int 对外开放的端口
redirectOnRead 无 在文件GET请求期间是代理还是重定向到volumes服务器
secure.secret String 加密Json Web令牌(JWT)的密钥
mount挂载客户端执行
yum install -y fuse
/root/weed mount -filer=10.191.72.112:8888 -dir=/seaweedfs/mount/ &>>/seaweedfs/status
/mount.log &
参数:
-filer filer节点
-dir 客户端挂载地址
SeaweedFS命令集:
benchmark
backup
compact
filer
fix
server
master
filer
s3
upload
download
shell
version
volume
export
mount
1476



被折叠的 条评论
为什么被折叠?



