go語言實現分布式對象存儲系統之單體對象存儲


 

對象存儲

基本概念

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

  • NAS(文件存儲):Network Attached storage,提供了存儲功能和文件系統的網絡服務器,客戶端可以訪問NAS上的文件系統,還可以上傳和下載文件,使用協議:SMB、NFS以及AFS等網絡文件系統協議,對於客戶端來說就是網絡上的文件服務器。
  • SAN(塊存儲):Storage Area Network,和NAS的區別就是SAN只提供了塊存儲,而把文件系統抽象給客戶端來管理,使用協議:Fibre\Channel、iSCSI\ATA over Ethnet和HyperSCSI,對於客戶端來說就是一塊磁盤,可以對其格式化,創建文件系統並掛載。
  • 對象存儲:對象指的是面向對象,集合了塊存儲和文件存儲的優點,擁有訪問速度快、容量大等特性。並且容易搭配雲計算,是一種新的網絡存儲架構。

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

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

 

 

 

 

不同的數據管理方式

  • NAS,數據是以一個個文件的形式管理的。
  • SAN,數據是以數據塊的形式管理的,每個數據塊都有自己的地址,沒有額外的背景信息。
  • 對象存儲,數據是以對象的方式管理,一個對象包括:數據、元數據、全局標識符。
對象的數據通常是無結構的數據,比如:圖片、視頻或文檔等;對象的元數據則指的是對象的相關描述,比如:圖片的大小、文檔的擁有者等;對象id則是一個全局的唯一標識符,用來區分對象的。

 

不同的訪問數據方式

  • NAS,通過NFS等網絡協議訪問某個遠程服務器上存儲的文件
  • SAN,通過數據塊的地址訪問SAN上的數據塊
  • 對象存儲,通過REST網絡服務訪問對象
對象存儲,訪問對象的方式很方便,是通過REST接口對對象進行操作,用HTTP動詞(GET、POST、PUT、DELETE等)描述操作。除此之外,還有一種訪問方式,就是使用各大雲商提供的客戶端去操作對象。
比如:Amazon的s3cmd、阿里雲的osscmd/ossutil、騰訊雲的coscmd等。

  

 

對象存儲優缺點

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

  • 可擴展性高:對象存儲能夠擴展數十乃至數百EB的容量,能夠充分利用高密度存儲;
  • 效率高:扁平化結構,不受復雜目錄系統對性能的影響;
  • 無需遷移:對象存儲是一種橫向擴展系統,隨着容量的增加,數據根據算法自動分布於所有的對象存儲節點;
  • 安全性高:對象存儲通常憑借HTTP調用對象存儲本身提供的認證密鑰來提供數據訪問;訪問方便:不光支持HTTP(S)協議,采用REST的API方式調用和檢索數據,同樣增加了NFS和SMB支持;成本相對低:與塊存儲方式相比,對象存儲是最具成本效益的數據存儲類型,並且與雲計算搭配,把對象存儲的這一特性發揮的淋漓盡致。

再提缺點:

  • 最終一致性:由於不同節點的位置不同,數據同步時可能會有一定時間的延遲或者錯誤;
  • 不易做數據庫:對象存儲比較適合存儲那些變動不大甚至不變的文件,而對於像數據庫這種需要直接與存儲裸盤相互映射的應用,還是塊存儲更合適。

 

 

單體對象存儲架構實現

單體對象存儲架構

 

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語言實現第一章總結



免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM