Go 語言實現單體對象存儲

【導讀】對象存儲是什麼?本文介紹了對象存儲的基本概念並實現了一個單體對象存儲。

對象存儲

基本概念

主流存儲類型分爲三種:塊存儲、文件存儲以及對象存儲

對象存儲系統 (Object-Based Storage System) 是綜合了 NAS 和 SAN 的優點,同時具有 SAN 的高速直接訪問和 NAS 的數據共享等優勢,提供了高可靠性、跨平臺性以及安全的數據共享的存儲體系結構。

爲了更好的說明三者的差異,我打個比方,假設有三個人想從 A 地到 B 地,現在有三種交通方式。甲選擇轎車、乙選擇公共汽車、丙選擇地鐵。塊存儲類似於轎車,速度快,但是容量小(轎車只能乘坐幾個人);文件存儲類似於公共汽車,速度慢(公共汽車有站點和紅綠燈需要考慮),但是容量較大(能多坐不少人);對象存儲類似於地鐵,速度快,容量大。

不同的數據管理方式

對象的數據通常是無結構的數據,比如:圖片、視頻或文檔等;對象的元數據則指的是對象的相關描述,比如:圖片的大小、文檔的擁有者等;對象 id 則是一個全局的唯一標識符,用來區分對象的。

不同的訪問數據方式

對象存儲,訪問對象的方式很方便,是通過 REST 接口對對象進行操作,用 HTTP 動詞(GET、POST、PUT、DELETE 等)描述操作。除此之外,還有一種訪問方式,就是使用各大雲商提供的客戶端去操作對象。
比如:Amazon 的 s3cmd、阿里雲的 osscmd/ossutil、騰訊雲的 coscmd 等。

對象存儲優缺點

先說優點,之前大概也提了下:

再提缺點:

單體對象存儲架構實現

單體對象存儲架構

go 語言實現

package main

import (
 "io"
 "net/http"
 "os"
 "log"
 "strings"
)

func main() {
 http.HandleFunc("/objects/",Handler)
 println("server...")
 log.Fatal(http.ListenAndServe("127.0.0.1:8006", nil))
}

func Handler(w http.ResponseWriter, r  *http.Request){
 println(r)
 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){
 //C:\Users\Administrator\go\src\awesomeProject\test_file
 f,e := os.Create(("C:/Users/Administrator/go/src/awesomeProject/test_file"+"/objects/"+strings.Split(r.URL.EscapedPath(),"/")[2]))

 if e != nil {
  log.Println(e)
  w.WriteHeader(http.StatusInternalServerError)
  return
 }
 defer f.Close()
 io.Copy(f,r.Body)
}


func Get(w http.ResponseWriter,r *http.Request){

 f,e := os.Open(("C:/Users/Administrator/go/src/awesomeProject/test_file"+"/objects/"+strings.Split(r.URL.EscapedPath(),"/")[2]))

 if e != nil {
  log.Println(e)
  w.WriteHeader(http.StatusNotFound)
  return
 }
 defer f.Close()
 io.Copy(w,f)
}

詳解

main 函數,註冊一個 HTTP 處理函數並開始監聽端口。

http.HandleFunc的作用是註冊 HTTP 處理函數 Handler,如果由客戶端訪問本機的 HTTP 服務且以 “/objects/” 開頭,那麼請求將由 Handler 負責處理。

http.ListenAndServer正式監聽端口,正常情況下會一直監聽,非正常情況下,log.Fatal 會對於錯誤並退出程序。

http.HandleFunc("/objects/",Handler)
println("server...")
log.Fatal(http.ListenAndServe("127.0.0.1:8006", nil))

Handler 函數,HTTP 中最重要的請求和響應 Response,Request 爲參數,根據客戶端不同的請求方式,執行不同的處理函數:Put 函數與 Get 函數。

func Handler(w http.ResponseWriter, r  *http.Request){
 println(r)
 m := r.Method
 if m == http.MethodPut{
  Put(w,r)
  return
 }
 if m == http.MethodGet{
  Get(w,r)
  return
 }
 w.WriteHeader(http.StatusMethodNotAllowed)

}

Put 函數,r.URL 變量記錄 HTTP 請求的 URL,EscapedPath 方法用於獲取結果轉義以後的路徑部分,該路徑形式是:/objects/<object_name>,然後 strings.Split 函數功能是分割/objects/\<object\_name>,分割爲 "“、”objects"、<object_name>, 去數組的第三個元素就是<object_name>,os.Create 在本地文件系統的根存儲目錄創建同名文件 f,創建成功將 r.Body 用 io.Copy 寫入文件 f。

func Put(w http.ResponseWriter,r *http.Request){
 //C:\Users\Administrator\go\src\awesomeProject\test_file
 f,e := os.Create(("C:/Users/Administrator/go/src/awesomeProject/test_file"+"/objects/"+strings.Split(r.URL.EscapedPath(),"/")[2]))

 if e != nil {
  log.Println(e)
  w.WriteHeader(http.StatusInternalServerError)
  return
 }
 defer f.Close()
 io.Copy(f,r.Body)
}

Get 函數同 Put 函數類似。此文爲分佈式對象存儲 - 原理、架構及 Go 語言實現第一章總結

轉自:- 零

cnblogs.com/-wenli/p/11434347.html

本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源https://mp.weixin.qq.com/s/XD0gChDdCFCiU4fxtiFfow