Presto:非死book的分布式SQL查詢引擎
背景
非死book 是一家數據驅動的公司。 數據處理和分析是 非死book 為 10 億多活躍用戶開發和交付產品的核心所在。 我門擁有世界上最大的數據倉庫之一,存儲了大約 300PB 以上的數據。 這些數據被一系列不同種類的程序所使用, 包括傳統的數據批處理程序、基于圖論的數據分析[1]、機器學習、和實時性的數據分析。
分析人員、數據科學家和工程師需要處理數據、分析數據、不斷地改善我們的產品, 對于這些人來說, 提高數據倉庫的查詢性能是非常重要的。在一定時間內能夠運行更多的查詢并且能夠更快地獲得查詢結果能夠提高他們的工作效率。
非死book 數據倉庫中的數據存儲在幾個大型的 Hadoop HDFS 的集群上。 Hadoop MapReduce[2]和 Hive 被設計為用于進行大規模、高可靠性的計算,而且這些技術都被優化為用來提高整體系統的吞吐量。但是當我們的數據倉庫增長到 PB 級別,并且我們的需求進一步提升的時候, 我們就非常需要一個在數據倉庫上工作的,能夠提供低延遲的交互式查詢系統。
在 2012 年秋天,非死book 數據基礎設施(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 的開發效率高,且擁有非常好的生態環境, 并且很容易同 非死book 數據基礎設施的其他 Java 應用進行集成。Presto 會將查詢計劃中的一部分動態地編譯成 JVM 字節代碼,并讓 JVM 優化和生成原生的機器代碼。 通過謹慎地使用內存和數據結構,Presto 避免了通常 Java 程序會碰到的內存分配和垃圾收集(Java garbage collection)的問題。(在后一篇文章中, 我們會分享一些在開發高性能 Java 系統的時候的一些提示和技巧,以及我們在搭建 Presto 系統時的一些經驗教訓。)
擴展性是在設計 Presto 時的另一個要點。在項目的早期階段, 我們就意識到出了 HDFS 之外,大量數據會被存儲在很多其他類型的系統中。 其中一些是像 HBase 一類的為人熟知的系統,另一類則是象 非死book New Feed 一樣的定制的后臺。Presto 設計了一個簡單的數據存儲的抽象層, 來滿足在不同數據存儲系統之上都可以使用 SQL 進行查詢。存儲插件(連接器,connector)只需要提供實現以下操作的接口, 包括對元數據(metadata)的提取,獲得數據存儲的位置,獲取數據本身的操作等。除了我們主要使用的 Hive/HDFS 后臺系統之外, 我們也開發了一些連接其他系統的 Presto 連接器,包括 HBase,Scribe 和定制開發的系統。
(譯者注:Scribe 是 非死book 的開源項目,可以實時的將大量服務器產生的日志文件匯總到文件系統中, 詳見:https://github.com/非死book/scribe)
(譯者注: 從目前的信息來看,Presto 的架構在分布式處理數據的方式和基于 MapReduce 2.0 的 HorntonWorks 的 Stinger 有著很大的不同,可能會比較接近于 Google 的 Dremel 或者 Cloudera 的 Impala。 )
現狀
正如上面所介紹的, Presto 的開發是從 2012 年的秋天開始的。 在 2013 年早期的時候我門的第一個生產系統開始運行。 在 2013 年春天的時候這個系統推廣到了 非死book 的整個公司。從那是起, 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/非死book/presto
非死book 數據基礎設施的 Presto 團隊由以下成員組成, Martin Traverso, Dain Sundstrom, David Phillips, Eric Hwang, Nileema Shingte 以及Ravi Murthy.
鏈接
[1] Scaling Apache Giraph to a trillion edges. https://www.非死book.com/notes/非死book-engineering/scaling-apache-giraph-to-a-trillion-edges/10151617006153920
[2] Under the hood: Scheduling MapReduce jobs more efficiently with Coronahttps://www.非死book.com/notes/非死book-engineering/under-the-hood-scheduling-mapreduce-jobs-more-efficiently-with-corona/10151142560538920
[3] Video of Presto talk at Analytics@Webscale conference, June 2013https://www.非死book.com/photo.php?v=10202463462128185