seaweedfs源码阅读8-GET&HEAD获取文件过程

来源:互联网 发布:高仿手表知乎 编辑:程序博客网 时间:2024/06/05 20:52

GET 文件请求

http://127.0.0.1:8080/27542,10088ee11dccb9

先生成一个新的needle,然后根据fid:10088ee11dccb9 , 其中,前8位使用16进制转换为uint64 ==> key, 后6位使用16进制转换为uint32 ==> hash,解析结果给新生成的needle赋值,n.Id=key, n.Cookie=hash

如果当前的volumeServer没有找到请求的volumeId

if !vs.store.HasVolume(volumeId) {        if !vs.ReadRedirect {            glog.V(2).Infoln("volume is not local:", err, r.URL.Path)            w.WriteHeader(http.StatusNotFound)            return        }        lookupResult, err := operation.Lookup(vs.GetMasterNode(), volumeId.String())        glog.V(2).Infoln("volume", volumeId, "found on", lookupResult, "error", err)        if err == nil && len(lookupResult.Locations) > 0 {            u, _ := url.Parse(util.NormalizeUrl(lookupResult.Locations[0].PublicUrl))            u.Path = r.URL.Path            arg := url.Values{}            if c := r.FormValue("collection"); c != "" {                arg.Set("collection", c)            }            u.RawQuery = arg.Encode()            http.Redirect(w, r, u.String(), http.StatusMovedPermanently)        } else {            glog.V(2).Infoln("lookup error:", err, r.URL.Path)            w.WriteHeader(http.StatusNotFound)        }        return    }

在volume_read_write.go 中,调用readNeedle,通过已知的n.Id ,获取存储的needle信息,操作在needle_map_memory.go 中

func (nm *NeedleMap) Get(key uint64) (element *NeedleValue, ok bool) {    element, ok = nm.m.Get(Key(key))    return}
(dlv) p element*github.com/chrislusf/seaweedfs/weed/storage.NeedleValue {Key: 1050766, Offset: 1, Size: 529810}

与上传信息对比
上传时返回信息:
{“fid”:”27542,10088ee11dccb9”,”fileName”:”raft.pdf”,”fileUrl”:”127.0.0.1:8080/27542,10088ee11dccb9”,”size”:529766}
此时信息
{Key: 1050766, Offset: 1, Size: 529810}
存储时以needle为单位,增加的大小为needle中其他数据的大小,如n.Id,n.Cookie

获取数据

func (n *Needle) ReadData(r *os.File, offset int64, size uint32, version Version) (err error) {    bytes, block, err := ReadNeedleBlob(r, offset, size)    if err != nil {        return err    }    n.rawBlock = block    n.ParseNeedleHeader(bytes)    if n.Size != size {        return fmt.Errorf("File Entry Not Found. Needle %d Memory %d", n.Size, size)    }    switch version {    case Version1:        n.Data = bytes[NeedleHeaderSize : NeedleHeaderSize+size]    case Version2:        n.readNeedleDataVersion2(bytes[NeedleHeaderSize : NeedleHeaderSize+int(n.Size)])  // 从bytes中读取存储数据,并设置needle的属性    }    if size == 0 {        return nil    }    checksum := util.BytesToUint32(bytes[NeedleHeaderSize+size : NeedleHeaderSize+size+NeedleChecksumSize])    newChecksum := NewCRC(n.Data)    if checksum != newChecksum.Value() {        return errors.New("CRC error! Data On Disk Corrupted")    }    n.Checksum = newChecksum    return nil}
func (n *Needle) readNeedleDataVersion2(bytes []byte) {    index, lenBytes := 0, len(bytes)    if index < lenBytes {        n.DataSize = util.BytesToUint32(bytes[index : index+4])        index = index + 4        if int(n.DataSize)+index > lenBytes {            // this if clause is due to bug #87 and #93, fixed in v0.69            // remove this clause later            return        }        n.Data = bytes[index : index+int(n.DataSize)]        index = index + int(n.DataSize)        n.Flags = bytes[index]        index = index + 1    }    if index < lenBytes && n.HasName() {        n.NameSize = uint8(bytes[index])        index = index + 1        n.Name = bytes[index : index+int(n.NameSize)]        index = index + int(n.NameSize)    }    if index < lenBytes && n.HasMime() {        n.MimeSize = uint8(bytes[index])        index = index + 1        n.Mime = bytes[index : index+int(n.MimeSize)]        index = index + int(n.MimeSize)    }    if index < lenBytes && n.HasLastModifiedDate() {        n.LastModified = util.BytesToUint64(bytes[index : index+LastModifiedBytesLength])        index = index + LastModifiedBytesLength    }    if index < lenBytes && n.HasTtl() {        n.Ttl = LoadTTLFromBytes(bytes[index : index+TtlBytesLength])        index = index + TtlBytesLength    }}

总结

根据请求URL中带有的fid, 解析,得到n.Id, n.Cookie,其中,n.Id 作为needle的唯一标识,在NeedleMapper中找到存储的needle信息,n.Cookie 作为数据验证信息,若找到的needle中的cookie于URL中的cookie不一致,返回错误信息.

0 0
原创粉丝点击