一个基于Golang的分布式存储开源项目

项目地址:https://code.google.com/p/weed-fs/

weed-fs是一个简单且高性能的分布式存储系统, 它有两个目标:

1、存储海量文件 2、快速访问所存的文件

weed-fs选择了 key~file 映射的方式实现文件寻址, 而不是POSIX文件系统已有的机制, 这有点类似于nosql系统, 你可以称之为“NoFS”

weed-fs的实现机制是管理volumes服务器, 而不是在一个中心阶段管理所有的元文件, volumes服务器可以管理文件及其元文件, 这种机制可以大大的缓解了中心节点的压力, 并且可以将元文件保存在volumes服务器的内存中, 而且文件自动采用Gzip 压缩 , 从而保证了文件的访问速度

weed-fs的理论模型可参考 Weed-FS models after Facebook's Haystack design paper. http://www.usenix.org/event/osdi10/tech/full_papers/Beaver.pdf

使用方式

weed-fs的master节点默认运行在9333端口,而volume节点运行在 8080 端口, 比如可以通过以下方式启动一个master节点和两个volume节点, 这里所有节点跑在localhost上, 但你可以跑在多台机器上

启动master节点 ./weed master

启动volume节点

 weed volume -dir="/tmp" -volumes=0-4 -mserver="localhost:9333" -port=8080 -publicUrl="localhost:8080" &
 weed volume -dir="/tmp/data2" -volumes=5-7 -mserver="localhost:9333" -port=8081 -publicUrl="localhost:8081" &

写文件

一个简单的保存文件的例子 curl http://localhost:9333/dir/assign {"fid":"3,01637037d6","url":"127.0.0.1:8080","publicUrl":"localhost:8080"}

第一步发送http GET请求获得文件的fid和volume服务器的url: curl -F file=@/home/chris/myphoto.jpg http://127.0.0.1:8080/3,01637037d6 {"size": 43234}

第二步发送http的 multipart POST请求(url+'/'+fid) 存储实际的文件

保存文件ID

你可以保存文件fid, 3,01637037d6到任何一个数据库中, 3表示volume服务器id,这是一个无符号的32位整型数字, 逗号后面的 01表示文件id,这是一个无符号的64位整型 ,最后的637037d6表示文件cookie, 它是一个无符号的32位整型, 用户保护url的安全访问 文件ID和cookie ID都是十六进制编码, 你可以按照你自己的格式对元组进行保存, 比如把fid当作字符串,理论上你需要 8+1+16+8=33 bytes个字节

读取文件

这里有一个如何根据url访问的例子

curl http://localhost:9333/dir/lookup?volumeId=3
{"Url":"127.0.0.1:8080","PublicUrl":"localhost:8080"}

首先通过volumeId查询 volume 服务器的url, 由于通常情况下, volume 服务器不会很多, 也不会经常变动,所以你可以缓存查询结果 现在你可以通过url从volume服务器上加载所需要的文件: http://localhost:8080/3,01637037d6.jpg

架构

对于大部分的分布式存储系统, 会把文件分成很多chunk, 中心节点保存文件名与chunk索引的映射,chunk索引中包含chunk server 和chunk handler等信息, 这种方式不能处理有效的处理大量的小文件,而且访问请求也会通过master节点, 在高并发的情况下, 响应会很慢。

在weed-fs中, 采用volumes server管理数据, 每个volume的大小为32GB,并且能够持有大量的文件,每个存储节点有多个volume节点,master节点只需要管理volume的元数据即可,而实际文件的元文件则储存在各个 volume 中, 每个元文件的大小为16 bytes,所有的文件访问均可在内存中处理,而硬盘操作仅仅是在实际的文件读取时才开始

Master Server and Volume Server

架构非常简单,实际数据存储在volumes里, 一个volume服务器包含多个volumes, 可同时支持读写操作,所有的volumes被 master server管理, master server包含了volume与volume server的映射关系,这种静态的对应关系可以很轻松的被缓存

对于每次的写请求, master server也会生成文件的key, 因为写没有读那么频繁, 所以一个master server可就可以应对大量的请求

读写文件

但客户端发出写请求, master server 返回 , 之后客户端想 volume 节点发出POST请求, 以REST的方式传送文件内容,当客户端需要读取文件, 它需要向master server或者缓存中获取, 最后用过public url获取内容

存储大小

在当前的设计中, 每个volume可以存储32GB的数据, 所以单个文件的大小是受制于volume的大小的, 但这个容量是可以在代码中调整的

内存储存

所有 volume server上的元文件信息是存储在内存中的, 而不需要从硬盘中读取, 每个元文件都是16字节大小的映射表

同类产品比较

HDFS的特点是分割大文件, 能很完美的读写大文件 WeedFS的特点是偏向于小文件, 追求更高的速度和并发能力

MogileFS有三层组件: tracers, database, storage nodes. WeedFS有两层组件:directory server, storage nodes. 多一层组件就意味着:很慢的访问、很复杂的操作以及更高的出错几率

GlusterFS是跟POSIX规范完全兼容的, 所以更复杂 WeedFS只有一部分兼容POSIX

Mongo's GridFS 采用MongoDB管理分隔后的chunks, 每次的读写请求都需要数据的查询元文件信息,对于少量请求是没有问题的, 但对于高并发的场景, 它很容易挂掉 WeedFS采用volume管理实际的数据, 查询任务分摊到各个volume节点, 所以很容易应对高负载的场景

你可能感兴趣的:(golang,go语言分布式,分布式)