Apache Drill 調研學習java
## 1、Drill概述node
在大數據時代,對於Hadoop中的信息,愈來愈多的用戶須要可以得到快速且互動的分析方法。大數據面臨的一個很大的問題是大多數分析查詢都很緩慢且非交互式。目前來看,MapReduce一般用於執行Hadoop數據上的批處理分析,但並不適合於你想快速獲得結果或者從新定義查詢參數。Google的Dremel能以極快的速度處理網絡規模的海量數據。據谷歌的研究報告顯示,Dremel能以拍字節(petabyte,PB,1PB等於1024TB)的數量級來進行查詢,並且只需幾秒鐘時間就能完成。而其對應的開源版本就是Drill。(ps:drill其實就是一個分佈式實時數據分析查詢的引擎。Drill,一個專爲互動分析大型數據集的分佈式系統。)
Apache Drill是一個低延遲的分佈式海量數據(涵蓋結構化、半結構化以及嵌套數據)交互式查詢引擎,使用ANSI SQL兼容語法,支持本地文件、HDFS、HBase、MongoDB等後端存儲,支持Parquet、JSON、CSV、TSV、PSV等數據格式。本質上Apache Drill是一個分佈式的mpp(大規模並行處理)查詢層。Drill的目的在於支持更普遍的數據源,數據格式,以及查詢語言。受Google的Dremel啓發,Drill知足上千節點的PB級別數據的交互式商業智能分析場景。c++
## 2、GoolDremal設計思想web
隨着Hadoop的流行,大規模的數據分析系統已經愈來愈普及。數據分析師須要一個能將數據玩轉的交互式系統。如此就能夠很是便捷的瀏覽數據創建分析模型。Dremal有一下幾個主要特色:sql
1. Dremal是一個大規模系統。在一個PB級別的數據集上面將任務縮短到秒級別,無疑須要大量的併發。磁盤的順序讀寫在100mb/s上下,那麼在一秒內處理1TB數據則意味着最少要1萬個磁盤的,可是機器越多就越容易出問題,如此大的集羣須要有足夠的容錯考慮,保證分析速度不被壞節點影響。shell
2. Dremal是MR交互式能力不足的補充。和MR同樣,Dremal也須要和數據運行在一塊兒,將計算移動到數據上面。因此須要像GFS同樣文件系統做爲存儲層。在設計之初, Dremal並不是是MR的替代品,他只是能夠很是快的分析,在使用的時候,經常使用它來處理MR的結果集或者創建分析原型。數據庫
3. Dremal的數據集是嵌套的。互聯網數據經常是非關係型的。Dremal還須要一個靈活的數據模型,這個模型相當重要。Dremal支持一個嵌套的數據模型,相似於json。而傳統的關係模型,因爲不可避免的大量join操做,在處理大規模數據的時候,每每是有心無力。apache
4. Dremal的數據是列示存儲的。使用列示存儲能夠再查詢只須要的那部分數據的時候減小cpu和磁盤的訪問量。同時列示存儲是壓縮友好的,使用壓縮能夠綜合cpu和磁盤,發揮最大效能。編程
5. Dremal結合了web搜索和DBMS的技術。首先他借鑑了web搜索中的「查詢樹」概念,將一個相巨大複雜的查詢,分割成較小較簡單的查詢。大事化小小事化了,能併發的在大量節點上跑。其次和並行DBMS同樣,Dremal能夠提升一個SQL-like的接口像hive和pig同樣。json
## 3、Drill的優點
1. 學習成本低
2. 低延遲的SQL查詢
3. 動態查詢自描述數據文件(json,text,Parquet),MPR-DB/Hbase表,不須要元數據定義的hive元數據。ANSI SQL
4. 嵌套數據支持
5. 與ApacheHive一體化(Hive表和視圖的查詢,支持全部的Hive文件格式和HiveUDFS)
6. BI/SQL工具集成使用標準的JDBC驅動程序
7. 訪問多個數據源
8. 用戶自定義UDF
9. 高性能(設計上高吞吐量和低延遲,不使用通用的執行引擎,柱形矢量引擎)
## 4、Drill架構
Drill的核心是DrillBit服務,主要負責接收客戶端的請求,處理查詢,並將結果返回給客戶端。
DrillBit可以安裝和運行在hadoop集羣中所須要的節點上造成一個分佈式環境。當DrillBit運行在集羣上的節點上時,可以最大程度的實現數據本地化的執行,不要進行網絡和節點間的數據移動。Drill使用Zookeeper來維護和管理集羣節點和節點的健康情況。
儘管DrillBit運行在Hadoop集羣中,不過他不依賴與hadoop集羣,能夠運行在任何的分佈式系統中。
DrillBit架構以下圖所示:

## 5、Drill原理
當提交一個Drill查詢時,客戶端或應用程序以SQL語句的方式發送查詢給Drill集羣中的DrillBit。DrillBit處理運行在每一個活動節點上的查詢計劃和執行查詢,以及跨集羣分發查詢任務以實現數據本地性的最大化。
DrillBit接收來自客戶端和應用程序的Drill查詢變成驅動整個查詢的Foreman。Foreman解析器解析SQL,將自定義規則應用到特定的SQL操做符轉換成特定的Drill理解的邏輯操做語法。集合的邏輯運算符造成邏輯的計劃。邏輯計劃描述了做業所須要生成的查詢結果和定義了數據源與應用操做。
Foreman發送邏輯計劃到一個基於優化在一個語句和邏輯讀計劃的SQL操做的順序的優化器。優化器使用與各類類型規則的從新整理以及函數的最優化方案。優化器將邏輯計劃轉換成一個描述如何執行查詢的物理計劃。

Foreman並行化轉換的物理計劃分爲多個階段,包括主要(Major)和次要(Minor)的Fragment。這些Fragment根據配置的數據源執行並建立多級執行重寫查詢樹,將結果返回給客戶端和應用程序。

Major Fragment是抽象的概念,表明查詢執行的一個階段。這個階段由一個或多個操做組成。Drill爲每一個Major Fragment分配一個MajorFragmentID。
例如,執行兩個文件的哈希聚合,Drill爲這個計劃建立兩個Major Fragment,第一個Fragment用於掃描兩個文件,第二個Fragment用於數據的聚合。
Drill經過一個交換操做符分離兩個Fragment。交換的改變發生在數據所在位置或者物理計劃的並行化中。交換是由發送器和接收器組成,容許數據在節點之間移動。
Major Fragment不執行任何的查詢任務。每一個Major Fragment被劃分紅一個或多個Minor Fragment,執行實際所需完成的查詢操做並返回結果給客戶端。

每一個Major Fragment是由多個minor Fragment並行構成的。一個Minor Fragment是內部運行線程的邏輯做業單元。在Drill中,一個邏輯做業單元也被稱爲碎片(slice)。Drill產生的執行計劃由Minor Fragment組成。Drill爲每一個Minor Fragment分配一個Minor FragmentID。
Foreman的並行器在執行期間從Major Fragment建立一個或多個Minor Fragment,分解的Major Fragment與多個Minor Fragment同樣能同時運行在集羣上。

Drill可以儘快的根據上游的數據需求來執行每一個Minor Fragment。Drill使用節點的本地化調度Minor Fragment,而後Drill採用輪訓的方式調度存在、可用的DrillBit。
Minor Fragment包含一個或多個關係操做,一種操做執行一個關係操做,例如,scan、filter、join、group等。每種操做都有特定的操做類型和一個操做ID。每一個操做D定義了它所在的Minor Fragment的關係。

例如,當執行兩個文件的散列彙集時,Drill拆分第一階段致力於掃描進兩個Minor Fragment。每一個Minor Fragment 包含掃描文件的掃描操做符。Drill拆分第二階段爲了彙集進四個Minor Fragment。四個Minor Fragment都包括散列彙集操做符。
Minor Fragment能夠做爲root、intermediate、leaf Fragment三種類型運行。一個執行樹只包括一個root Fragment。執行樹的座標編號是從root開始的,root是0。數據流是從下游的leaf Fragment到root Fragment。
運行在Foreman的root Fragment接收傳入的查詢、從表讀取元數據,從新查詢而且路由到下一級服務樹。下一級的Fragment包括Intermediate 和leaf Fragment。
當數據可用或者能從其餘的Fragment提供時,Intermediate Fragment啓動做業。他們執行數據操做而且發送數據到下游處理。經過聚合Root Fragment的結果數據,進行進一步聚合並提供查詢結果給客戶端或應用程序。
Leaf Fragment並行掃描表而且與存儲層數據通訊或者訪問本地磁盤數據。Leaf Fragment的部分結果傳遞給Intermediate Fragment,而後對Intermediate結果執行合併操做。

## 6、總結
### 6.1 drill優缺點對比
通過一天的調研與其餘同類型技術的對比,drill給個人感受,首先是實時交互式SQL分佈式查詢引擎。適用於實時的數據分析查詢。
首先說說drill的優勢:
1. 支持自定義的嵌套數據集,數據靈活。
2. Hive一體化,徹底支持hive包括hive的udf,而且支持自定義udf
3. 低延遲的sql查詢,與經常使用sql有些不一樣,不過學習成本較低
4. 支持多數據源
5. 性能較高。
再來看看drill的缺點:
1. drill語法和常規sql有區別,通常是如「select * from 插件名.表名」的形式。主要是由於drill查詢不一樣數據源時須要切換不一樣的插件。下面分別是hive,hbase,文件系統三種數據源時候的查詢sql。
a) hvie:select * from hive.test01;
b) hbase:select * from hbase.test01;
c) dfs:select * from dfs.`/home/liking/test.csv`;查出來以後是一列數據,若想對數據查詢不一樣的列須要用columns[0]的形式來標記。
Select columns[0] from dfs.`/home/liking/test.csv`。另外匹配的文件類型須要在插件的工做空間來配置,具體的配置請參考官方文檔。
2.技術線太長,不容易切合到實際生產線上去。
3.國內使用較少,沒有大型成功案例,不夠大衆化,出現問題可能維護起來比較困難。資料比較少。
### 6.2 其餘同類型技術簡單介紹
1. Apache Kylin:核心思想是預計算,在查詢以前創建好索引,以便提升查詢速度。Kylin從數據倉庫中最經常使用的Hive中讀取源數據,使用 MapReduce做爲Cube構建的引擎,並把預計算結果保存在HBase中,對外暴露Rest API/JDBC/ODBC的查詢接口。由於Kylin支持標準的ANSI SQL,因此能夠和經常使用分析工具(如Tableau、Excel等)進行無縫對接。
美團、京東、百度等互聯網公司都有使用。e最大有8個維度,最大數據條數4億,最大存儲空間800G,30個Cube共佔存儲空間4T左右。查詢性能上,當QPS在50左右,全部查詢平均在200ms之內,當QPS在200左右,平均響應時間在1s之內。但從性能來說沒有問題,但他須要預計算,數十gb的文件大概須要幾十分鐘。對於實時性高的應用場景不能忍受。
2. Impala:基於hive的實時分佈式查詢引擎。與hive公用元數據庫信息,但對udf的結合不夠好,並且在嵌套數據的處理上也有問題。不過對於簡單的查詢來講效果能夠。相比於drill,Impala須要定義模式。相對來講適合模式固定,查詢條件簡答的實時查詢。
3. presto:京東,美團都有使用。缺點是學習成本較高,語法語義有問題。Facebook開源的沒有權限控制,京東發佈的版本有,可是不知道維護起來是否困難。有書能夠參考。強類型不支持類型轉換,京東版本作了類型轉換,不過facebook沒有接受京東的代碼。全部處理都在內存中完成,自己是有內存限制的,但京東經過提升少許節點的內存,將大資源的任務的數據限制在高性能節點上來提升集羣的性能瓶頸。
#### 6.3在實際問題中的表現和評估:
Drill的評估有這幾方面須要考慮。對複雜語法的支持,在大數據狀況下多表性能如何,提供接口是否易用。
Drill:用於Hadoop,NoSQL和雲存儲的無模式SQL查詢引擎
Drill:
1. 支持ANSI SQL2003,徹底兼容標準的sql,支持複雜的查詢如where的子查詢和join,可是好像不支持insert,update,delete。只是負責提供查詢數據。
2. 支持查詢各類非關係型數據庫以及各種文件系統(沒有說能不能查詢關係型數據庫)。支持數據本地化,能夠將存儲節點與drill放在一塊兒。
3. 提供三種操做接口,webui,shell,編程。提供java和c++的編程接口。編程中使用drill驅動類便可。org.apache.drill.jdbc.Driver
發現的問題:
1. 第一次查詢速度大速度下降,之後會變快。多是受測試環境拖累。
2. 問題:Java 1.7 or later is required to run Apache Drill.明明是1.8的jdk版本卻報版本太低的錯誤。定位到drill-config.sh 396行。發現沒有對」.」進行轉義形成。
加上轉義符,轉義後解決。
3. 在鏈接hbase時能夠鏈接到數據庫的原信息,可是執行sql時卻報錯。
錯誤信息:
```
Query Failed: An Error Occurred
org.apache.drill.common.exceptions.UserRemoteException: SYSTEM ERROR:
IllegalAccessError: tried to access method
com.google.common.base.Stopwatch.()V
from class org.apache.hadoop.hbase.zookeeper.MetaTableLocator
[Error Id: 225f9409-3be7-42f2-be6d-4cabe21bc518 on sengtest:31010]
```
開始懷疑是HBASE版本問題,找了一個0.98版本,一樣的問題。
問題定位在drill的jar上面去。
下載HBASE Shaded Client 替換便可,下載地址: http://mvnrepository.com/artifact/org.apache.hbase/hbase-shaded-client/1.2.3
將這四個jar包
hbase-annotations-1.1.3.jar 、hbase-client-1.1.3.jar
hbase-common-1.1.3.jar 、hbase-protocol-1.1.3.jar
替換成
hbase-shaded-client-1.2.3.jar
問題解決。
注意:從drill 1.17的release nodes上面能夠看到drill已經能夠適配1.x版本的hbase。
4. 鏈接hive時能夠正確訪問元數據,執行sql查詢時出錯。報unknowhost,由於元數據正常訪問,說明插件配置沒有問題,問題定位到hdfs-site.xml。發現配置的ha,namenode沒法被識別。暫時解決辦法:在客戶端配置namenode的host映射。弊端:對於ha的namenode若是主備切換以後可能還須要再配置。
經過jdbc鏈接drill:經過jdbc鏈接drill須要注意的是jar包引入和鏈接的方式。
Drill的jdbc maven依賴
```xml
<dependency>
<groupId>org.apache.drill.exec</groupId>
<artifactId>drill-jdbc-all</artifactId>
<version>1.11.0</version>
</dependency>
```
Dril的鏈接方式有兩種,一是制定具體的drill或者drill集羣的ip和端口號。另外一種是經過zk來完成。兩種方式的具體格式以下:若有更深刻的需求能夠上官網查看。
```svala
Drillbit:jdbc:drill:drillbit=<node name>[:<port>][,<node name2>[:<port>]...
DrillZK:jdbc:drill:zk=<zk name>[:<port>][,<zk name2>[:<port>]...
```
jdbc鏈接時,查詢hbase與文件系統均返回varchar類型。查詢hive時支持大部分數據類型,如今並不提供對於hive的寫操做。不支持的hive數據類型有:List,Map STRUCT,TIMESTAMP(Unix Epoch format),UNION
下面來講一下查詢hive時支持的數據類型與sql的映射。
| 支持的SQL類型 | Hive類型 |
| ------------- |:-------------:|
| BIGINT | BIGINT |
| BOOLEAN | BOOLEAN |
| VARCHAR | CHAR |
| DATE | DATE |
| DECIMAL* | DECIMAL |
| FLOAT | FLOAT |
| DOUBLE | DOUBLE |
| INTEGER |INT,TINYINT,SMALLINT|
| INTERVAL | N/A |
| TIME | N/A |
| N/A | TIMESPAMP (unix的系統時間)|
| TIMESPAMP | TIMESPAMP (JDBC時間格式:yyyy-mm-dd hh\:mm\:ss) |
| None | STRING |
| VARCHAR | VARCHAR |
| VARBINARY | BINARY |
官網地址:http://drill.apache.org/