數據庫內核雜談(十六):Snowflake Elastic Data Warehouse

{"type":"doc","content":[{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","marks":[{"type":"strong"}],"text":"本文是數據庫內核系列文章之一。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"link","attrs":{"href":"https:\/\/www.infoq.cn\/article\/QYSiGFujIXZVQjZvb8BG","title":"","type":null},"content":[{"type":"text","text":"上一期"}]},{"type":"text","text":"介紹了執行器的兩種主流的實現來提升性能:code-gen(代碼生成)和vec-exec(向量計算)。這期的內容,介紹一個實現了vec-exec的商用數據倉庫系統,Snowflake。除了使用了vec-exec(畢竟,聯合創始人Marcin的博士畢業論文就是關於vec-exec的),Snowflake也是一款100%計算和存儲分離,面向雲原生的數據倉庫系統(是不是第一個我不敢確認,還請大家查證,留言給我)。本文內容主要參考他們發表於SIGMOD-16的paper: The Snowflake Elastic Data Warehouse。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"Snowlake是2012年成立的,2015年正式推出商用版本。2012年,正是雲服務起步不久,大數據熱火朝天的時候。當時,數據倉庫的主流趨勢是SQL On Hadoop。Cloudera, Hontornworks, MapR, Greenplum HAWQ,  Facebook的Presto,算是百花齊放。但主創團隊認爲,RDBMS不會消失,用戶們會因爲上雲的趨勢,想要一款完全適配雲端的數據倉庫。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"簡介"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"文章簡單介紹了市面上通常的on-prem分佈式數據倉庫的一些缺點。首先就是計算和存儲硬件是耦合的,即每個服務器同時負責存儲數據,並且執行SQL語句得到結果。耦合的劣勢在於,不能針對不同的workloads做優化。二就是服務器的node membership改變(無論是因爲服務器損壞,或者是因爲數據量提升需要擴容)對用戶來說都不友善。一,就是要進行大量數據的reshuffle。二是,爲了做到高可用,可能會保留一部分node作爲stand-by replica,當主節點有問題時,馬上接替主節點,這相當於變相提高了數據成本。總結來說,on-prem的數據倉庫要做到同時保持可伸縮性(elasticity)和高可用性(availability)併兼顧成本,是很難魚與熊掌兼得的。三就是對服務進行升級比較麻煩。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於雲服務的出現,很多上述的問題,變得不再是問題了。一就是,雲服務通常會提供多種類型的服務器來針對特定的usecase;二,服務器的下線,上線,擴容在雲服務上都屬於基本操作;三是,雲上有高可用,低成本的存儲系統;四是,服務更新非常方便。基於這些原因,Snowflake選擇了完完全全的計算和存儲分離的架構設計。整個架構分成三個大模塊:"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"1)數據存儲:完全交給AWS的S3來存儲數據。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2)Virtual Warehouse(VW) 虛擬數據倉庫實例(下面簡稱VW):由多個Virtual Node(AWS中的EC2 instance)組成的一個Virtual Cluster,負責執行各種SQL語句,因此稱爲Virtual Warehouse。數據庫的執行引擎是也是自己構建的分佈式引擎。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"3)Cloud Services:整個Snowflake的大腦:負責管理數據存儲和VW,以及其他一系列的操作,比如安全,登陸,事物管理,用戶隔離,等等。值得注意的是,你可以大致認爲整個AWS,所有的用戶,共享這一個大腦實例(當然,這個實例本身是多中心複製,高可用加高備份的),但每個用戶只能管理屬於自己的數據和VW。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"數據存儲"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"在設計存儲系統的時候,Snowflake有糾結過,是應該使用AWS的S3,還是自行設計類似於HDFS的存儲系統。最終,在經過了各種比較,利弊權衡後,決定使用S3。雖然,S3的性能並不是最快;並且,由於是網絡接入,也不是最穩定。但是,勝在高可用性和高可靠性上。團隊決定基於S3打造數據存儲系統,同時,可以把精力放在優化local caching和數據傾斜(skew resilience)上。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"相對於本地文件系統,S3的access latency會更高,並且,由於是網絡接入(尤其是用https),CPU使用率也更高。而且,S3本身就是一個簡單的blob存儲,支持的主要創建,刪除和讀取文件,即,不能對現有文件進行更新,更新相當於重新創建一個更新過的文件。但是,S3的讀取有一大好處在於,可以讀取部分文件。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"S3的這些屬性,對於整個Snowflake的數據存儲和並行控制設計有重大的影響。首先,表數據被水平(horizontally partitioned)地切分成多個不可變的blob文件;每個文件通過列存(column-store)的形式保存數據,Snowflake具體使用的存儲格式是PAX的Hybrid-column store(挖個坑,可以單獨講一期這個)。每個數據文件包含數據頭用來存儲元數據。基於S3的下載部分文件的API,對於運行的SQL語句,優化器會選擇只下載必須用到的數據block即可。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"值得一提的是,Snowflake不單單使用S3來存儲表數據文件,也用S3來存儲臨時生成的intermediate result(語句執行中,某個operator產生的臨時結果集)。一旦這些結果集的大小超過了本地磁盤空間,spill到磁盤上的文件就會以S3的形式存儲。這樣的好處在於,可以讓Snowflake真正可以處理巨大的數據而不用擔心內存或者本地磁盤空間喫緊。另一個好處在於,這些臨時結果集也可能被利用作爲cache使用。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"最後文中還提到了數據庫的其他元數據存儲,包括有哪些caching文件,每個表存在了哪些S3文件中,等等,都是存儲在一個transactional的key-value store中,並不在S3裏。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"虛擬數據倉庫實例(Virtual Warehouse)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"VW就是一個由多個EC2 instance(文中稱這些instance爲worker node,以下簡稱WN)組成的的分佈式數據庫實例。並且,可以根據workload的需求,選擇不同的體量(Snowflake提到是用T-shirt size來劃分,從X-S到XX-L)。VW本身單單是作爲計算引擎存在,是無狀態的,所有的數據文件都在S3上,所有的metadata都在key-values上。因此,Snowflake建議,如果沒有查詢語句,可以把VW給關了,來節省成本。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"執行SQL語句:每個語句instance都只會運行在一個VW上;每個VW有多個WN;每個WN只隸屬於一個VW,不會被共享。(這邊有註解說,WN變成共享的會是一個未來的工作,因爲可以更好地提升使用率並且會進一步降低用戶成本)。當一個語句被運行時,所有的WN在這個VW上,(或者也可能是一部分WN,如果優化器認爲這是一個非常輕量級的語句),都會起一個worker process,這個進程的生命週期就是這句語句的執行週期。worker process ,在執行的過程中,不會對外部資源造成任何變化,換言之,no side effect,即使是update語句。爲什麼這麼說呢,因爲所有的表數據文件都是immutable的。這樣帶來的好處就是,如果worker process 由於各種原因崩潰了, 通常只是需要retry即可,沒有其他善後事宜要做。現在VW裏還不支持partial retry,這也在未來計劃的工作中。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"每個用戶可以同時擁有幾個VW實例,並且這些VW還分別同時運行多個語句。VW通過S3共享數據文件。這裏S3的優勢就體現出來了,幾乎無限的存儲空間,使得用戶可以查詢,整合所有的數據。同時,用戶可以通過構建多個VW的形式,對不同類型的語句進行分類,使得彼此之間互相不會影響。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"由於VW的可伸縮性(elasticity),通常情況下,可以通過起一個更大size的VW來提升語句的性能,但保持一樣的使用成本。例如,   一個複雜的分析語句在一個4節點VW上需要運行15個小時,但在一個32節點VW上只需要2小時。因爲是雲原生,用戶只需要支付運行VW時的費用即可。因此,在價格不變的情況下,用戶體驗和查詢速度卻大幅度提升。這也是Snowflake雲原生數據倉庫的一大賣點。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"本地緩存: 每個WN都會用本地文件爲表數據做本地緩存,即已經被從S3那讀取的數據文件。這些文件是包含元數據信息和要用到的column的數據。這些緩存的數據文件可以被多個worker process共享(如果需要讀取一樣的數據),文中提到維護了一個簡單的LRU的cache replacement策略,效果非常不錯。爲了進一步提升hit rate,同一份數據文件被多個WN節點保存,優化器會用consistent hashing算法,來分配哪些節點保存哪些數據。同時,對於後續要讀取對應數據的語句,優化器也會根據這個分配發送到對應節點。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"數據傾斜處理:一些節點可能相對於其他節點,運行更慢,比如硬件問題或者是單純網絡問題。Snowflake的優化是,每個WN在讀取了相應的數據文件後,當它發現其他WN還在讀取,他會發送請求給其他WN要求分擔更多的數據,而且這些數據直接從S3讀取。從而來確保不要把過多的數據處理放在速度慢的WN上。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"執行引擎:雖說可以通過增加節點來提升性能,但是Snowflake依然希望每一個節點的單體性能都能做到極致。因此,Snowflake構建了自己的,基於列存,向量執行(vec-exec),並且是push-based(推模式)的執行引擎。Columnar: 沒啥爭議,對於OLAP語句來說,Columnar-store無論從存儲,讀取效率和執行效率來說,都優於row-store。Vec-exec:也沒有爭議,Marcin肯定把Vec-Exec這套運行優化放到執行器上。push-based: 相對於Volcano的拉模式,是下方的operator,當處理完數據後,把數據push到上方的operator(從執行計劃角度來看上下),類似於code-gen,這樣的好處是提高了cache的利用率,因爲可以避免不必要的循環控制語句。另一點就是,一些其他傳統數據庫系統在執行語句時需要考慮的麻煩,對於Snowflake來說沒有。比如,不用transaction management,因爲所有的語句都是沒有side effect的。"}]},{"type":"heading","attrs":{"align":null,"level":2},"content":[{"type":"text","text":"Cloud Services(VW大腦)"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"相對於VW的無狀態即插即用,Cloud Services (以下簡稱CS)是一個長期在線的,有狀態的大腦。它管理,協調着所有的用戶請求,數據存儲,VW的生成,停止,接入控制, 優化器, 元數據,等等,並且是對所有用戶共享的。CS相當於是Snowflake提供SAAS對於用戶的單點接入。當然,不同用戶之間是不知道對方的存在的。實現方面,CS的所有組件都是有多備份,並且可以做到多數據中心複製,用來保證高可用和高性能。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"至此,所有的組件都介紹過了,下圖也清晰地展現了整個Snowflake SAAS架構。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"image","attrs":{"src":"https:\/\/static001.geekbang.org\/infoq\/e0\/e0db8eab207f6e9dc333bc624b0fcd3d.png","alt":null,"title":null,"style":[{"key":"width","value":"75%"},{"key":"bordertype","value":"none"}],"href":null,"fromPaste":true,"pastePass":true}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"正是依託了雲服務的高可用和可伸縮性,Snowflake提供了100%SAAS的雲原生數據倉庫服務,對於用戶而言,只需要支付數據存儲費用,以及即插即用的VW的費用。主創團隊真的很有眼光,堅信雲原生的數據庫會有自己的市場,而當時大紅大紫的SQL On Hadoop,已經沒有太大聲音了。如今Snowflake已經成功上市(截止2021年2月12日,市值高達:84.78 Billion)。今天的內容就到這,歡迎閱讀。"}]},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null}},{"type":"paragraph","attrs":{"indent":0,"number":0,"align":null,"origin":null},"content":[{"type":"text","text":"2021 年的願景之一是做更多對於技術和管理的輸出,如果想要和我更多交流,歡迎關注我的知識星球:"},{"type":"link","attrs":{"href":"https:\/\/t.zsxq.com\/feEUfay","title":"","type":null},"content":[{"type":"text","text":"Dr.ZZZ 聊技術和管理"}]},{"type":"text","text":"。"}]}]}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章