1.圖片空間數(shù)據(jù)庫(kù)存儲(chǔ)成本暴漲
圖片空間是淘寶智能圖片中心面向商家提供的免費(fèi)圖片存儲(chǔ)管理服務(wù),由于淘寶、天貓主站上累積的用戶圖片數(shù)據(jù)量非常大(想想淘寶/天貓的商家和消費(fèi)者每天要上傳多少圖片!),并且增長(zhǎng)量驚人,圖片空間業(yè)務(wù)面臨著非常巨大的存儲(chǔ)空間和寫(xiě)入性能壓力。尤其每年雙11之前,商家大量更新商品庫(kù)存保有單位SKU(Stock keeping Unit),此時(shí)數(shù)據(jù)會(huì)急劇增長(zhǎng)。

淘寶/天貓每日新增大量商品、評(píng)論圖片某年雙十一前夕,當(dāng)時(shí)阿里大部分?jǐn)?shù)據(jù)庫(kù)系統(tǒng)還使用的是InnoDB存儲(chǔ)引擎,圖片空間的研發(fā)同學(xué)梳理雙十一線上風(fēng)險(xiǎn)時(shí),咨詢到DB磁盤(pán)及水位的容量是否足夠,我們?cè)攀牡┑┑卣f(shuō):“沒(méi)有問(wèn)題,四個(gè)月前我們剛擴(kuò)了一倍機(jī)器”。可是沒(méi)過(guò)多久就被現(xiàn)實(shí)打臉了:不到5個(gè)月的時(shí)間,業(yè)務(wù)數(shù)據(jù)累積了過(guò)去6-7年的量,每日增量急劇上升,擴(kuò)容的磁盤(pán)很快也將不夠了。
2.解決方案,擴(kuò)容還是換引擎?
為什么選擇新引擎
最簡(jiǎn)單粗暴的方法當(dāng)然是擴(kuò)容,這樣做風(fēng)險(xiǎn)最小,但卻只能解決眼前的問(wèn)題。以現(xiàn)在數(shù)據(jù)的膨脹速度,未來(lái)難免多次擴(kuò)容。僅僅因?yàn)榭臻g不足的問(wèn)題,導(dǎo)致成本翻好幾倍,這是難以接受的。另外一個(gè)方法是換引擎,當(dāng)時(shí)阿里主打高性能低成本的自研存儲(chǔ)引擎X-Engine剛剛成熟(TODO:X-ENGINE架構(gòu)超鏈接),相較于基于B+-Tree的存儲(chǔ)引擎(例如InnoDB)數(shù)據(jù)頁(yè)存在較多空間浪費(fèi),基于LSM-Tree的X-Engine數(shù)據(jù)完全緊湊排列,空間利用率更高。而緊湊排列的數(shù)據(jù)施以前綴壓縮技術(shù),空間使用進(jìn)一步減少。

X-Engine的Data Block無(wú)需原地更新,可以方便使用通用壓縮算法(zlib,zstd,snapy等)壓縮。所有位于LSM-tree低層次的數(shù)據(jù)都會(huì)默認(rèn)壓縮。經(jīng)過(guò)大量對(duì)比測(cè)試,X-Engine默認(rèn)選用了ZSTD壓縮算法,但同時(shí)也保留了對(duì)其他算法的支持。此外后臺(tái)compaction會(huì)持續(xù)刪除無(wú)效記錄(LSM-Tree更新和刪除都是寫(xiě)入新記錄,舊版本記錄不再被需要時(shí),視為無(wú)效),持續(xù)釋放冗余的空間。因?yàn)樯鲜黾夹g(shù)特點(diǎn),X-Engine對(duì)存儲(chǔ)空間的節(jié)省幾乎到達(dá)了“變態(tài)”的程度,以至于當(dāng)圖片空間庫(kù)的數(shù)據(jù)全部從InnoDB轉(zhuǎn)移到X-Engine后,空間節(jié)省了7倍,如下圖所示

如何做到降低7倍成本
為什么數(shù)據(jù)從InnoDB遷移至X-Engine后,取得了如此巨大的成本收益?
- 首先,InnoDB采用B+-Tree索引數(shù)據(jù),伴隨著數(shù)據(jù)寫(xiě)入,樹(shù)的節(jié)點(diǎn)不停地分裂合并,導(dǎo)致定長(zhǎng)的數(shù)據(jù)頁(yè)長(zhǎng)期處于“半滿”狀態(tài),空間存在浪費(fèi)。而X-Engine的更新刪除操作,都是追加寫(xiě)到內(nèi)存memtable,不會(huì)更改磁盤(pán)上的數(shù)據(jù),因此這些靜態(tài)數(shù)據(jù)可以緊湊的排列,不用為未來(lái)的寫(xiě)入預(yù)留空間,空間利用率很高。雖然追加寫(xiě)會(huì)產(chǎn)生冗余的多版本數(shù)據(jù),X-Engine后臺(tái)Compaction操作往往可以及時(shí)地清理無(wú)用的多版本數(shù)據(jù)。
- 其次,圖片空間庫(kù)存儲(chǔ)了大量的圖片元信息(例如user_id、圖片地址URL等),這些信息有一個(gè)特點(diǎn):相鄰數(shù)據(jù)之間相似度非常高,例如同一個(gè)user_id往往對(duì)應(yīng)多個(gè)圖片地址,圖片地址URL之間的前綴十分相似。X-Engine的前綴壓縮機(jī)制保證:相鄰key的相同前綴,盡量只存儲(chǔ)一次。因此包含圖片元信息的二級(jí)索引,經(jīng)過(guò)前綴壓縮,所占空間很少。
- 最后,主表的key雖然不能使用前綴壓縮,但通用壓縮算法,面對(duì)圖片元信息記錄中大量相似的文本字符(URL等),也能大顯身手,取得理想的壓縮比率。InnoDB雖然也支持?jǐn)?shù)據(jù)頁(yè)壓縮,且對(duì)靜態(tài)數(shù)據(jù)有較好的壓縮比率,但是隨著數(shù)據(jù)寫(xiě)入,B+-Tree持續(xù)分裂合并,空間很快就會(huì)膨脹起來(lái)。X-Engine靜態(tài)的數(shù)據(jù)頁(yè),不存在這個(gè)問(wèn)題。
性能表現(xiàn)依然優(yōu)異
此外,由于圖片空間是一個(gè)高頻使用的應(yīng)用,如果X-Engine的性能不滿足要求,也無(wú)法落地。得益于LSM輕量化寫(xiě)機(jī)制,X-Engine寫(xiě)入操作本就是優(yōu)勢(shì),何況還引入了group commit和事務(wù)處理流水線機(jī)制,大大增加了寫(xiě)入處理的并發(fā)度。讀請(qǐng)求本是LSM的弱項(xiàng),分層的結(jié)構(gòu)和追加寫(xiě)產(chǎn)生的多版本數(shù)據(jù),會(huì)增加讀請(qǐng)求查詢路徑的長(zhǎng)度,X-Engine為此做了大量的優(yōu)化,諸如:多粒度Cache(memtable,Block Cache和Row Cache)、bloomfilter和range scan filter(Surf, SIGMOD'18)有效減少點(diǎn)查詢和范圍掃描的次數(shù)、異步I/O預(yù)取等,盡力把它打造成讀寫(xiě)性能均衡,成本優(yōu)勢(shì)突出的存儲(chǔ)引擎。關(guān)于X-Engine讀寫(xiě)優(yōu)化,可以參考這篇文章(TODO:超鏈接)。
經(jīng)過(guò)DBA和業(yè)務(wù)開(kāi)發(fā)同學(xué)的驗(yàn)證,X-Engine的讀寫(xiě)性能及延時(shí)完全滿足業(yè)務(wù)需求。很快,淘寶圖片空間庫(kù)全部切換為X-Engine引擎,節(jié)省了大量的存儲(chǔ)成本。
3.X-Engine適合什么樣的業(yè)務(wù)
X-Engine分層存儲(chǔ)的架構(gòu),特別適合具有如下業(yè)務(wù)負(fù)載特征的業(yè)務(wù):
- 庫(kù)表數(shù)據(jù)量特別大,對(duì)成本敏感的業(yè)務(wù)。傳統(tǒng)InnoDB引擎遷移到X-Engine后,依據(jù)數(shù)據(jù)特征不同,存儲(chǔ)空間可降低2倍~10倍。遷移到X-Engine之后,很多業(yè)務(wù)可以免除分庫(kù)分表的需求,使用單庫(kù)即可承載近10TB的數(shù)據(jù)存儲(chǔ)服務(wù)。例如:X-Engine在釘釘?shù)膽?yīng)用。
- 數(shù)據(jù)訪問(wèn)具有鮮明的時(shí)間特征。例如大部分讀取及修改操作集中在最近寫(xiě)入的數(shù)據(jù)上,而歷史數(shù)據(jù)較少被訪問(wèn)(例如淘寶交易庫(kù)(超鏈接))。X-Engine新寫(xiě)入的數(shù)據(jù)通過(guò)高效的內(nèi)存索引緩存,訪問(wèn)性能極高,而較少訪問(wèn)的歷史數(shù)據(jù)保存在磁盤(pán),提供稍遜的讀寫(xiě)性能。例如:X-Engine在淘寶交易庫(kù)的應(yīng)用。