分布式对象存储笔记 | 青训营笔记
这是我参与「第四届青训营 」笔记创作活动的的第10天。
首先认识存储:传统网络存储和对象存储
1.1 传统网络存储(如图):
NAS和SAN并不是完全对立的,在现代的网络存储中通常都是两者混用,可以同时提供文件级别的协议和块级别的协议。
1.1.1 对象存储的数据管理方式(网络存储和对象存储的区别)
对象的元数据是对象的描述信息(如歌的歌名,照片的拍摄时间等等)。
对象的标识符用于引用该对象(通常会用对象的散列值来做其标识符)。
1.1.2 访问数据的方式
1.1.3 对象存储的优势
a.提升了存储系统的扩展性。
b.以更低的代价提供了数据冗余的能力。
1.2 单机版对象存储的架构
1.2.1 REST接口
单机版的REST接口极其简单,只实现了PUT和GET方法。
1.2.2 对象PUT流程
客户端的GET请求提供了<object_name>,我们的服务进程从本地磁盘上的文件$STORAGE_ROOT/object/<object_name>中读取对象并将其写入HTTP响应正文。
1.3 GO语言实现
package DFS
import (
"io"
"log"
"net/http"
"os"
"strings"
)
func main() {
http.HandleFunc("/objects/", objects.Handler)
log.Fatal(http.ListenAndServe(os.Getenv("LISTEN_ADDRESS"), nil))
}
func Handler(w http.ResponseWriter, r *http.Request) { //*表示指针变量
m := r.Method //=是赋值而:=是声明变量并赋值
if m == http.MethodPut {
put(w, r)
return
}
if m == http.MethodGet {
get(w, r)
return
}
w.WriteHeader(http.StatusMethodNotAllowed)
}
func put(w http.ResponseWriter, r *http.Request) {
f, e := os.Create(os.Getenv("STORAGE_ROOT") + "/object/" + strings.Split(r.URL.EscapedPath(), "/")[2]) //os是GO语言中提供的操作系统函数的接口,是一个比较重要的包。 顾名思义,os 包的作用主要是在服务器上进行系统的基本操作,如文件操作、目录操作、执行命令、信号与中断、进程、系统状态等等。
if e != nil {
log.Println(e)
w.WriteHeader(http.StatusInternalServerError)
return
}
defer f.Close() //defer是Go语言中的延迟执行语句,用来添加函数结束时执行的代码,常用于释放某些已分配的资源、关闭数据库连接、断开socket连接、解锁一个加锁的资源。 Go语言机制担保一定会执行defer语句中的代码。
io.Copy(f, r.Body)
}
func get(w http.ResponseWriter, r *http.Request) {
f, e := os.Open(os.Getenv("STORAGE_ROOT") + "/object/" + strings.Split(r.URL.EscapedPath(), "/")[2])
if e != nil {
log.Println(e)
w.WriteHeader(http.StatusNotFound)
return
}
defer f.Close()
io.Copy(w, f)
}