简介:seaweedfs是一套基于go语言开发的分布式存储系统,目前最佳的海量小文件存储解决方案(大中型文件存储也没问题),支持fuse加载、支持api方式调用、支持设置有效期自动清理、支持多机房多机柜异地容灾等,项目地址:https://github.com/chrislusf/seaweedfs
seaweedfs
搭建
#最小化集群(master+volume+filer)
./weed server -dir data/vol1 -filer -ip localhost -master.dir data/mdir -volume.images.fix.orientation -volume.max 5000 - volume.port 9334
#在另外的机器加一个vol节点
./weed volume -dir data/vol2 -images.fix.orientation -port 9335 -ip localhost -max 5000 -mserver master1:9333,master2:9333
#在另外的机器加一个master节点(master节点需要单数个)
./weed master -ip localhost -mdir data/mdir -port 9333 -peers masterip1:9333,masterip2:9333
#在另外机器加filer节点
./weed filer -ip localhost -master masterip1:9333,masterip2:9333 -peers filerip1:8888,filerip2:8888 -port 8888
注意事项
- volume的max参数代表最大可创建的块数量,一个块默认为30GB,根据实例所在服务器的磁盘空间计算,保留必要的冗余之后可以尽可能多的设置。
- 使用seaweedfs的filer组件存储图片如果出现502、503、各种timeout的错误在排除网络带宽、filer.toml设置的最大数据库连接数 的因素后可以尝试分流filer服务的流量,因为根据seaweedfs的wiki中说的filer要处理文件内容并完成网络请求的分发所以压力比较大,所以适时地扩充更多的filer节点能有效的降低或避免50x以及timeout的发生
使用
#通过master直接上传
curl -F file=@/home/chris/myphoto.jpg http://localhost:9333/submit
{"fid":"3,01fbe0dc6f1f38","fileName":"myphoto.jpg","fileUrl":"localhost:8080/3,01fbe0dc6f1f38","size":68231}
# time to live, examples, 3m: 3 minutes, 4h: 4 hours, 5d: 5 days, 6w: 6 weeks, 7M: 7 months, 8y: 8 years
#curl通过filer上传图片
curl http://ipaddr:8888/testjpg.jpg -F "img=@/tmp/testjpg.jpg"
#curl通过filer上传图片图片有效期1年
curl http://ipaddr:8888/testjpg.jpg?ttl=1y -F "img=@/tmp/testjpg.jpg"
#不使用filer上传
curl http://ipaddr:9333/dir/assign
#不使用filer上传图片有效期1分钟
curl http://ipaddr:9333/dir/assign?ttl=1m
#返回:
{"fid":"123,12312321312","url":"ipaddrreturnbymaster:9334","publicUrl":"ipaddr:9334","count":1}
#上传文件
curl http://ipaddrreturnbymaster:9334/123,12312321312 -F "img=@/tmp/testjpg.jpg"
#通过filer将文件挂载到本地操作
weed mount -filer=localhost:8888 -dir=/some/existing/dir -filer.path=/one/remote/folder
#通过api接口遍历文件
curl -H "Accept: application/json" "http://filerip:port/?pretty=y"
- 通过kotlin调用(java类似)
//使用javaclient操作seaweedfs filer接口
//kotlin+hutool+seaweedfs-javaclient
@Test
fun filerTest(){
//connect to filer grpc port
val fc=FilerClient("localhost",18888)
//准备数据
val ba15mb= RandomUtils.nextBytes(1024*1024*15)
val ba1mb=RandomUtils.nextBytes(1024*1024)
val ba50mb=RandomUtils.nextBytes(1024*1024*50)
//清理测试目录
fc.rm("/ice",true,true)
fc.mkdirs("/ice",666)
for (i in 0 until 10){
var sos1:SeaweedOutputStream
var sos15:SeaweedOutputStream
var sos50:SeaweedOutputStream
var ut= measureTimeMillis {
sos1=SeaweedOutputStream(fc,"/ice/idx_${i}_1mb.dat")
sos15=SeaweedOutputStream(fc,"/ice/idx_${i}_15mb.txt")
sos50=SeaweedOutputStream(fc,"/ice/idx_${i}_50mb.txt")
}
println("ut1:${ut} ms")
ut= measureTimeMillis {
sos1?.use {
it.write(ba1mb)
}
sos15?.use {
it.write(ba15mb)
}
sos50?.use {
it.write(ba50mb)
}
}
println("ut2:${ut} ms")
}
println("ok")
}
//测试结果:ut1:20 ms
//ut2:7104 ms
//ut1:1 ms
//ut2:683 ms
//ut1:0 ms
//ut2:691 ms
//ut1:0 ms
//ut2:632 ms
//ut1:0 ms
//ut2:738 ms
//ut1:0 ms
//ut2:720 ms
//ut1:0 ms
//ut2:655 ms
//ut1:1 ms
//ut2:658 ms
//ut1:1 ms
//ut2:667 ms
//ut1:0 ms
//ut2:634 ms
//ok
性能优化
- 增加并发写入支持
#并发写入12个volume复制份数为2实际写入为24个volume并发写入(同时写入12个不同的)
curl http://localhost:9333/vol/grow?count=12&replication=001
- 增加并发读取支持
#设置复制份数为2则同一个文件支持两个并发读取,不同的资源并发读取数量以volume分块数为准(非volume server节点数)
curl http://localhost:9333/vol/grow?count=12&replication=001
- 增加同时打开文件数量
#先执行这个命令
ulimit -n 10240
#再启动seaweedfs
./weed .....
问题处理
- 修复丢失volume(有复制份数的情况下),生产系统建议周期性的定时执行此任务
weed shell -master masterip:9333
volume.fix.replication
seaweedfs空间清理
当filer中有文件被删除后,seaweedfs不会立即清理而是会每15分钟检测一次,当达到30%的空间占用后
- 使用Seaweedfs_java_client中的测试代码测试N次后本地data/vol1占用空间1.4GB,当前集群中实际存储文件共660MB
- 通过调用强制清理:
http://localhost:9333/vol/vacuum?garbageThreshold=0.0001后占用空间661MB - 或者使用shell
weed shell执行(代表文件占用体积达到0.1%就执行回收,假如总空间特别大的话,此比例可以再放小些,否则没达到指定的比例不会执行回收操作)
lock
volume.vacuum -garbageThreshold 0.001