開源SQL-on-Hadoop系統一覽
引言
查詢分析是大資料要解決的核心問題之一,而SQL作為查詢分析中使用最簡單、最廣泛的的語言之一,必然而然的催生了許多支援在Hadoop上使用SQL的系統,這就是所謂的SQL-on-Hadoop系統,其中大眾熟知的Hive就是最早的SQL-on-Hadoop系統。
經過若干年的發展,SQL-on-Hadoop系統已經百花齊放,按照架構劃分這些系統大致可以分為以下幾類:
- MapReduce架構系統:如Hive,這類系統是在MapReduce計算框架上封裝了一個SQL語義層,在執行過程中把SQL轉換為MapReduce程式來執行
- MPP架構系統:如Impala、Presto、Drill等,這類系統採用MPP(Massively Parallel Processing)架構,使用的是分散式查詢引擎,而非MapReduce
- 預計算系統:如Druid、Kylin等,這類系統主要特點是對資料進行預計算,並將結果儲存,而在查詢時直接獲取相應結果值。
本文主要是對這些系統做了一個基本總結,並簡單介紹了一些主流系統的架構以及處理流程。下表是按照時間順序,對這些系統的一個概述,包括技術特點和主導公司等。
專案名稱 | 時間點 | 技術特點 | 主導公司 |
---|---|---|---|
Apache Hive | 2008年進入Apache,2010年畢業 | 一款基於HDFS的MapReduce計算框架,提供類SQL的資料查詢功能,本質是將SQL轉換為MapReduce任務執行 | 初期由Facebook開發,後被各大公司廣泛接受 |
Apache Spark | 2010年進入Apache,2014年畢業 | 資料在記憶體中以RDD(Resilient Distributed Datasets)表示,DataFrame是其核心程式設計抽象,同時也支援互動式查詢和流計算 | Databricks |
Cloudera Impala | 2012年進入Apache,仍在孵化中 | 一款使用C/C++實現的MPP SQL查詢引擎,使用HDFS作為儲存,並支援列存 | Cloudera |
Apache Drill | 2012年進入Apache,2014年畢業 | 以Google Dremel論文為基礎,一個MPP資料查詢引擎,支援schema free的互動式資料查詢 | MapR |
Presto | 2013年開源 | 基於記憶體的計算引擎,本身並不儲存資料,支援跨資料來源的級聯查詢 | |
Stinger Initiative | 2013年 | 對Hive的效能優化和提升 | Hortonworks |
Apache Phoenix | 2013年進入Apache,2014年5月畢業 | 構建在HBase上的一個SQL層 | 初期由Salesforce開發 |
Apache Tajo | 2013年進入Apache,2014年5月畢業 | 基於Hadoop的資料倉庫和SQL資料查詢執行引擎 | 由Database Lab., Korea University開發 |
Apache Flink | 2014年4月進入Apache,2014年12月畢業 | 流式的資料流執行引擎,基於流計算來模擬批計算,分別提供了流處理和批處理API | Data Artisans |
Apache Kylin | 2014年11月進入Apache,2015年11月畢業 | 使用CUBE技術做多維資料預計算和聚合 | 初期由ebay開發,現由Kyligence主導 |
Apache HAWQ | 2015年進入Apache,2018年5月畢業 | Hadoop原始大規模並行SQL分析引擎,支援ACID事物特性 | Hortonworks |
Apache Trafodion | 2015年進入Apache,孵化中 | 構建在HBase上的一個SQL層 | HP實驗室 |
Apache Hive
Apache Hive是Hadoop生態系統中最早的SQL引擎,它可以將結構化資料檔案對映為一張資料庫表,並提供類SQL查詢功能。Hive本質上是在MapReduce計算框架上封裝了一個SQL語義層,並在執行過程中把SQL轉換為MapReduce程式來執行。
Hive通過使用者互動介面接收SQL後,其Driver結合元資料將SQL翻譯成MapReduce程式,並提交到Hadoop中執行,最後將執行結果輸出,其架構如下圖所示:
主要組成部分包括:
- user interface:即使用者介面,包含CLI(命令列),JDBC/ODBC等
- Metastore:即元資料,包括表名、表的資料所在目錄等;預設元資料儲存在自帶的derby資料庫中,推薦使用MySQL
- Driver:即驅動器,包含以下幾個元件:
(1) 解析器(SQL Parser):將SQL轉換成抽象語法樹(AST),並對AST進行語法分析。
(2) 編譯器(Compiler):將AST編譯生成邏輯執行計劃。
(3) 優化器(Query Optimizer):對邏輯執行計劃進行優化。
(4) 執行器(Execution):把邏輯執行計劃轉換成可以執行的物理計劃。
Hive提供的類SQL查詢功能避免了開發人員書寫複雜的MapReduce程式,極大的簡化了MapReduce程式的開發,大大減少了相應的學習成本。隨著技術的不斷進步,Hive的執行引擎也不斷髮展,尤其是有了Tez之後,其效能有了很大的改進。不過,其缺點依舊很明顯,即處理速度慢,比較適合執行在批處理場景中,而不適合互動式查詢等對時延要求高的場景中。
Apache Spark
Spark是一個通用的大資料計算框架,期望使用一個技術棧來解決大資料領域包括批處理、流計算、互動式查詢、圖計算和機器學習在內的各種計算任務,其軟體棧如下圖所示:
其中的Spark SQL元件是一個用於處理結構化資料的元件,它吸收了一個叫Shark(Hive-on-Spark)的專案。Spark SQL中最重要的一個概念就是DataFrame,它是帶有Shema資訊的RDD,類似於傳統資料庫中的二維表格。Spark SQL支援將多種外部資料來源的資料轉化為DataFrame,包括Json、Parquet等,並可以通過將其註冊為臨時表,然後使用SQL來處理和分析這些資料。Spark SQL的執行流程包含以下幾步,如圖所示:
包含以下幾個步驟:
- SQL語句經過SqlParser解析成UnresolvedLogicalPlan。
- Analyzer結合catalog進行繫結,生成LogicalPlan。
- Optimizer對LogicalPlan優化,生成OptimizedLogicalPlan。
- SparkPlan將OptimizedLogicalPlan轉換成PhysicalPlan。
- prepareForExecution()將PhysicalPlan轉換成executedPhysicalPlan。
- PhysicalPlan執行得到最終結果RDD。
傳統的MapReduce程式中Map和Reduce階段的結果都要寫磁碟,這大大降低了系統性能。Spark使用RDD作為基本資料結構,資料常駐記憶體,所以計算速度得到了很大提高。但是當記憶體不足時,其計算速度會大大降低,甚至容易出現OOM錯誤。
Apache Impala
Apache Impala是一款基於HDFS/HBase的MPP查詢引擎,其架構如下圖所示:
主要組成部分包括:
- Impalad: 即Impala Daemon(Impala守護程序);它執行在叢集的每個node上,負責接收客戶端的查詢請求,對查詢進行並行化處理。其中接收查詢請求的Impalad為Coordinator,Coordinator對查詢語句處理後生成執行計劃,再把執行計劃分發給具有相應資料的其它Impalad執行,其他Impalad執行完成後,把結果傳送回
Coordinator,由Coordinator構建最終結果,並返回給客戶端。另外,Impalad程序也會和Statusstore通訊以確認哪些Impalad是可以正常工作的。 - Statestore: 負責跟蹤和檢查Impalad健康狀態的程序,由statestored程序表示;它負責處理Impalad的註冊訂閱,並且和各個Impalad程序保持心跳連結。
- CLI: 提供給使用者查詢使用的命令列工具(Impala Shell使用python實現),同時Impala還提供了Hue,JDBC, ODBC使用介面。
Impala沒有使用MapReduce計算框架,而是使用與商用並行關係資料庫中類似的分散式查詢引擎,並且Impala的中間結果不寫入磁碟,而是通過網路以流的形式傳遞,這大大降低了IO開銷,因而Impala的查詢速度非常快。但是Impala缺點也很明顯,如對使用者自定義函式支援不好、不支援Transforms、不支援查詢期的容錯等。
Apache Drill
Apache Drill是一個分散式的MPP SQL引擎,是開源版本的Google Dremel。它支援對本地檔案、HDFS、HBASE等資料進行資料查詢,也支援對如JSON等schema-free的資料進行查詢,其架構如下圖所示:
從上圖可以看到,Drill的核心是DrillBit,它主要負責接收客戶端的請求,處理查詢,並將結果返回給客戶端。 Drill的查詢流程包括以下步驟:
- drill客戶端發起查詢,任意DrilBit都可以接受來自客戶端的查詢。
- 收到請求的DrillBit成為驅動節點(Foreman),對查詢進行分析優化生成執行計劃,之後將執行計劃劃分成各個片段,並確定合適的節點來執行。
- 各個節點執行查詢片段,並將結果返回給驅動節點。
- 驅動節點將結果返回給客戶端。
Presto
Presto是一個分散式的MPP查詢引擎,支援多種資料來源,包括Hive、RDBMS、Redis等,並且可以跨資料來源查詢。Presto的基本架構如下圖所示:
主要組成部分包括:
- coodinator:用於解析查詢SQL,生成執行計劃,並分發給worker執行。
- discovery server:worker上線後,向discovery server註冊。coodinator分發任務前,需要向discovery server獲取可以正常工作worker列表。
- worker:具體執行任務的工作節點。
Apache Phoenix
Apache Phoenix是一個執行在HBase上的SQL框架,其本質是用Java寫的基於JDBC API操作HBase的開源SQL引擎,通過Phoenix可以像使用MySQL等關係型資料庫一樣操作HBase中的表。Apache Phoenix支援ACID事務功能的標準SQL,它將SQL編譯成原生HBase的scan語句,其架構如下圖所示:
從上圖可以看到:
- Phoenix的JDBC driver是在HBase的client端。
- Phoenix在HBase的RegionServer上。
Apache Kylin
Apache Kylin是一個開源的分散式分析引擎,提供Hadoop/Spark之上的SQL查詢介面及多維分析(OLAP)能力。Kylin的核心是預計算,即對可能用到的度量進行預計算,並將結果儲存為Cube以便查詢時直接訪問。Kylin的架構如下圖所示:
主要組成部分包括:
- 離線構建部分:根據元資料的定義,從資料來源(如Hive)抽取資料,並通過MapReduce Job構建Cube。構建後的Cube儲存在HBase中。
- 線上查詢部分:使用者通過RESTful API、JDBC/ODBC等介面提交SQL,REST服務把SQL交給查詢引擎處理。查詢引擎解析SQL,生成邏輯執行計劃,之後將其轉化為基於Cubde物理執行計劃,最後讀取預計算生成的Cube並返回結果。
Apache Flink
Apache Flink是一個面向分散式資料流處理和批量資料處理的開源計算平臺,它能夠基於同一個Flink執行時提供流處理和批處理兩種型別應用的功能。區別於其他流處理系統,Flink作為流處理時,把輸入資料流看做是無界的,而批處理被作為一種特殊的流處理,只是它的輸入資料流被定義為有界的。
基於同一個Flink執行時(Flink Runtime),Flink分別提供了流處理和批處理API,為了實現API層流與批的統一,Flink提供了一種關係型API,即Table & SQL API。
Apache HAWQ
Apache HAWQ的全稱是Hadoop With Query,是一個Hadoop原生的MPP SQL引擎。HAWQ能直接在HDFS上讀寫資料,而不需要connector,並支援ACID事務特性,其架構如下圖所示:
主要組成部分包括:
- HAWQ master:負責處理客戶端提交的SQL,解析優化後向叢集Segment節點下發查詢,合併從各Segemt節點返回的結果,並返回最終結果給客戶端。HAWQ master內部由HAWQ Resource Manager,HAWQ Catalog Service,HAWQ Fault Tolerance Service,HAWQ Dispatcher等元件組成。HAWQ master還需要維護global system catalog,global system catalog是系統表的集合,其中包含了HAWQ叢集的元資料資訊。
- HAWQ segment:叢集的計算節點,本身不儲存任何資料,所有資料都儲存在HDFS上。HAWQ master在分派SQL請求給Segment時會附帶相關的元資料資訊,元資料資訊包含了表的HDFS URL,Segment通過HDFS URL訪問需要處理的資料。
- PXF agent:PXF(Pivotal eXtension Framework)的服務。PXF是一個允許HAWQ訪問外部系統資料的可擴充套件框架,其中內建了訪問HDFS檔案,HBase表以及Hive表的聯結器,PXF還可以通過和HCatalog整合來直接訪問Hive表。
結束語
SQL-on-Hadoop系統經過了若干年的發展,已經有了很大的提高,但是目前各個系統仍然在不斷完善提高,例如:
- 執行計劃方面:更強的優化器
- 執行效率方面:支援code generation、vectorization等
- 儲存格式方面:支援更高效列存等
未來也會出現更多技術、更多系統。本文主要介紹了目前幾大開源的SQL-on-Hadoop系統及其架構,包括Hive、Spark、Presto、Drill等。