作者:對象存儲研發團隊
在介紹 QingStor 對象存儲內部的架構和設計原理之前,我們首先來了解一下對象存儲的概念。從外部視角看,對象存儲有什么特性,我們應該如何使用。
對象存儲本質上是一款存儲產品,與其他的存儲,如文件存儲、塊存儲,功能是類似的,主要的功能都是數據的讀和寫。 最大的不同在于 對象存儲是把數據作為對象進行管理 ,這是它最主要的特征,所有的數據在這里面都當做一個對象處理。
對象存儲有一些非常鮮明的特點:
結構是扁平的, 不像文件存儲那樣有目錄層級,在讀寫數據時不需要對目錄進行層層查找和打開。
對象存儲具備海量數據存儲的能力,這里的海量指的是不僅僅是幾百 GB 的量,而是說幾百 TB 甚至上 PB 的級別。
對象存儲適用于非結構化數據的存儲,非結構化具體指的是不對數據的類型和格式做任何假設,不管是簡單的文本,還是圖片、視頻、音頻都可以存在對象存儲里,當做對象來處理。
對象存儲通過 Restful 接口對外提供服務,也就是 HTTP 協議,這使得對象存儲的訪問非常方便,隨時隨地可以進行數據的上傳和下載。
1. 核心優勢
上面講的幾點是對象存儲產品所具備的通用特征,接下來介紹一下 QingStor 對象存儲獨有的核心優勢,主要包括三方面:
第一,對海量小文件這個場景,我們在存儲及 I/O 上都做了針對性的優化。
第二,QingStor 對象存儲的系統具有無限擴展的能力,當數據量、訪問量增加時,可以通過增加節點的方式提升計算和存儲能力。
第三,QingStor 對象存儲是數據存儲與流轉的平臺,從兩方面來體現:
首先, 所有功能的 API 都是開放的,可以通過任意調用 API 來完成業務邏輯。
其次, 提供一些非常有特色的功能,像生命周期管理、跨區域復制以及自定義回調等,可以適配更多的業務場景。
2. 全局數據模型
上圖是 QingStor 對象存儲的全局數據模型,可以理解成一個邏輯上的視圖。
這包括幾個主要概念:Global 是全局的意思,Global 由多個 Zone 組成,Zone 是區域的意思,可以把它理解成數據中心,例如在北京區域部署了一套對象存儲,同時在上海數據中心也部署了一套,這兩套對象存儲屬于同一個 Global。
QingStor 對象存儲在 Zone 級別和 Global 級別都有相應的管理服務。
Zone 由很多個 Bucket(存儲桶)組成,在使用對象存儲時,必須要先申請一個存儲桶,然后才能向存儲桶中上傳對象數據,以存儲桶為單位來存儲和管理對象數據。
在同一個 Zone 下面可以有很多個存儲桶,存儲桶里有各種各樣的對象數據,對象數據對類型大小沒有限制,單個存儲桶中對象的數量也沒有限制,可以無限量上傳對象數據。
3. 架構解析
這是 QingStor 對象存儲的后臺系統架構,這個架構圖經過了一些簡化和抽象。
首先是接入子系統,對象存儲提供的是在線服務,通過 Restful 進行訪問,本質上相當于在線服務的后臺,需要有接入子系統來完成接收請求、解析協議等工作。
在接入子系統下是索引子系統,索引子系統用來存儲和管理對象的元數據,元數據指的是對象的 Meta 信息,包括 Object 類型、大小、寫入時間之類的信息,由索引子系統管理。
存儲子系統負責存儲和管理數據實體本身,保證數據的可靠持久化存儲。
事件子系統主要工作是異步事件處理和分布式任務調度,它是生命周期管理等功能的底層機制。
圖中幾條實線箭頭顯示了數據的流向或者說是請求處理流程,請求從接入子系統下來,接入子系統會和索引子系統及存儲子系統交互,獲取元數據以及數據實體,這是核心的讀寫流程。
虛線表示在開啟了一些功能的情況下,可能會產生事件發送到事件子系統。這里有兩個虛線箭頭,一是讀寫流程中會觸發一些事件,會將事件發送至子系統;二是用戶可以主動提交一些事件,經過接入子系統進入事件子系統。
這幾個子系統構成了 QingStor 對象存儲后臺的主要模塊。
從這個架構圖來看,其內部實現并不是特別復雜。
QingStor 對象存儲是一款存儲產品,其核心功能是做數據的讀寫,邏輯上必然不能太復雜。
但是要把這個系統做好并不是那么容易,因為對象存儲主要應對的是海量數據的場景,在這個場景下有很多架構設計上的挑戰。
首先,數據都要做可靠的存儲、可靠的持久化,防止任何數據丟失;
第二,在訪問量很大的情況下,需要保證系統的持續服務能力;
第三,系統需要有良好的擴展性以應對不斷增加的數據量和請求量。
此外,QingStor 對象存儲是一個分布式系統,由多個節點共同協調提供服務,這種情況下,單個節點的故障是常有的,我們需要做到單個節點故障的情況下,保證服務的可用性以及數據的可靠存儲,這些都是在設計架構時需要重點考慮的問題。
接下來,依次來解讀這幾個子系統是如何實現的。
4. 子系統實現
在接入子系統中最重要是 Gateway 服務,Gateway 服務本質上是在后臺運行的 Server,它運行在網關節點上。
Gateway 服務的主要功能是接收上游發下來的請求,做協議解析以及數據處理與數據讀寫,對象存儲中最重要的數據讀寫功能基本在這里完成。
Gateway 服務本身是無狀態的,也就是請求被哪一個 Gateway 服務處理都是一樣的,因此 Gateway 可以非常輕松進行擴展,也就是服務實例的增加與減少。
從整體的鏈路上看一下接入層是如何保證高可用的。
用戶開始訪問對象存儲之前,會先訪問 DNS 服務器,通過對象存儲服務的域名拿到一個虛擬 IP 地址,這個虛擬 IP 會指向某一臺網關節點,如果這個節點故障了,虛擬 IP 會自動遷移到另外存活的節點上。
也就是 QingStor對象存儲可以保證用獲取到的 IP 永遠指向一個存活的節點,業務永遠是可用的。
在請求到達節點后,對象存儲會進一步做負載均衡,把請求分到多個節點的 Gateway 服務上。
當請求轉到一個 Gateway 上,發現這個 Gateway 出了問題,系統自動會將這個請求重新轉發,這是請求級別的Failover。
通過這兩個機制,QingStor 對象存儲可以保證訪問請求都可以得到響應。
此外,將 Gateway 實現為無狀態服務,可以非常方便地進行水平擴展,通過增加 Gateway 服務實例個數來頂住高并發的訪問量,保證服務可用。
接下來談談索引子系統的架構,索引子系統的主要功能是存儲和管理對象數據的元數據,元數據包括對象的類型、大小、寫入時間與存儲位置等信息。
這些信息是非常重要的,如果元數據丟失,數據本身就無法讀取,因此要保證元數據絕對安全可靠的存儲。
另一方面,海量數據的場景需要支撐海量數據的索引,索引子系統必須要能夠處理數據量不斷增大的情況。在此基礎之上還要盡可能提升系統的處理性能。
QingStor對象存儲是如何做到的?
首先通過數據分片的方式來應對海量數據。把數據按切片存儲,切片的意思是按照對象名稱字母序進行切片。比如第一個節點存 A-F 對象,第二個節點存 U-Z 對象,每一個節點會負責一個區間的數據,然后使用一個協調服務記錄節點及其所負責的區域對應關系。
通過這種方式,可以很方便地橫向擴展,如果 A-F 的對象數據太多,系統會把它拆成兩個,增加一個節點進來,將 A-F 拆分為 A-D,A-D 保留在原有的節點,D-F 放在新的節點,通過這種方式可以處理更多的數據,也提升了處理讀寫的能力。
添加新的節點通過協調服務進行,數據的拆分和再平衡過程是完全自動進行的。
QingStor 對象存儲的 Gateway 服務實時跟協調服務保持連接,可以獲取最新的數據分布情況。 通過這種分片存儲機制,保證了海量數據情況下可以通過增加節點的方式來提升存儲能力。
在數據安全可靠方面,QingStor 對象存儲采用副本機制, 每一份元數據都采用三副本方式進行存儲,如果有一個副本所在的機器發生故障,可以從其他的副本上讀取數據,在訪問的時候保證永遠可用。
如果數據所在節點發生變化,Gateway 會立即通過協調服務知道應該訪問哪個節點得到數據。此外,三副本都進行了持久化存儲,保證數據是安全可靠的。
QingStor 對象存儲在單個節點上存儲元數據時使用 KV 存儲引擎,KV 存儲引擎的索引結構是 LSM,LSM 索引結構最大的優勢是寫入非常快,可以提升系統的整體寫入性能。
除此之外,LSM 還有一個特點,它底層的數據在磁盤上存儲時是有序的,也就是一個個 sst 文件,可以提供高效的按順序查詢。
QingStor 對象存儲在處理列出存儲桶中對象的查詢接口時,可以很好的應用這個存儲特性,高效地將數據按字母序列出來。因為它本身是有序存儲,所以讀取速度非常快,接口處理非常高效,這是采用 KV 存儲的優勢。
總體來看 , QingStor對象存儲的索引子系統通過分片加協調服務的方式使其有很好的擴展性,同時通過副本保障數據的安全。
此外,在單個節點上采用 KV 存儲引擎提升寫入效率,同時支持 list 接口的高效查詢。
存儲子系統存的是對象數據本身,對象存儲應對的是海量場景,數據量非常大,而且會持續增加,訪問量也會非常大,而且有增加的可能性,因此架構的設計要保障系統可以不斷提升性能。此外,還需要保證數據的安全性和集群的穩定性。
QingStor 對象存儲在統一命名存儲空間下將存儲分成一個個存儲組,每個存儲組由各自的分布式文件系統組成。
采用存儲組設計的優勢主要包括三方面:
一是區分冷熱數據,也就是存儲分級,QingStor 對象存儲提供兩種存儲級別:低頻存儲和標準存儲。
標準存儲相對于低頻存儲來講,其訪問量高一些,數據量可能會少一些。
低頻存儲的數據量大,但訪問量會低一些。
針對兩種不同的存儲需求可以使用不同的存儲組,組和組之間是沒有關系的,因此不同的存儲組可以采用異構的硬件設備。對于低頻存儲,可以使用大容量的磁盤和低一點CPU的配置,進一步優化成本。
第二,采用存儲組可以使得集群擴展起來更加靈活方便,比如系統要進行擴容,如何做?
加一個存儲組即可,可以直接把新數據寫到新的存儲組中,不需要對歷史數據做移動和遷移等復雜操作。
QingStor 對象存儲同時支持另一種擴容方式,將既有數據遷移一部分到新存儲組上,使得整個集群比較均衡。
第三,采用存儲組具有故障隔離的效果。如果存儲組 1 出現節點的故障或者整個存儲組壞掉,對其他存儲組沒有影響,其他存儲組可以正常處理數據,具有故障隔離的效果。
在單個存儲組內,應用 QingStor 文件存儲的核心技術,采用三副本進行存儲,每次寫入數據,等到三副本寫入全部完成才會返回寫入成功,保證數據的強一致性和安全性。
本地文件系統直接和底層的塊設備打交道,省去了 Linux 本地文件系統,使得 I/O 處理在性能上的得到提升。
QingStor 對象存儲的數據傳輸采用 RDMA 高效傳輸協議,RDMA 是一種在不同的節點之間傳輸數據的機制,它不需要經過 CPU,直接通過硬件控制將數據從一個節點拷貝到另一個節點,和 CPU 的執行是并行的,是一種高效傳輸數據的方式。
事件子系統在 QingStor 對象存儲的架構中,不處于數據讀寫的核心流程上,但它提供了很多非常重要的功能,生命周期管理、跨區域復制以及自定義回調都是基于事件子系統來進行設計的。
事件子系統的基本邏輯比較簡單,產生事件和處理事件,這里事件可以理解成消息系統。
產生消息有兩條鏈路,一條鏈路在做數據讀寫時,當你完成一條數據的讀、寫入、刪除或者更新,索引子系統會產生事件,發送到事件子系統中;還有一條鏈路是用戶直接通過接入子系統提交一個事件,可以進入事件子系統中。
事件子系統有很多預置的消費者進程,消費者會處理事件,這些事件是通過分布式消息隊列保存的,消費者按照預設的邏輯讀取事件并對其進行處理。比如有一個消費者專門處理生命周期的功能,有一個消費者專門處理自定義回調的功能。