zoukankan      html  css  js  c++  java
  • 分布式对象存储 读书笔记(三) 元数据

    上节的代码无法区分同一个对象的不同版本,为了记录对象版本以及其他一些元数据,本节中会加入一个新组件:元数据服务

    元数据服务就是提供对元数据的存取功能的服务。元数据指的是对象的描述信息,比如对象的名字、版本、大小以及散列值.

    新增加服务后的结构图如下

    需要新安装一个ElasticSearch搜索引擎。安装过程可自行百度

    ElasticSearch搜索引擎中,我们需要定义这样一个映射。

    '{"mappings":{"objects":{"properties":{"name":{"type":"string","index":"not_analyzed"},"version":{"type":"integer"},"size":{"type":"integer"},"hash":{"type":"string"}}}}}'

    ES的索引相当于数据库而类型相当于数据库的表,映射则相当于定义表结构。该索引只有一个类型就是objects,包括4个属性分别是name,version,size和hash

    接口服务代码添加了versions访问处理函数

    1 func main() {
    2     go heartbeat.ListenHeartbeat()
    3     http.HandleFunc("/objects/", objects.Handler)
    4     http.HandleFunc("/locate/", locate.Handler)
    5     http.HandleFunc("/versions/", versions.Handler)
    6     log.Fatal(http.ListenAndServe(os.Getenv("LISTEN_ADDRESS"), nil))
    7 }
    View Code

    version处理函数仅处理Get请求

    调用ES的API进行version查询最后返回

     1 func Handler(w http.ResponseWriter, r *http.Request) {
     2     m := r.Method
     3     if m != http.MethodGet {
     4         w.WriteHeader(http.StatusMethodNotAllowed)
     5         return
     6     }
     7     from := 0
     8     size := 1000
     9     name := strings.Split(r.URL.EscapedPath(), "/")[2]
    10     for {
    11         metas, e := es.SearchAllVersions(name, from, size)
    12         if e != nil {
    13             log.Println(e)
    14             w.WriteHeader(http.StatusInternalServerError)
    15             return
    16         }
    17         for i := range metas {
    18             b, _ := json.Marshal(metas[i])
    19             w.Write(b)
    20             w.Write([]byte("
    "))
    21         }
    22         if len(metas) != size {
    23             return
    24         }
    25         from += size
    26     }
    27 }
    View Code

    OBJECT处理函数中 添加了DELETE处理

    在ES中添加新版本,数据为0 ,哈希为"",表示删除操作

    OBJECT处理函数中 PUT操作没有较大改变 但是添加了在ES中记录元数据的代码

    OBJECT处理函数中 GET操作会根据version查询ES 获取元数据 才开始获取对象数据 

     1 func get(w http.ResponseWriter, r *http.Request) {
     2     name := strings.Split(r.URL.EscapedPath(), "/")[2]
     3     versionId := r.URL.Query()["version"]
     4     version := 0
     5     var e error
     6     if len(versionId) != 0 {
     7         version, e = strconv.Atoi(versionId[0])
     8         if e != nil {
     9             log.Println(e)
    10             w.WriteHeader(http.StatusBadRequest)
    11             return
    12         }
    13     }
    14     meta, e := es.GetMetadata(name, version)
    15     if e != nil {
    16         log.Println(e)
    17         w.WriteHeader(http.StatusInternalServerError)
    18         return
    19     }
    20     if meta.Hash == "" {
    21         w.WriteHeader(http.StatusNotFound)
    22         return
    23     }
    24     object := url.PathEscape(meta.Hash)
    25     stream, e := getStream(object)
    26     if e != nil {
    27         log.Println(e)
    28         w.WriteHeader(http.StatusNotFound)
    29         return
    30     }
    31     io.Copy(w, stream)
    32 }
    33 
    34 func put(w http.ResponseWriter, r *http.Request) {
    35     hash := utils.GetHashFromHeader(r.Header)
    36     if hash == "" {
    37         log.Println("missing object hash in digest header")
    38         w.WriteHeader(http.StatusBadRequest)
    39         return
    40     }
    41 
    42     c, e := storeObject(r.Body, url.PathEscape(hash))
    43     if e != nil {
    44         log.Println(e)
    45         w.WriteHeader(c)
    46         return
    47     }
    48     if c != http.StatusOK {
    49         w.WriteHeader(c)
    50         return
    51     }
    52 
    53     name := strings.Split(r.URL.EscapedPath(), "/")[2]
    54     size := utils.GetSizeFromHeader(r.Header)
    55     e = es.AddVersion(name, hash, size)
    56     if e != nil {
    57         log.Println(e)
    58         w.WriteHeader(http.StatusInternalServerError)
    59     }
    60 }
    View Code

    实操验证

    开启 rabbitmq ES 设置ES映射

    开启 apiserver dataserver

    使用curl 上传一个test3对象  这时候会显示400 bad request。 因为没提供test3 对象的散列值 

    先计算对象的哈希值的 然后再添加哈希PUT一次

    OK!!

    作 者: itdef
    欢迎转帖 请保持文本完整并注明出处
    技术博客 http://www.cnblogs.com/itdef/
    B站算法视频题解
    https://space.bilibili.com/18508846
    qq 151435887
    gitee https://gitee.com/def/
    欢迎c c++ 算法爱好者 windows驱动爱好者 服务器程序员沟通交流
    如果觉得不错,欢迎点赞,你的鼓励就是我的动力
    阿里打赏 微信打赏
  • 相关阅读:
    Atitit js nodejs下的进程管理wmic process进程管理
    Atitit 提取sfit特征点,并绘制到原图上
    Atitit 局部图查找大图 方法 与 说明
    Atitit java读取tif文件为空null的解决 图像处理
    Aititi 特征点检测算法与匹配的前世今生与历史传承attilax总结v4
    Atitit it行业图像处理行业软件行业感到到迷茫的三大原因和解决方案
    Atitit js nodejs 图像处理压缩缩放算法 attilax总结
    Atitit 2017年第68界机器视觉图像处理学术大会会议记要attilax总结自建学院自颁学位理论
    Atitit nodejs js 获取图像分辨率 尺寸 大小 宽度 高度
    Atitit 图像处理之编程之类库调用的接口api cli gui ws rest  attilax大总结.docx
  • 原文地址:https://www.cnblogs.com/itdef/p/9608289.html
Copyright © 2011-2022 走看看