Apache Drill 調研學習


Apache Drill 調研學習

## 一、Drill概述

在大數據時代,對於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級別數據的交互式商業智能分析場景。

## 二、GoolDremal設計思想

隨着Hadoop的流行,大規模的數據分析系統已經越來越普及。數據分析師需要一個能將數據玩轉的交互式系統。如此就可以非常便捷的瀏覽數據建立分析模型。Dremal有一下幾個主要特點:

1. Dremal是一個大規模系統。在一個PB級別的數據集上面將任務縮短到秒級別,無疑需要大量的並發。磁盤的順序讀寫在100mb/s上下,那么在一秒內處理1TB數據則意味着最少要1萬個磁盤的,但是機器越多就越容易出問題,如此大的集群需要有足夠的容錯考慮,保證分析速度不被壞節點影響。

2. Dremal是MR交互式能力不足的補充。和MR一樣,Dremal也需要和數據運行在一起,將計算移動到數據上面。所以需要像GFS一樣文件系統作為存儲層。在設計之初, Dremal並非是MR的替代品,他只是可以非常快的分析,在使用的時候,常常使用它來處理MR的結果集或者建立分析原型。

3. Dremal的數據集是嵌套的。互聯網數據常常是非關系型的。Dremal還需要一個靈活的數據模型,這個模型至關重要。Dremal支持一個嵌套的數據模型,類似於json。而傳統的關系模型,由於不可避免的大量join操作,在處理大規模數據的時候,往往是有心無力。

4. Dremal的數據是列示存儲的。使用列示存儲可以再查詢只需要的那部分數據的時候減少cpu和磁盤的訪問量。同時列示存儲是壓縮友好的,使用壓縮可以綜合cpu和磁盤,發揮最大效能。

5. Dremal結合了web搜索和DBMS的技術。首先他借鑒了web搜索中的“查詢樹”概念,將一個相巨大復雜的查詢,分割成較小較簡單的查詢。大事化小小事化了,能並發的在大量節點上跑。其次和並行DBMS一樣,Dremal可以提高一個SQL-like的接口像hive和pig一樣。


## 三、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. 高性能(設計上高吞吐量和低延遲,不使用通用的執行引擎,柱形矢量引擎)

## 四、Drill架構

Drill的核心是DrillBit服務,主要負責接收客戶端的請求,處理查詢,並將結果返回給客戶端。
DrillBit能夠安裝和運行在hadoop集群中所需要的節點上形成一個分布式環境。當DrillBit運行在集群上的節點上時,能夠最大程度的實現數據本地化的執行,不要進行網絡和節點間的數據移動。Drill使用Zookeeper來維護和管理集群節點和節點的健康狀況。
盡管DrillBit運行在Hadoop集群中,不過他不依賴與hadoop集群,可以運行在任何的分布式系統中。
DrillBit架構如下圖所示:

![](img/jiagou.png)


## 五、Drill原理

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

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

Major Fragment是抽象的概念,代表查詢執行的一個階段。這個階段由一個或多個操作組成。Drill為每個Major Fragment分配一個MajorFragmentID。
例如,執行兩個文件的哈希聚合,Drill為這個計划創建兩個Major Fragment,第一個Fragment用於掃描兩個文件,第二個Fragment用於數據的聚合。
Drill通過一個交換操作符分離兩個Fragment。交換的改變發生在數據所在位置或者物理計划的並行化中。交換是由發送器和接收器組成,允許數據在節點之間移動。
Major Fragment不執行任何的查詢任務。每個Major Fragment被划分成一個或多個Minor Fragment,執行實際所需完成的查詢操作並返回結果給客戶端。
![](img/m.png)

每個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一樣能同時運行在集群上。
![](img/chaxun.png)

Drill能夠盡快的根據上游的數據需求來執行每個Minor Fragment。Drill使用節點的本地化調度Minor Fragment,然后Drill采用輪訓的方式調度存在、可用的DrillBit。
Minor Fragment包含一個或多個關系操作,一種操作執行一個關系操作,例如,scan、filter、join、group等。每種操作都有特定的操作類型和一個操作ID。每個操作D定義了它所在的Minor Fragment的關系。
![](img/chaxunguanxi.png)

例如,當執行兩個文件的散列聚集時,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結果執行合並操作。
![](img/marge.png)


## 六、總結

### 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/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM