背景
Facebook是一家資料驅動的公司。 資料處理和分析是Facebook為10億多活躍使用者開發和交付產品的核心所在。 我門擁有世界上最大的資料倉儲之一,儲存了大約 300PB 以上的資料。 這些資料被一系列不同種類的程式所使用, 包括傳統的資料批處理程式、基於圖論的資料分析[1]、機器學習、和實時性的資料分析。
分析人員、資料科學家和工程師需要處理資料、分析資料、不斷地改善我們的產品, 對於這些人來說, 提高資料倉儲的查詢效能是非常重要的。在一定時間內能夠執行更多的查詢並且能夠更快地獲得查詢結果能夠提高他們的工作效率。
Facebook資料倉儲中的資料儲存在幾個大型的Hadoop HDFS的叢集上。 Hadoop MapReduce[2]和Hive被設計為用於進行大規模、高可靠性的計算,而且這些技術都被優化為用來提高整體系統的吞吐量。但是當我們的資料倉儲增長到PB級別,並且我們的需求進一步提升的時候, 我們就非常需要一個在資料倉儲上工作的,能夠提供低延遲的互動式查詢系統。
在2012年秋天,Facebook 資料基礎設施(Data Infrastructure)部門的一支團隊開始為我們的資料倉儲的使用者解決這個問題。我們評估了一些外部專案, 發現這些專案或者是太不成熟,或者就是不能滿足我們在靈活性和規模性上的要求。 所以我們決定開始搭建Presto,一個嶄新的能夠在PB級別的資料上進行互動式查詢的系統。
在這篇文章中,我們將簡單地介紹Presto的架構、現狀和前景。
架構
Presto是一個分散式SQL查詢引擎, 它被設計為用來專門進行高速、實時的資料分析。它支援標準的ANSI SQL,包括複雜查詢、聚合(aggregation)、連線(join)和視窗函式(window functions)。
下面的架構圖中展現了簡化的Presto系統架構。客戶端(client)將SQL查詢傳送到Presto的協調員(coordinator)。協調員會進行語法檢查、分析和規劃查詢計劃。計劃員(scheduler)將執行的管道組合在一起, 將任務分配給那些裡資料最近的節點,然後監控執行過程。 客戶端從輸出段中將資料取出, 這些資料是從更底層的處理段中依次取出的。
Presto的執行模型和Hive或MapReduce有著本質的區別。Hive將查詢翻譯成多階段的MapReduce任務, 一個接著一個地執行。 每一個任務從磁碟上讀取輸入資料並且將中間結果輸出到磁碟上。 然而Presto引擎沒有使用MapReduce。它使用了一個定製的查詢和執行引擎和響應的操作符來支援SQL的語法。除了改進的排程演算法之外, 所有的資料處理都是在記憶體中進行的。 不同的處理端通過網路組成處理的流水線。 這樣會避免不必要的磁碟讀寫和額外的延遲。 這種流水線式的執行模型會在同一時間執行多個資料處理段, 一旦資料可用的時候就會將資料從一個處理段傳入到下一個處理段。 這樣的方式會大大的減少各種查詢的端到端響應時間。
Presto系統是用Java來實現的, 主要原因是Java的開發效率高,且擁有非常好的生態環境, 並且很容易同Facebook資料基礎設施的其他Java應用進行整合。Presto會將查詢計劃中的一部分動態地編譯成JVM位元組程式碼,並讓JVM優化和生成原生的機器程式碼。 通過謹慎地使用記憶體和資料結構,Presto避免了通常Java程式會碰到的記憶體分配和垃圾收集(Java garbage collection)的問題。(在後一篇文章中, 我們會分享一些在開發高效能Java系統的時候的一些提示和技巧,以及我們在搭建Presto系統時的一些經驗教訓。)
擴充套件性是在設計Presto時的另一個要點。在專案的早期階段, 我們就意識到出了HDFS之外,大量資料會被儲存在很多其他型別的系統中。 其中一些是像HBase一類的為人熟知的系統,另一類則是象Facebook New Feed一樣的定製的後臺。Presto設計了一個簡單的資料儲存的抽象層, 來滿足在不同資料儲存系統之上都可以使用SQL進行查詢。儲存外掛(聯結器,connector)只需要提供實現以下操作的介面, 包括對後設資料(metadata)的提取,獲得資料儲存的位置,獲取資料本身的操作等。除了我們主要使用的Hive/HDFS後臺系統之外, 我們也開發了一些連線其他系統的Presto 聯結器,包括HBase,Scribe和定製開發的系統。
(譯者注:Scribe是Facebook的開源專案,可以實時的將大量伺服器產生的日誌檔案彙總到檔案系統中, 詳見:https://github.com/facebook/scribe)
(譯者注: 從目前的資訊來看,Presto的架構在分散式處理資料的方式和基於MapReduce 2.0的HorntonWorks的Stinger有著很大的不同,可能會比較接近於Google的Dremel或者Cloudera的Impala。 )
現狀
正如上面所介紹的, Presto的開發是從2012年的秋天開始的。 在2013年早期的時候我門的第一個生產系統開始執行。 在2013年春天的時候這個系統推廣到了Facebook的整個公司。從那是起, Presto成為了公司內在資料倉儲上進行互動式分析的主要系統。 它被部署到了多個不同的地區,而且我們成功地將一個叢集擴充套件到了1000個節點。 超過1000名以上的員工在日常工作中使用這個系統, 他們每天在一個PB的資料上會執行超過30,000個查詢。
Presto在CPU的效能和主要的查詢效能上比Hive/MapReduce要好10倍以上。它目前支援ANSI SQL的大部分操作, 包括連線、 左/右外連線、 子查詢、以及通用的聚合和標量函式, 同時也包含了一些近似的去重(使用了 HyperLogLog)和近似的百分數(基於quantile digest演算法,)計算。目前階段的主要限制是在表連線時候的大小限制以及唯一鍵值和群組的基數(cardinality of unique keys/groups)。目前系統沒有能力將查詢結果回寫到特定的表中(目前查詢結果會直接通過流輸出的方式返回給客戶端)。
(譯者注:對大資料進行特定操作的時候會用到一些使用統計方法的近似演算法。HyperLogLog演算法時用來估計大量資料中特定值出現次數的,具體可以看這篇博文。Quantile Digest演算法及具體應用可以看這篇博文。)
展望
我們在積極努力地擴充套件Presto的功能以及提供效能。 在接下來的幾個月中,我們會去除查詢中連線和聚合的大小限制,同時我們將提供將查詢結果寫入輸出表的功能。 我們同時在開發一個查詢加速器。主要是設計一種為查詢處理優化的新的資料格式來避免不必要的資料轉換。 這些新的特性會將後臺資料倉儲中經常使用的資料集合快取起來, 系統會有效地使用這些快取資料來加速查詢的速度,而不需要讓使用者知道快取機制的存在。 我們同時也在開發一個高效能的HBase聯結器(HBase connector)。
開源
2013年6月的Analytics @ WebScale大會上, 我們第一次介紹了Presto。在那之後,它吸引了許多外界對它的關注。在最近的幾個月中, 我們已經將Presto的原始碼和可執行包釋出給了一些外界的公司。他們已經在他們自己的環境中成功地進行了部署和測試的工作, 並且給了我們很好的反饋。
今天我們非常高興宣佈我們將Presto變成開源專案。 你可以在以下的網站上找到原始碼和文件。 我將非常樂意從你這裡瞭解到你的用例,以及Presto可以怎樣幫到你的互動式分析。
Preston 官網:http://prestodb.io/
Preston Github 主頁:https://github.com/facebook/presto
Facebook資料基礎設施的Presto團隊由以下成員組成, Martin Traverso, Dain Sundstrom, David Phillips, Eric Hwang, Nileema Shingte 以及Ravi Murthy.
連結
[1] Scaling Apache Giraph to a trillion edges. https://www.facebook.com/notes/facebook-engineering/scaling-apache-giraph-to-a-trillion-edges/10151617006153920
[2] Under the hood: Scheduling MapReduce jobs more efficiently with Coronahttps://www.facebook.com/notes/facebook-engineering/under-the-hood-scheduling-mapreduce-jobs-more-efficiently-with-corona/10151142560538920
[3] Video of Presto talk at Analytics@Webscale conference, June 2013https://www.facebook.com/photo.php?v=10202463462128185