2019独角兽企业重金招聘Python工程师标准>>>
计费系统中需要用到大量的小文件存储,之前一直用的hadoop的hdfs存储。来讨论下hadoop为啥不适用现在的项目:
1.计费文件比较小,一般都是几十KB,最大也不过几MB. 用Hadoop,每个文件都会占用128M的chunk,空间浪费。
2.研发项目都是基于go的,hadoop的go写的客户端gowfs实在是不好用,本身hadoop也不提供go的api(好像只支持java和c的)
3.hadoop的维护起来很麻烦。用的这一年多时间里,hdfs集群down掉了3-4次吧,每次都是全重启一遍就莫名其妙的好了。最近的一次是因为节点重启后ip变了,用gowfs接口上传的文件大小始终是0。用hdfs的命令行put文件的时候才发现put的时候失败了。最后把节点手动重启一遍,把hosts重新配置,重新免密登录后才恢复正常。
4.why choose weed fs,轻量级,go原生写的,支持http REST API上传,下载,删除文件。非常适合小文件存储。维护起来也方便,架构简单。
weed fs的使用(mac osx)
github仓库地址:https://github.com/chrislusf/seaweedfs (需要深度源码的时候再用)
下载安装包:https://bintray.com/chrislusf/seaweedfs/download_file?file_path=go_0.70_darwin_amd64.zip 目前最新的包是0.7.0(release)
解压后的安装包
pandadeMBP:go_0.70_darwin_amd64 panda$ ls
tools weed
tools: 自带的工具,可以解析idx文件 ./tools -file xxx.idx
weed: weed fs服务的核心程序
------------------------------weed 架构----------------------------------------
weed fs使用key-file的结构,每个file都有一个唯一的key.
weed-fs自身可以在两种模式下运行,一种是Master,另外一种则是Volume。
集群的维护以及强一致性的保证由master们保 证,master间通过raft协议实现强一致性。
Volume是实际管理和存储数据的运行实例。
下面我们来搭建个简单的weed fs集群(单机版)
./weed master -defaultReplication 001
启动weed master,并指定1个rack副本。默认端口是9333
(volume的dir必须存在)
./weed volume -max 2 -port 8081 -dir /tmp/data1
启动一个volume server, 它最多会有2个volume, 数据都存储在/tmp/data1下,监听的是8081端口
./weed volume -max 2 -port 8082 -dir /tmp/data2
启动另一个volume server, 它最多会有2个volume, 数据都存储在/tmp/data2下,监听的是8082端口
接下来就可以post和get文件了。
pandadeMBP:go_0.70_darwin_amd64 panda$ curl http://127.0.0.1:9333/dir/assign
{"fid":"19,96afc0da84","url":"127.0.0.1:8082","publicUrl":"127.0.0.1:8082","count":1}
第一步,申请文件id, 响应的是其中1个volume服务器的地址(127.0.0.1:8082)以及某个volume的卷ID(19)
第二步,post文件:
pandadeMBP:Downloads panda$ curl -F [email protected] http://127.0.0.1:8082/19,96afc0da84
{"name":"1.png","size":72674}
响应内容为文件名,及文件size
第三步,可以get文件内容了,在浏览器执行http://127.0.0.1:8082/19,96afc0da84 即可。
备注:由于mater设置了defaultReplication为001,所以volume的max必须》=2,在每次post文件的时候,2个volume之间会做备份
管理页面:
http://127.0.0.1:9333/ui/index.html master的管理页面
http://127.0.0.1:8081/ui/index.html volume的管理页面
------------------------------weed replication-----------------------------------
数据的可靠性则可以通过weed-fs提供的 replication机制保证。
weed-fs提供了若干种replication策略(rack – 机架,一个逻辑上的概念):
000 no replication, just one copy
001 replicate once on the same rack
010 replicate once on a different rack in the same data center
100 replicate once on a different data center
200 replicate twice on two other different data center
110 replicate once on a different rack, and once on a different data center
参考 weed fs集群文章: http://tonybai.com/2015/08/22/intro-of-using-weedfs/
------------------------------weed filer-----------------------------------
启动了一个文件服务器,它支持任何文件的REST操作。
//创建或重写一个文件, the directories /path/to 会被自动创建
POST /path/to/file
//获取文件内容
GET /path/to/file
//create or overwrite the file, the filename in the multipart request will be used
POST /path/to/
//返回子目录的文件列表的json格式
GET /path/to/
filer 既然是模仿传统上我们所认知的文件目录功能,那么就必然需要提供文件夹和文件的增删改查这四大功能。也因此,filer分两块实现,文件夹的增删改查,文件的增删改查,然后两者还要实现关联。
weed-fs认为文件夹的数量远远小于文件的数量,但是文件夹的访问次数又远远高于文件的次数,所以存储的处理上,文件夹是存放在内存中,而文件则是存放在leveldb中(go实现)。
文件夹的实现并不是很复杂,就是一大堆的字典组成一个目录树,而且,每一个文件夹的增删改操作都会记录到一个log文件里面去。每次启动的时候,都会先去加载这个log文件,根据上面记录的增删改操作在内存中构建出原有的目录树来。
文件增删改查的实现上,则要理解一点,即file id,在weed-fs中,每个存进来的文件都会给你一个file id,如果不启用 filer 功能的话,你要找一个文件是要通过 file id来查找的,而不是根据文件路径名来找到的。
参考 http://ju.outofmemory.cn/entry/93655
./weed filer -dir /tmp/metadata -defaultReplicaPlacement 001
在/tmp/metadata目录中可以看到log文件,这个思想类似于mysql,将每次操作都写到日志里,通过日志来回复数据。
pandadeMBP:Downloads panda$ curl -F [email protected] http://127.0.0.1:8888/test/10/21.png
{"name":"1.png","size":72674}
通过filer上传文件,也会做备份。
pandadeMBP:weed panda$ cat /tmp/metadata/dir.log
add /test 1
add /test/10 2
在dir.log中可以看到文件夹的创建操作。
在浏览器中可以执行: http://127.0.0.1:8888/test/
{
-
Directory: "/test/",
- Files: [
- {
-
name: "1.png",
-
fid: "18,7d7badbfa6"
-
- {
-
name: "12.png",
-
fid: "18,7e42429039"
-
- {
-
name: "13.png",
-
fid: "17,7f35826436"
-
- {
- Subdirectories: [
- {
-
Name: "10",
-
Id: 2
-
- {
}