对象存储 | 青训营笔记

225 阅读4分钟

这是我参与「第三届青训营 -后端场」笔记创作活动的第3篇笔记。

一.什么是对象存储

对象存储也叫做基于对象的存储,用来描述解决和处理离散单元的方法的通用术语,这些离散单元被称作对象。在对象存储中,数据与关联的元数据和唯一标识符捆绑在一起,以形成存储池。对象存储消除了文件存储中使用的分层文件结构,所有对象都在一个被称作存储池的扁平地址空间的同一级别里。每个对象都会被分配一个唯一的标识符,允许服务器或最终用户来检索对象而不必知道数据的物理地址。

二.为什么要有对象存储

1.海量数据场景下不同存储比较:

a.在海量数据存储情况下,单机存储和单机数据库都难以存下海量的数据。

b.分布式数据库虽在容量和弹性上有有很大的进展,但只适合存储结构化或半结构化的数据,要求数据和数据之间有一定的关联关系,且这些信息一般不超过KB级别。因而分布式存储更适合应对海量存储场景。

c.分布式文件系统HDFS同属于分布式存储,但其存储文件数量受Name Node限制,在易用性上存在提供的伪Posix文件接口开发略复杂无法直接HTTP访问、非云原生搭建维护较麻烦、视频图片相关生态接入略复杂的问题。

d.作为最后登场的主角,对象存储TOS支持海量存储在对象数量无限制。成本上同HDFS使用成本低的普通的X86服务器,但其具备冷热数据分级存储的能力在成本上更占优势。在易用性上其提供了Restful HTTP接口,开发使用起来更为简单;同时基于云原生搭建按需申请使用,减少搭建维护成本;对视频和图片相关生态丰富。

2.对象存储的优点总结

易用:提供Restful HTTP接口(GET HEAD PUT DELETE...)解放业务,让业务专注于业务逻辑开发。

海量:适用于存储海量的静态数据如图片、视频、备份等。

便宜:成本低,在大存储情况下节省宝贵的经费。

三.对象存储怎么用

1.首先上对象存储平台如字节的TOS、七牛云平台等,申请Bucket。

2.针对对象存储提供的Restful接口完成业务逻辑开发。

PUT:参数:Bucket, Key,对象内容 返回:成功/失败

GET:参数:Bucket, Key 返回: 对象内容

HEAD: Lite版GET 参数:Bucket, Key 返回:对象元信息,如大小/Content-Type等

DELETE:参数:Bucket,Key 返回:成功/失败

进阶模块:大文件分块上传、分页

对象存储上传接口.png

对象存储分页接口.png

四.TOS架构设计

对象存储架构设计.png

五.简单实践

准备:登陆注册七牛云存储平台,创建存储空间

配置文件go.mod中添加sdk: require github.com/qiniu/go-sdk/v7 v7.12.1

cmd更新依赖:go mod tidy

import (
    "fmt"
    "github.com/qiniu/go-sdk/v7/auth/qbox"
    "github.com/qiniu/go-sdk/v7/storage"
)
​
// 七牛云存储密钥配置
var (
    accessKey  = ""
    secretKey  = ""
    bucketName = ""   // 创建的空间名称
)
​
// UploadFileToObjectStore 输入要上传的文件地址,返回存储后的访问url地址
func UploadFileToObjectStore(toUploadFilePath string) (error, string) {
    // 上传成功的时候返回存储后的文件访问URL地址
    var fileUrlPath string// 根据操作系统自动判断分隔符
    sysType := runtime.GOOS
    var sysSpliter string
    if sysType == "windows" {
        sysSpliter = "\"
    } else {
        sysSpliter = "/"
    }
    // 分割文件路径获取要上传的文件名
    fileSlice := strings.Split(toUploadFilePath, sysSpliter)
    fileName := fileSlice[len(fileSlice)-1]
​
    bucket := bucketName
    putPolicy := storage.PutPolicy{
        Scope: bucket,
    }
    mac := qbox.NewMac(accessKey, secretKey)
    upToken := putPolicy.UploadToken(mac)
    cfg := storage.Config{}
    // 空间对应的机房
    cfg.Zone = &storage.ZoneHuanan
    // 是否使用https域名
    cfg.UseHTTPS = false
    // 上传是否使用CDN上传加速
    cfg.UseCdnDomains = true
    // 构建表单上传的对象
    formUploader := storage.NewFormUploader(&cfg)
    ret := storage.PutRet{}
    // 可选配置
    putExtra := storage.PutExtra{
        Params: map[string]string{
            "x:name": "github logo",
        },
    }
​
    // 上传文件
    if err := formUploader.PutFile(context.Background(), &ret, upToken, fileName, toUploadFilePath, &putExtra); err != nil {
        return err, fileUrlPath
    }
    fmt.Println("文件上传成功!")
    fmt.Println(ret.Key, ret.Hash)
​
    // 拼接返回文件的访问url地址
    var bt1 bytes.Buffer
    bt1.WriteString("")  // 填写七牛云提供的临时解析域名即外链
    bt1.WriteString(fileName)
    fileUrlPath = bt1.String()
    return nil, fileUrlPath
}