一、前言

Snowflake是一款面向Amazon Cloud上EC2和S3而構建起來的在線數倉系統,支持極致彈性、多租戶、端到端安全、完整CRUD、事務、內置半結構化、無結構化數據等特性。從2012年開始設計開發,從2015年正式可用,到目前為止在Amazon Cloud上已經獲得了顯著的成功。就在2018年獲得7.13億美金的融資,總共獲得9.28億融資,估值從15億迅速上升到35億美金,營收翻4倍,其市場價值可見一斑!

Snowflake獲4.5億美元融資 估值達35億美元?

www.ebrun.com

Snowflake的成功還是有很多確定性因素的,其核心人員是資料庫領域的前輩,在此論文中也有提到說,他們團隊的資料庫開發經驗有100年以上(哪怕一人10年經驗,那也有10位這樣的核心人員了)。另外,從產品和技術上來看,Snowflake走出不一樣的道路,給我們有很多啟示,有很多很驚艷的點,我從自己的理解來回味下這篇論文。

二、架構選擇

Snowflake在設計之初就選擇了「存儲計算分離」的架構,在當時應該算是一招大膽而富有遠見的選擇,在2012年就開始基於EC2+S3來構建系統(也許,一開始並沒有這麼選擇),選擇信任底層AWS雲平台的基礎設施。這與當時的資料庫、數據倉庫的主流的做法有不小差異,因為基礎設施上無論是存儲、還是網路,性能上都不一定能滿足需求。

時至今日很多中小型公司都還沒完全相信雲計算,不願意搬遷自己的業務到雲上。對比同時期的阿里雲,那時才成立3年,整體才剛剛建設穩定,但顯然還不能做到存儲計算分離,公司都還沒有完全去IOE呢。

考慮到百G網路的到來,底層分散式文件系統不斷升級,延時不斷降低而吞吐大幅提升,基於遠程分散式塊存儲而構建嚴格語義與極致性能的資料庫系統,已經不是什麼新鮮事了,PolarDB和Aurora都已經證明。有同學測試過,基於網盤的資料庫與基於本地SSD的資料庫在性能上越來越接近了,在延時上還有些損失,但其他方面有一大堆的好處,光在自動擴容、高可靠、容災備份等複雜無比的問題上,就可以大大簡化並大量節省開發資源。

另外,選擇S3這種「Write-once」或「Append-only」的存儲作為其底層存儲,相比於傳統存儲有些劣勢,但也引入不少新特效和能力,因而在技術上也有很多變化,文件的組織方式、過期回收機制、mvcc機制、擴縮能力,都可以因地制宜。仔細想想,這與LSM的思路也有類似,從「In-place update」到「delete+add」,加快吞吐。

Snowflake另一個正確的選擇是「不選擇Hadoop」,在hadoop風口期卻沒有選擇hadoop,也是很有勇氣的。現在無論是阿里雲還是AWS,互動式的大數據分析又成為PB級數倉的選擇,Presto、F1 Query、包括我們自己的產品等,重新回歸傳統資料庫的體驗。因為底層基礎設施能力的提升和彈性能力讓上層資料庫服務也更加靈活,能適應於更寬泛的workload,因此Snowflake能同時支持和吸引了更多傳統數倉和傳統Hadoop的客戶。

三、技術實現

雖然底層選擇S3解決了很多的存儲問題,但在現階段延時問題還是存在的,另外像S3、阿里雲OSS這種對象存儲系統,除了在容量上收費,還有RPC調用也會收費(這部分費用不低)。因此,針對熱數據做本地SSD緩存+多級緩存是很自然的選擇。因為VirtualWarehouse單元是用戶級別的,所以這些熱數據緩存可以被Query級、進程級、EC2級、用戶級大量復用,從而極大的降低成本。

Snowflake選擇在多個VW間構建Consistent Hashing的緩存層,來管理S3上的表文件和對應node節點(真正的計算節點)之間的關係;同時優化器感知這個緩存層,在做物理執行計劃時,將query中的掃表運算元按表文件名分派到對應的node上,從而實現緩存的高命中率;同時,因為存儲計算分離+share data架構,計算上並不強耦合緩存層,所以node節點的增刪並不需要立即做緩存數據的shuffle,而是基於LRU,在多個後續Query中攤還的替換表文件,完成緩存層的Lazy Replacement,平滑過渡。

S3無限容量+數據多副本+分散式強一致等,還給Snowflake帶來更多紅利。比如,基於S3做Temp Table等中間計算數據Spill To Dis,且無限寫入,從而適配於workloads的多樣性。另外,也可以放棄傳統資料庫的Buffer Pool(聽一些大佬說,這是單機資料庫里最複雜的模塊之一了),

另一個有意思的問題是數據和計算傾斜的問題。VW的節點之間可能存在很大差異(比如同樣是4core8G,但可能底層的CPU性能不一樣),同一個Query中分配給多個process之間的TableScan運算元真正的工作負載也不一定均衡(比如一個SQL需要掃描一個超大的表,包含了大量的Partition文件,優化器如果按照文件數來做分片切分出多個PartitionTableScan運算元,很可能這些運算元拿到相同的文件數量但真正要處理的位元組數差異巨大),導致SQL整體執行上的嚴重長尾效應。Snowflake提出了file stealing的思想,與Work stealing相似,和Java的ForkJoinPool做法類似,竊取同一個query中其他node上分配到的表文件掃描任務,經過同意後轉移所有權,從而快速達到自平衡。

同時,Snowflake這套純SaaS化體驗的架構又與現在雲平台上主推的「容器化」、「ServerLess「、「Pay-as-you-go」等主流趨勢不謀而合。用戶完全不需要關心集群有多大,有多少機器,只需要根據自己的「性能需求」和「價格意願」而選擇VirtualWarehouse的尺寸即可,就像買T恤一樣非常寬鬆、簡單的規格;面向用戶的CloudService和面向數據的Storage,完全實現彈性伸縮、按量計費,用戶開通完服務,通過系統分配的Endpoint就可以「拎包入住」了(打個小廣告,目前我們團隊開發的Data Lake Analytics,也是朝這個方向來努力的??)。

在優化器和執行計劃方面,Snowflake放棄了索引(我猜想因為選擇了S3作為底層存儲,畢竟是對象存儲,不能像傳統資料庫那樣的方式來實現ACID,自然索引也不例外),失去了一些自主可控力,也收穫一些別的能力。比如文中提到的「執行計劃搜索空間的減少」,還有更容易實現的MVCC機制,time-travel功能等。傳統索引更適合於事務處理,而分析處理更注重大塊數據的拖取和計算,良好的文件編碼格式(orc,parquet等)和充分的壓縮,以及文中提到的文件級別的剪枝優化(min-max,data skipping,zone map等),這些文件級別的剪枝優化佔用空間很小,且都可以下推到文件上快速過濾數據,反而比傳統面向TP的全局索引更適合於AP處理(這是我收益很大的地方,固化的思路以為所有資料庫場景都需要索引,在自己工作中也在設想全局索引的方案,這給我很大的啟發)。

關於計算下推,這種文件級別的剪枝優化還有很多優點,比如佔用空間小,維護簡單,可以全量參與非常複雜的表達式計算。傳統資料庫的索引列如果在表達式或函數內,那就沒辦法直接使用,或者維護更加複雜的函數索引或表達式索引,而min-max、bitmap等可以直接參与很多表達式計算,只要這些表達式也符合一些約束(單調性、連續性等),這大大提升了靈活性和數據剪枝效率。同時這些剪枝優化還可以用於多表join時替代傳統資料庫的統計信息的作用,無需單獨維護性能直方圖、數據分部等統計數據。

四、安全性

Snowflake是把安全作為基礎能力而設計的。相比而言,國內的產品在這方面弱多了,之前聽公司另一個同事分享關於「差分隱私」的話題,才意識到我們的產品在用戶數據安全和用戶隱私方面的思考有多麼缺乏。國外的市場和法律對雲平台的用戶數據安全有著異常嚴苛的要求,GDPR就說明這一切。目前阿里雲的產品,也都要完成一系列的安全設計評審,安全功能開發(完成GDPR規範要求,引入KMS來管理密鑰等)和最終安全審計才能上線。我們也正一步步的向更規範的目標靠攏。

本文中也提到了,Snowflake從計算鏈路的端到端,以及數據存儲上兩方面來構建其安全體系。設計出一套多層次的key加密體系,為這些加密key設計生命周期,通過key rotation來持續更新key,通過rekey來持續更新數據,最頂層key則利用硬體加密(比如阿里雲上的KMS服務)來維護。雖然這套體系不難理解,但真的感嘆他們對安全的重視!

五、總結

自己閱讀這篇論文最大的感受是:雲計算真的是顛覆性的,對資料庫、數倉系統以及其他各種PaaS、SaaS服務在設計和實現上的顛覆。相比過去,基於雲計算來開發資料庫、中間件等產品的門檻越來越低,雲計算確實更大程度的解放開發同學,讓他們更專註於真正面向用戶的特性上。我們DLA也是一樣,借力於雲計算以及CloudNative的生態,我們可以更多的思考和實現用戶的差異化需求了。

斷斷續續寫了很久時間,終於在回家的路上完成了。祝大家新年快樂!祝DLA能有機會服務於更多的客戶!


推薦閱讀:
相关文章