2.10. weed-fs¶
weed-fs是Go语言实现的,类facebook haystack的面向blob的分布式存储系统.
上周从Quora问题 http://www.quora.com/What-is-a-good-choice-for-storing-blob-like-files-in-a-distributed-environment 下面的回答中发现。最近比较关注Go语言以及GO实现的一些分布式系统,因此将代码下载下来研究了一下。
2.10.2. 主要特点¶
- 类facebook haystack, 面向blob的对象存储
- Master-Worker架构。 Blob存储在物理volume, 一个worker上包含很多物理卷,这个物理卷 + 数据存放策略组成逻辑卷,Master管理这些逻辑卷
- Master使用raft协议保证无单点故障
- 灵活blob存放策略,支持数据中心+ 同数据中心不同机架+ 同数据中心同机架
2.10.3. 编译¶
安装依赖:
go get bazil.org/fuse/
go get github.com/disintegration/imaging/
go get github.com/goraft/raft/
go get github.com/gorilla/mux
go get github.com/rwcarlsen/goexif
go get github.com/syndtr/goleveldb
go get github.com/tgulacsi/go-cdb/
下载代码后编译
go get code.google.com/p/weed-fs/
go build go build code.google.com/p/weed-fs/go/weed
2.10.4. 搭建测试集群¶
首先启动master, 在启动volume server(数据中心dc1中, 机架rack1上两个节点, 机架rack2上一个几点。数据中心dc2上,机架rack3上一个节点)
# start weed master
./weed master > master.log 2>&1 &
# start weed volume server
mkdir -p demo/data1
./weed volume -dir=demo/data1 -max=5 -mserver=localhost:9333 -port=8080 -dataCenter=dc1 -rack=rack1 > node-1.log 2>&1 &
mkdir -p demo/data2
./weed volume -dir=demo/data2 -max=5 -mserver=localhost:9333 -port=8081 -dataCenter=dc1 -rack=rack1 > node-2.log 2>&1 &
# datanode in different rack, but same data center
mkdir -p demo/data3
./weed volume -dir=demo/data3 -max=5 -mserver=localhost:9333 -port=8082 -dataCenter=dc1 -rack=rack2 > node-3.log 2>&1 &
# datanode in different data center
mkdir -p demo/data4
./weed volume -dir=demo/data4 -max=5 -mserver=localhost:9333 -port=8083 -dataCenter=dc2 -rack=rack3 > node-4.log 2>&1 &
2.10.5. 简单测试¶
上传文件
- 分配文件ID. 文件ID = volume ID + file key + 校验码
$ curl http://localhost:9333/dir/assign
{"fid":"27,0498cb603b","url":"127.0.0.1:8081","publicUrl":"localhost:8081","count":1}
同时可以指定数据放置策略
$ curl http://localhost:9333/dir/assign?replication=011
{"fid":"20,05551858e0","url":"127.0.0.1:8081","publicUrl":"localhost:8081","count":1}
防止策略参见:https://code.google.com/p/weed-fs/wiki/RackDataCenterAwareReplication
- 上出文件
根据返回的文件ID,构造volume server上传地址,上传数据
$ curl -F @hello.txt http://127.0.0.1:8081/20,05551858e0
{"size": 43234}
下载文件
根据volume id, 从Master查询volume所在server地址
$ curl http://localhost:9333/dir/lookup?volumeId=20
{"volumeId":"20","locations":
[{"url":"127.0.0.1:8081","publicUrl":"localhost:8081"},
{"url":"127.0.0.1:8080","publicUrl":"localhost:8080"},
{"url":"127.0.0.1:8083","publicUrl":"localhost:8083"}
]
}
客户端可以根据返回volume server地址选择一个(如选择一个同数据中心,最近的)构造下载地址
$ curl http://127.0.0.1:8083/20,05551858e0
2.10.6. volume的一致性¶
一个逻辑卷有一个确定数据存放策略,根据存放策略,一个逻辑卷包含一个或者多个逻辑卷。 怎么保持这些逻辑卷的同步呢?
现在实现是同步协议。当请求发到一个volume server上之后, 这个server将数据在转发到这个逻辑卷的其他卷服务器上去,当数据在所有物理卷上都成功之后,才返回给客户端成功。
这个实现会造成: * 一个逻辑卷里面各个物理卷的数据不一致,某些卷里面会与脏数据. * 如果一个物理卷不可用的时候,整个逻辑卷都是不可写。
可以使用raft协议来世实现逻辑卷的一致性。