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

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

X-Engine的Data Block無需原地更新,可以方便使用通用壓縮算法(zlib,zstd,snapy等)壓縮。所有位于LSM-tree低層次的數據都會默認壓縮。經過大量對比測試,X-Engine默認選用了ZSTD壓縮算法,但同時也保留了對其他算法的支持。此外后臺compaction會持續刪除無效記錄(LSM-Tree更新和刪除都是寫入新記錄,舊版本記錄不再被需要時,視為無效),持續釋放冗余的空間。因為上述技術特點,X-Engine對存儲空間的節省幾乎到達了“變態”的程度,以至于當圖片空間庫的數據全部從InnoDB轉移到X-Engine后,空間節省了7倍,如下圖所示

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