作者:對(duì)象存儲(chǔ)研發(fā)團(tuán)隊(duì)
在介紹 QingStor 對(duì)象存儲(chǔ)內(nèi)部的架構(gòu)和設(shè)計(jì)原理之前,我們首先來了解一下對(duì)象存儲(chǔ)的概念。從外部視角看,對(duì)象存儲(chǔ)有什么特性,我們應(yīng)該如何使用。
對(duì)象存儲(chǔ)本質(zhì)上是一款存儲(chǔ)產(chǎn)品,與其他的存儲(chǔ),如文件存儲(chǔ)、塊存儲(chǔ),功能是類似的,主要的功能都是數(shù)據(jù)的讀和寫。 最大的不同在于 對(duì)象存儲(chǔ)是把數(shù)據(jù)作為對(duì)象進(jìn)行管理 ,這是它最主要的特征,所有的數(shù)據(jù)在這里面都當(dāng)做一個(gè)對(duì)象處理。
對(duì)象存儲(chǔ)有一些非常鮮明的特點(diǎn):
結(jié)構(gòu)是扁平的, 不像文件存儲(chǔ)那樣有目錄層級(jí),在讀寫數(shù)據(jù)時(shí)不需要對(duì)目錄進(jìn)行層層查找和打開。
對(duì)象存儲(chǔ)具備海量數(shù)據(jù)存儲(chǔ)的能力,這里的海量指的是不僅僅是幾百 GB 的量,而是說幾百 TB 甚至上 PB 的級(jí)別。
對(duì)象存儲(chǔ)適用于非結(jié)構(gòu)化數(shù)據(jù)的存儲(chǔ),非結(jié)構(gòu)化具體指的是不對(duì)數(shù)據(jù)的類型和格式做任何假設(shè),不管是簡單的文本,還是圖片、視頻、音頻都可以存在對(duì)象存儲(chǔ)里,當(dāng)做對(duì)象來處理。
對(duì)象存儲(chǔ)通過 Restful 接口對(duì)外提供服務(wù),也就是 HTTP 協(xié)議,這使得對(duì)象存儲(chǔ)的訪問非常方便,隨時(shí)隨地可以進(jìn)行數(shù)據(jù)的上傳和下載。
1. 核心優(yōu)勢

上面講的幾點(diǎn)是對(duì)象存儲(chǔ)產(chǎn)品所具備的通用特征,接下來介紹一下 QingStor 對(duì)象存儲(chǔ)獨(dú)有的核心優(yōu)勢,主要包括三方面:
第一,對(duì)海量小文件這個(gè)場景,我們?cè)诖鎯?chǔ)及 I/O 上都做了針對(duì)性的優(yōu)化。
第二,QingStor 對(duì)象存儲(chǔ)的系統(tǒng)具有無限擴(kuò)展的能力,當(dāng)數(shù)據(jù)量、訪問量增加時(shí),可以通過增加節(jié)點(diǎn)的方式提升計(jì)算和存儲(chǔ)能力。
第三,QingStor 對(duì)象存儲(chǔ)是數(shù)據(jù)存儲(chǔ)與流轉(zhuǎn)的平臺(tái),從兩方面來體現(xiàn):
首先, 所有功能的 API 都是開放的,可以通過任意調(diào)用 API 來完成業(yè)務(wù)邏輯。
其次, 提供一些非常有特色的功能,像生命周期管理、跨區(qū)域復(fù)制以及自定義回調(diào)等,可以適配更多的業(yè)務(wù)場景。
2. 全局?jǐn)?shù)據(jù)模型

上圖是 QingStor 對(duì)象存儲(chǔ)的全局?jǐn)?shù)據(jù)模型,可以理解成一個(gè)邏輯上的視圖。
這包括幾個(gè)主要概念:Global 是全局的意思,Global 由多個(gè) Zone 組成,Zone 是區(qū)域的意思,可以把它理解成數(shù)據(jù)中心,例如在北京區(qū)域部署了一套對(duì)象存儲(chǔ),同時(shí)在上海數(shù)據(jù)中心也部署了一套,這兩套對(duì)象存儲(chǔ)屬于同一個(gè) Global。
QingStor 對(duì)象存儲(chǔ)在 Zone 級(jí)別和 Global 級(jí)別都有相應(yīng)的管理服務(wù)。
Zone 由很多個(gè) Bucket(存儲(chǔ)桶)組成,在使用對(duì)象存儲(chǔ)時(shí),必須要先申請(qǐng)一個(gè)存儲(chǔ)桶,然后才能向存儲(chǔ)桶中上傳對(duì)象數(shù)據(jù),以存儲(chǔ)桶為單位來存儲(chǔ)和管理對(duì)象數(shù)據(jù)。
在同一個(gè) Zone 下面可以有很多個(gè)存儲(chǔ)桶,存儲(chǔ)桶里有各種各樣的對(duì)象數(shù)據(jù),對(duì)象數(shù)據(jù)對(duì)類型大小沒有限制,單個(gè)存儲(chǔ)桶中對(duì)象的數(shù)量也沒有限制,可以無限量上傳對(duì)象數(shù)據(jù)。
3. 架構(gòu)解析

這是 QingStor 對(duì)象存儲(chǔ)的后臺(tái)系統(tǒng)架構(gòu),這個(gè)架構(gòu)圖經(jīng)過了一些簡化和抽象。
首先是接入子系統(tǒng),對(duì)象存儲(chǔ)提供的是在線服務(wù),通過 Restful 進(jìn)行訪問,本質(zhì)上相當(dāng)于在線服務(wù)的后臺(tái),需要有接入子系統(tǒng)來完成接收請(qǐng)求、解析協(xié)議等工作。
在接入子系統(tǒng)下是索引子系統(tǒng),索引子系統(tǒng)用來存儲(chǔ)和管理對(duì)象的元數(shù)據(jù),元數(shù)據(jù)指的是對(duì)象的 Meta 信息,包括 Object 類型、大小、寫入時(shí)間之類的信息,由索引子系統(tǒng)管理。
存儲(chǔ)子系統(tǒng)負(fù)責(zé)存儲(chǔ)和管理數(shù)據(jù)實(shí)體本身,保證數(shù)據(jù)的可靠持久化存儲(chǔ)。
事件子系統(tǒng)主要工作是異步事件處理和分布式任務(wù)調(diào)度,它是生命周期管理等功能的底層機(jī)制。
圖中幾條實(shí)線箭頭顯示了數(shù)據(jù)的流向或者說是請(qǐng)求處理流程,請(qǐng)求從接入子系統(tǒng)下來,接入子系統(tǒng)會(huì)和索引子系統(tǒng)及存儲(chǔ)子系統(tǒng)交互,獲取元數(shù)據(jù)以及數(shù)據(jù)實(shí)體,這是核心的讀寫流程。
虛線表示在開啟了一些功能的情況下,可能會(huì)產(chǎn)生事件發(fā)送到事件子系統(tǒng)。這里有兩個(gè)虛線箭頭,一是讀寫流程中會(huì)觸發(fā)一些事件,會(huì)將事件發(fā)送至子系統(tǒng);二是用戶可以主動(dòng)提交一些事件,經(jīng)過接入子系統(tǒng)進(jìn)入事件子系統(tǒng)。
這幾個(gè)子系統(tǒng)構(gòu)成了 QingStor 對(duì)象存儲(chǔ)后臺(tái)的主要模塊。
從這個(gè)架構(gòu)圖來看,其內(nèi)部實(shí)現(xiàn)并不是特別復(fù)雜。
QingStor 對(duì)象存儲(chǔ)是一款存儲(chǔ)產(chǎn)品,其核心功能是做數(shù)據(jù)的讀寫,邏輯上必然不能太復(fù)雜。
但是要把這個(gè)系統(tǒng)做好并不是那么容易,因?yàn)閷?duì)象存儲(chǔ)主要應(yīng)對(duì)的是海量數(shù)據(jù)的場景,在這個(gè)場景下有很多架構(gòu)設(shè)計(jì)上的挑戰(zhàn)。
首先,數(shù)據(jù)都要做可靠的存儲(chǔ)、可靠的持久化,防止任何數(shù)據(jù)丟失;
第二,在訪問量很大的情況下,需要保證系統(tǒng)的持續(xù)服務(wù)能力;
第三,系統(tǒng)需要有良好的擴(kuò)展性以應(yīng)對(duì)不斷增加的數(shù)據(jù)量和請(qǐng)求量。
此外,QingStor 對(duì)象存儲(chǔ)是一個(gè)分布式系統(tǒng),由多個(gè)節(jié)點(diǎn)共同協(xié)調(diào)提供服務(wù),這種情況下,單個(gè)節(jié)點(diǎn)的故障是常有的,我們需要做到單個(gè)節(jié)點(diǎn)故障的情況下,保證服務(wù)的可用性以及數(shù)據(jù)的可靠存儲(chǔ),這些都是在設(shè)計(jì)架構(gòu)時(shí)需要重點(diǎn)考慮的問題。
接下來,依次來解讀這幾個(gè)子系統(tǒng)是如何實(shí)現(xiàn)的。
4. 子系統(tǒng)實(shí)現(xiàn)

在接入子系統(tǒng)中最重要是 Gateway 服務(wù),Gateway 服務(wù)本質(zhì)上是在后臺(tái)運(yùn)行的 Server,它運(yùn)行在網(wǎng)關(guān)節(jié)點(diǎn)上。
Gateway 服務(wù)的主要功能是接收上游發(fā)下來的請(qǐng)求,做協(xié)議解析以及數(shù)據(jù)處理與數(shù)據(jù)讀寫,對(duì)象存儲(chǔ)中最重要的數(shù)據(jù)讀寫功能基本在這里完成。
Gateway 服務(wù)本身是無狀態(tài)的,也就是請(qǐng)求被哪一個(gè) Gateway 服務(wù)處理都是一樣的,因此 Gateway 可以非常輕松進(jìn)行擴(kuò)展,也就是服務(wù)實(shí)例的增加與減少。
從整體的鏈路上看一下接入層是如何保證高可用的。
用戶開始訪問對(duì)象存儲(chǔ)之前,會(huì)先訪問 DNS 服務(wù)器,通過對(duì)象存儲(chǔ)服務(wù)的域名拿到一個(gè)虛擬 IP 地址,這個(gè)虛擬 IP 會(huì)指向某一臺(tái)網(wǎng)關(guān)節(jié)點(diǎn),如果這個(gè)節(jié)點(diǎn)故障了,虛擬 IP 會(huì)自動(dòng)遷移到另外存活的節(jié)點(diǎn)上。
也就是 QingStor對(duì)象存儲(chǔ)可以保證用獲取到的 IP 永遠(yuǎn)指向一個(gè)存活的節(jié)點(diǎn),業(yè)務(wù)永遠(yuǎn)是可用的。
在請(qǐng)求到達(dá)節(jié)點(diǎn)后,對(duì)象存儲(chǔ)會(huì)進(jìn)一步做負(fù)載均衡,把請(qǐng)求分到多個(gè)節(jié)點(diǎn)的 Gateway 服務(wù)上。
當(dāng)請(qǐng)求轉(zhuǎn)到一個(gè) Gateway 上,發(fā)現(xiàn)這個(gè) Gateway 出了問題,系統(tǒng)自動(dòng)會(huì)將這個(gè)請(qǐng)求重新轉(zhuǎn)發(fā),這是請(qǐng)求級(jí)別的Failover。
通過這兩個(gè)機(jī)制,QingStor 對(duì)象存儲(chǔ)可以保證訪問請(qǐng)求都可以得到響應(yīng)。
此外,將 Gateway 實(shí)現(xiàn)為無狀態(tài)服務(wù),可以非常方便地進(jìn)行水平擴(kuò)展,通過增加 Gateway 服務(wù)實(shí)例個(gè)數(shù)來頂住高并發(fā)的訪問量,保證服務(wù)可用。

接下來談?wù)勊饕酉到y(tǒng)的架構(gòu),索引子系統(tǒng)的主要功能是存儲(chǔ)和管理對(duì)象數(shù)據(jù)的元數(shù)據(jù),元數(shù)據(jù)包括對(duì)象的類型、大小、寫入時(shí)間與存儲(chǔ)位置等信息。
這些信息是非常重要的,如果元數(shù)據(jù)丟失,數(shù)據(jù)本身就無法讀取,因此要保證元數(shù)據(jù)絕對(duì)安全可靠的存儲(chǔ)。
另一方面,海量數(shù)據(jù)的場景需要支撐海量數(shù)據(jù)的索引,索引子系統(tǒng)必須要能夠處理數(shù)據(jù)量不斷增大的情況。在此基礎(chǔ)之上還要盡可能提升系統(tǒng)的處理性能。
QingStor對(duì)象存儲(chǔ)是如何做到的?
首先通過數(shù)據(jù)分片的方式來應(yīng)對(duì)海量數(shù)據(jù)。把數(shù)據(jù)按切片存儲(chǔ),切片的意思是按照對(duì)象名稱字母序進(jìn)行切片。比如第一個(gè)節(jié)點(diǎn)存 A-F 對(duì)象,第二個(gè)節(jié)點(diǎn)存 U-Z 對(duì)象,每一個(gè)節(jié)點(diǎn)會(huì)負(fù)責(zé)一個(gè)區(qū)間的數(shù)據(jù),然后使用一個(gè)協(xié)調(diào)服務(wù)記錄節(jié)點(diǎn)及其所負(fù)責(zé)的區(qū)域?qū)?yīng)關(guān)系。
通過這種方式,可以很方便地橫向擴(kuò)展,如果 A-F 的對(duì)象數(shù)據(jù)太多,系統(tǒng)會(huì)把它拆成兩個(gè),增加一個(gè)節(jié)點(diǎn)進(jìn)來,將 A-F 拆分為 A-D,A-D 保留在原有的節(jié)點(diǎn),D-F 放在新的節(jié)點(diǎn),通過這種方式可以處理更多的數(shù)據(jù),也提升了處理讀寫的能力。
添加新的節(jié)點(diǎn)通過協(xié)調(diào)服務(wù)進(jìn)行,數(shù)據(jù)的拆分和再平衡過程是完全自動(dòng)進(jìn)行的。
QingStor 對(duì)象存儲(chǔ)的 Gateway 服務(wù)實(shí)時(shí)跟協(xié)調(diào)服務(wù)保持連接,可以獲取最新的數(shù)據(jù)分布情況。 通過這種分片存儲(chǔ)機(jī)制,保證了海量數(shù)據(jù)情況下可以通過增加節(jié)點(diǎn)的方式來提升存儲(chǔ)能力。
在數(shù)據(jù)安全可靠方面,QingStor 對(duì)象存儲(chǔ)采用副本機(jī)制, 每一份元數(shù)據(jù)都采用三副本方式進(jìn)行存儲(chǔ),如果有一個(gè)副本所在的機(jī)器發(fā)生故障,可以從其他的副本上讀取數(shù)據(jù),在訪問的時(shí)候保證永遠(yuǎn)可用。
如果數(shù)據(jù)所在節(jié)點(diǎn)發(fā)生變化,Gateway 會(huì)立即通過協(xié)調(diào)服務(wù)知道應(yīng)該訪問哪個(gè)節(jié)點(diǎn)得到數(shù)據(jù)。此外,三副本都進(jìn)行了持久化存儲(chǔ),保證數(shù)據(jù)是安全可靠的。
QingStor 對(duì)象存儲(chǔ)在單個(gè)節(jié)點(diǎn)上存儲(chǔ)元數(shù)據(jù)時(shí)使用 KV 存儲(chǔ)引擎,KV 存儲(chǔ)引擎的索引結(jié)構(gòu)是 LSM,LSM 索引結(jié)構(gòu)最大的優(yōu)勢是寫入非常快,可以提升系統(tǒng)的整體寫入性能。
除此之外,LSM 還有一個(gè)特點(diǎn),它底層的數(shù)據(jù)在磁盤上存儲(chǔ)時(shí)是有序的,也就是一個(gè)個(gè) sst 文件,可以提供高效的按順序查詢。
QingStor 對(duì)象存儲(chǔ)在處理列出存儲(chǔ)桶中對(duì)象的查詢接口時(shí),可以很好的應(yīng)用這個(gè)存儲(chǔ)特性,高效地將數(shù)據(jù)按字母序列出來。因?yàn)樗旧硎怯行虼鎯?chǔ),所以讀取速度非常快,接口處理非常高效,這是采用 KV 存儲(chǔ)的優(yōu)勢。
總體來看 , QingStor對(duì)象存儲(chǔ)的索引子系統(tǒng)通過分片加協(xié)調(diào)服務(wù)的方式使其有很好的擴(kuò)展性,同時(shí)通過副本保障數(shù)據(jù)的安全。
此外,在單個(gè)節(jié)點(diǎn)上采用 KV 存儲(chǔ)引擎提升寫入效率,同時(shí)支持 list 接口的高效查詢。

存儲(chǔ)子系統(tǒng)存的是對(duì)象數(shù)據(jù)本身,對(duì)象存儲(chǔ)應(yīng)對(duì)的是海量場景,數(shù)據(jù)量非常大,而且會(huì)持續(xù)增加,訪問量也會(huì)非常大,而且有增加的可能性,因此架構(gòu)的設(shè)計(jì)要保障系統(tǒng)可以不斷提升性能。此外,還需要保證數(shù)據(jù)的安全性和集群的穩(wěn)定性。
QingStor 對(duì)象存儲(chǔ)在統(tǒng)一命名存儲(chǔ)空間下將存儲(chǔ)分成一個(gè)個(gè)存儲(chǔ)組,每個(gè)存儲(chǔ)組由各自的分布式文件系統(tǒng)組成。
采用存儲(chǔ)組設(shè)計(jì)的優(yōu)勢主要包括三方面:
一是區(qū)分冷熱數(shù)據(jù),也就是存儲(chǔ)分級(jí),QingStor 對(duì)象存儲(chǔ)提供兩種存儲(chǔ)級(jí)別:低頻存儲(chǔ)和標(biāo)準(zhǔn)存儲(chǔ)。
標(biāo)準(zhǔn)存儲(chǔ)相對(duì)于低頻存儲(chǔ)來講,其訪問量高一些,數(shù)據(jù)量可能會(huì)少一些。
低頻存儲(chǔ)的數(shù)據(jù)量大,但訪問量會(huì)低一些。
針對(duì)兩種不同的存儲(chǔ)需求可以使用不同的存儲(chǔ)組,組和組之間是沒有關(guān)系的,因此不同的存儲(chǔ)組可以采用異構(gòu)的硬件設(shè)備。對(duì)于低頻存儲(chǔ),可以使用大容量的磁盤和低一點(diǎn)CPU的配置,進(jìn)一步優(yōu)化成本。
第二,采用存儲(chǔ)組可以使得集群擴(kuò)展起來更加靈活方便,比如系統(tǒng)要進(jìn)行擴(kuò)容,如何做?
加一個(gè)存儲(chǔ)組即可,可以直接把新數(shù)據(jù)寫到新的存儲(chǔ)組中,不需要對(duì)歷史數(shù)據(jù)做移動(dòng)和遷移等復(fù)雜操作。
QingStor 對(duì)象存儲(chǔ)同時(shí)支持另一種擴(kuò)容方式,將既有數(shù)據(jù)遷移一部分到新存儲(chǔ)組上,使得整個(gè)集群比較均衡。
第三,采用存儲(chǔ)組具有故障隔離的效果。如果存儲(chǔ)組 1 出現(xiàn)節(jié)點(diǎn)的故障或者整個(gè)存儲(chǔ)組壞掉,對(duì)其他存儲(chǔ)組沒有影響,其他存儲(chǔ)組可以正常處理數(shù)據(jù),具有故障隔離的效果。
在單個(gè)存儲(chǔ)組內(nèi),應(yīng)用 QingStor 文件存儲(chǔ)的核心技術(shù),采用三副本進(jìn)行存儲(chǔ),每次寫入數(shù)據(jù),等到三副本寫入全部完成才會(huì)返回寫入成功,保證數(shù)據(jù)的強(qiáng)一致性和安全性。
本地文件系統(tǒng)直接和底層的塊設(shè)備打交道,省去了 Linux 本地文件系統(tǒng),使得 I/O 處理在性能上的得到提升。
QingStor 對(duì)象存儲(chǔ)的數(shù)據(jù)傳輸采用 RDMA 高效傳輸協(xié)議,RDMA 是一種在不同的節(jié)點(diǎn)之間傳輸數(shù)據(jù)的機(jī)制,它不需要經(jīng)過 CPU,直接通過硬件控制將數(shù)據(jù)從一個(gè)節(jié)點(diǎn)拷貝到另一個(gè)節(jié)點(diǎn),和 CPU 的執(zhí)行是并行的,是一種高效傳輸數(shù)據(jù)的方式。

事件子系統(tǒng)在 QingStor 對(duì)象存儲(chǔ)的架構(gòu)中,不處于數(shù)據(jù)讀寫的核心流程上,但它提供了很多非常重要的功能,生命周期管理、跨區(qū)域復(fù)制以及自定義回調(diào)都是基于事件子系統(tǒng)來進(jìn)行設(shè)計(jì)的。
事件子系統(tǒng)的基本邏輯比較簡單,產(chǎn)生事件和處理事件,這里事件可以理解成消息系統(tǒng)。
產(chǎn)生消息有兩條鏈路,一條鏈路在做數(shù)據(jù)讀寫時(shí),當(dāng)你完成一條數(shù)據(jù)的讀、寫入、刪除或者更新,索引子系統(tǒng)會(huì)產(chǎn)生事件,發(fā)送到事件子系統(tǒng)中;還有一條鏈路是用戶直接通過接入子系統(tǒng)提交一個(gè)事件,可以進(jìn)入事件子系統(tǒng)中。
事件子系統(tǒng)有很多預(yù)置的消費(fèi)者進(jìn)程,消費(fèi)者會(huì)處理事件,這些事件是通過分布式消息隊(duì)列保存的,消費(fèi)者按照預(yù)設(shè)的邏輯讀取事件并對(duì)其進(jìn)行處理。比如有一個(gè)消費(fèi)者專門處理生命周期的功能,有一個(gè)消費(fèi)者專門處理自定義回調(diào)的功能。






