Kylin安裝與使用

Markble發表於2020-10-04

目錄

一、Kylin概述

二、Kylin機構

三、Kylin特點

四、安裝

4.1 Kylin依賴環境

4.2 Kylin搭建

4.3 Kylin相容性問題

4.4 Kylin啟動

五、Kylin Cube構建原理

5.1 維度和度量

5.2 Cube和Cuboid

5.3 Cube構建演算法

六、Kylin Cube構建優化

6.1 使用衍生維度(derived dimension)

6.2 使用聚合組(Aggregation group)

6.4 Row Key優化

6.5 併發粒度優化

6.6 Kylin BI工具整合


一、Kylin概述

Apache Kylin是一個開源的分散式分析引擎,提供Hadoop/Spark之上的SQL查詢介面及多維分析(OLAP)能力以支援超大規模資料,最初由eBay Inc開發並貢獻至開源社群。它能在亞秒內查詢巨大的Hive表。

二、Kylin機構

1)REST Server
REST Server是一套面向應用程式開發的入口點,旨在實現針對Kylin平臺的應用開發工作。 此類應用程式可以提供查詢、獲取結果、觸發cube構建任務、獲取後設資料以及獲取使用者許可權等等。另外可以通過Restful介面實現SQL查詢。

2)查詢引擎(Query Engine)
當cube準備就緒後,查詢引擎就能夠獲取並解析使用者查詢。它隨後會與系統中的其它元件進行互動,從而向使用者返回對應的結果。 

3)路由器(Routing)
在最初設計時曾考慮過將Kylin不能執行的查詢引導去Hive中繼續執行,但在實踐後發現Hive與Kylin的速度差異過大,導致使用者無法對查詢的速度有一致的期望,很可能大多數查詢幾秒內就返回結果了,而有些查詢則要等幾分鐘到幾十分鐘,因此體驗非常糟糕。最後這個路由功能在發行版中預設關閉。

4)後設資料管理工具(Metadata)
Kylin是一款後設資料驅動型應用程式。後設資料管理工具是一大關鍵性元件,用於對儲存在Kylin當中的所有後設資料進行管理,其中包括最為重要的cube後設資料。其它全部元件的正常運作都需以後設資料管理工具為基礎。 Kylin的後設資料儲存在hbase中。
 
5)任務引擎(Cube Build Engine)
這套引擎的設計目的在於處理所有離線任務,其中包括shell指令碼、Java API以及Map Reduce任務等等。任務引擎對Kylin當中的全部任務加以管理與協調,從而確保每一項任務都能得到切實執行並解決其間出現的故障。

三、Kylin特點

Kylin的主要特點包括支援SQL介面、支援超大規模資料集、亞秒級響應、可伸縮性、高吞吐率、BI工具整合等。

1)標準SQL介面:Kylin是以標準的SQL作為對外服務的介面。

2)支援超大資料集:Kylin對於大資料的支撐能力可能是目前所有技術中最為領先的。早在2015年eBay的生產環境中就能支援百億記錄的秒級查詢,之後在移動的應用場景中又有了千億記錄秒級查詢的案例。

3)亞秒級響應:Kylin擁有優異的查詢相應速度,這點得益於預計算,很多複雜的計算,比如連線、聚合,在離線的預計算過程中就已經完成,這大大降低了查詢時刻所需的計算量,提高了響應速度。

4)可伸縮性和高吞吐率:單節點Kylin可實現每秒70個查詢,還可以搭建Kylin的叢集。

5)BI工具整合

Kylin可以與現有的BI工具整合,具體包括如下內容。
ODBC:與Tableau、Excel、PowerBI等工具整合
JDBC:與Saiku、BIRT等Java工具整合
RestAPI:與JavaScript、Web網頁整合
Kylin開發團隊還貢獻了Zepplin的外掛,也可以使用Zepplin來訪問Kylin服務。

四、安裝

4.1 Kylin依賴環境

安裝Kylin前需先部署好Hadoop、Hive、Zookeeper、HBase,並且需要在/etc/profile中配置以下環境變數HADOOP_HOMEHIVE_HOMEHBASE_HOME記得source使其生效。

4.2 Kylin搭建

1)上傳Kylin安裝包apache-kylin-3.0.2-bin.tar.gz
2)解壓apache-kylin-3.0.2-bin.tar.gz到/opt/module
[Mark@hadoop102 sorfware]$ tar -zxvf apache-kylin-3.0.2-bin.tar.gz -C /opt/module/
[Mark@hadoop102 module]$ mv /opt/module/apache-kylin-3.0.2-bin /opt/module/kylin

4.3 Kylin相容性問題

如果都使用最新版本的框架,可能會有相容性的問題

4.4 Kylin啟動

(1)啟動Kylin之前,需先啟動Hadoop(hdfs,yarn,jobhistoryserver)、Zookeeper、HBase
(2)啟動Kylin

[Mark@hadoop102 kylin]$ bin/kylin.sh start

啟動之後檢視各個節點程式:
--------------------- hadoop102 ----------------

3360 JobHistoryServer
31425 HMaster
3282 NodeManager
3026 DataNode
53283 Jps
2886 NameNode
44007 RunJar
2728 QuorumPeerMain
31566 HRegionServer

--------------------- hadoop103 ----------------
5040 HMaster
2864 ResourceManager
9729 Jps
2657 QuorumPeerMain
4946 HRegionServer
2979 NodeManager
2727 DataNode

--------------------- hadoop104 ----------------
4688 HRegionServer
2900 NodeManager
9848 Jps
2636 QuorumPeerMain
2700 DataNode
2815 SecondaryNameNode

http://hadoop102:7070/kylin檢視Web頁面

五、Kylin Cube構建原理

5.1 維度和度量

維度:即觀察資料的角度。比如員工資料,可以從性別角度來分析,也可以更加細化,從入職時間或者地區的維度來觀察。維度是一組離散的值,比如說性別中的男和女,或者時間維度上的每一個獨立的日期。因此在統計時可以將維度值相同的記錄聚合在一起,然後應用聚合函式做累加、平均、最大和最小值等聚合計算。

度量:即被聚合(觀察)的統計值,也就是聚合運算的結果。比如說員工資料中不同性別員工的人數,又或者說在同一年入職的員工有多少。

5.2 Cube和Cuboid

有了維度跟度量,一個資料表或者資料模型上的所有欄位就可以分類了,它們要麼是維度,要麼是度量(可以被聚合)。於是就有了根據維度和度量做預計算的Cube理論。

給定一個資料模型,我們可以對其上的所有維度進行聚合,對於N個維度來說,組合`的所有可能性共有2n種。對於每一種維度的組合,將度量值做聚合計算,然後將結果儲存為一個物化檢視,稱為Cuboid。所有維度組合的Cuboid作為一個整體,稱為Cube。

下面舉一個簡單的例子說明,假設有一個電商的銷售資料集,其中維度包括時間[time]、商品[item]、地區[location]和供應商[supplier],度量為銷售額。那麼所有維度的組合就有24 = 16種,如下圖所示:

一維度(1D)的組合有:[time]、[item]、[location]和[supplier]4種;
二維度(2D)的組合有:[time, item]、[time, location]、[time, supplier]、[item, location]、[item, supplier]、[location, supplier]3種;
三維度(3D)的組合也有4種;
最後還有零維度(0D)和四維度(4D)各有一種,總共16種。
注意:每一種維度組合就是一個Cuboid,16個Cuboid整體就是一個Cube。

5.3 Cube構建演算法

1)逐層構建演算法(layer

我們知道,一個N維的Cube,是由1個N維子立方體、N個(N-1)維子立方體、N*(N-1)/2個(N-2)維子立方體、......、N個1維子立方體和1個0維子立方體構成,總共有2^N個子立方體組成,在逐層演算法中,按維度數逐層減少來計算,每個層級的計算(除了第一層,它是從原始資料聚合而來),是基於它上一層級的結果來計算的。比如,[Group by A, B]的結果,可以基於[Group by A, B, C]的結果,通過去掉C後聚合得來的;這樣可以減少重複計算;當 0維度Cuboid計算出來的時候,整個Cube的計算也就完成了。

每一輪的計算都是一個MapReduce任務,且序列執行;一個N維的Cube,至少需要NMapReduce Job

演算法優點:
1)此演算法充分利用了MapReduce的優點,處理了中間複雜的排序和shuffle工作,故而演算法程式碼清晰簡單,易於維護;
2)受益於Hadoop的日趨成熟,此演算法非常穩定,即便是叢集資源緊張時,也能保證最終能夠完成。

演算法缺點:
1)當Cube有比較多維度的時候,所需要的MapReduce任務也相應增加;由於Hadoop的任務排程需要耗費額外資源,特別是叢集較龐大的時候,反覆遞交任務造成的額外開銷會相當可觀;
2)由於Mapper邏輯中並未進行聚合操作,所以每輪MR的shuffle工作量都很大,導致效率低下。
3)對HDFS的讀寫操作較多:由於每一層計算的輸出會用做下一層計算的輸入,這些Key-Value需要寫到HDFS上;當所有計算都完成後,Kylin還需要額外的一輪任務將這些檔案轉成HBase的HFile格式,以匯入到HBase中去;
總體而言,該演算法的效率較低,尤其是當Cube維度數較大的時候。

2)快速構建演算法(inmem

也被稱作“逐段”(By Segment) 或“逐塊”(By Split) 演算法,從1.5.x開始引入該演算法,該演算法的主要思想是,每個Mapper將其所分配到的資料塊,計算成一個完整的小Cube 段(包含所有Cuboid)。每個Mapper將計算完的Cube段輸出給Reducer做合併,生成大Cube,也就是最終結果。如圖所示解釋了此流程。

與舊演算法相比,快速演算法主要有兩點不同:
1) Mapper會利用記憶體做預聚合,算出所有組合;Mapper輸出的每個Key都是不同的,這樣會減少輸出到Hadoop MapReduce的資料量,Combiner也不再需要;
2)一輪MapReduce便會完成所有層次的計算,減少Hadoop任務的調配。

六、Kylin Cube構建優化

6.1 使用衍生維度(derived dimension)

衍生維度用於在有效維度內將維度表上的非主鍵維度排除掉,並使用維度表的主鍵(其實是事實表上相應的外來鍵)來替代它們。Kylin會在底層記錄維度表主鍵與維度表其他維度之間的對映關係,以便在查詢時能夠動態地將維度表的主鍵“翻譯”成這些非主鍵維度,並進行實時聚合。

雖然衍生維度具有非常大的吸引力,但這也並不是說所有維度表上的維度都得變成衍生維度,如果從維度表主鍵到某個維度表維度所需要的聚合工作量非常大,則不建議使用衍生維度。

6.2 使用聚合組(Aggregation group)

聚合組(Aggregation Group)是一種強大的剪枝工具。聚合組假設一個Cube的所有維度均可以根據業務需求劃分成若干組(當然也可以是一個組),由於同一個組內的維度更可能同時被同一個查詢用到,因此會表現出更加緊密的內在關聯。每個分組的維度集合均是Cube所有維度的一個子集,不同的分組各自擁有一套維度集合,它們可能與其他分組有相同的維度,也可能沒有相同的維度。每個分組各自獨立地根據自身的規則貢獻出一批需要被物化的Cuboid,所有分組貢獻的Cuboid的並集就成為了當前Cube中所有需要物化的Cuboid的集合。不同的分組有可能會貢獻出相同的Cuboid,構建引擎會察覺到這點,並且保證每一個Cuboid無論在多少個分組中出現,它都只會被物化一次。

對於每個分組內部的維度,使用者可以使用如下三種可選的方式定義,它們之間的關係,具體如下。

1)強制維度(Mandatory,如果一個維度被定義為強制維度,那麼這個分組產生的所有Cuboid中每一個Cuboid都會包含該維度。每個分組中都可以有0個、1個或多個強制維度。如果根據這個分組的業務邏輯,則相關的查詢一定會在過濾條件或分組條件中,因此可以在該分組中把該維度設定為強制維度。

2)層級維度(Hierarchy,每個層級包含兩個或更多個維度。假設一個層級中包含D1,D2…Dn這n個維度,那麼在該分組產生的任何Cuboid中, 這n個維度只會以(),(D1),(D1,D2)…(D1,D2…Dn)這n+1種形式中的一種出現。每個分組中可以有0個、1個或多個層級,不同的層級之間不應當有共享的維度。如果根據這個分組的業務邏輯,則多個維度直接存在層級關係,因此可以在該分組中把這些維度設定為層級維度。

3)聯合維度(Joint,每個聯合中包含兩個或更多個維度,如果某些列形成一個聯合,那麼在該分組產生的任何Cuboid中,這些聯合維度要麼一起出現,要麼都不出現。每個分組中可以有0個或多個聯合,但是不同的聯合之間不應當有共享的維度(否則它們可以合併成一個聯合)。如果根據這個分組的業務邏輯,多個維度在查詢中總是同時出現,則可以在該分組中把這些維度設定為聯合維度。

這些操作可以在Cube Designer的Advanced Setting中的Aggregation Groups區域完成,如下圖所示

聚合組的設計非常靈活,甚至可以用來描述一些極端的設計。假設我們的業務需求非常單一,只需要某些特定的Cuboid,那麼可以建立多個聚合組,每個聚合組代表一個Cuboid。具體的方法是在聚合組中先包含某個Cuboid所需的所有維度,然後把這些維度都設定為強制維度。這樣當前的聚合組就只能產生我們想要的那一個Cuboid了。

再比如,有的時候我們的Cube中有一些基數非常大的維度,如果不做特殊處理,它就會和其他的維度進行各種組合,從而產生一大堆包含它的Cuboid。包含高基數維度的Cuboid在行數和體積上往往非常龐大,這會導致整個Cube的膨脹率變大。如果根據業務需求知道這個高基數的維度只會與若干個維度(而不是所有維度)同時被查詢到,那麼就可以通過聚合組對這個高基數維度做一定的“隔離”。我們把這個高基數的維度放入一個單獨的聚合組,再把所有可能會與這個高基數維度一起被查詢到的其他維度也放進來。這樣,這個高基數的維度就被“隔離”在一個聚合組中了,所有不會與它一起被查詢到的維度都沒有和它一起出現在任何一個分組中,因此也就不會有多餘的Cuboid產生。這點也大大減少了包含該高基數維度的Cuboid的數量,可以有效地控制Cube的膨脹率。

6.4 Row Key優化

Kylin會把所有的維度按照順序組合成一個完整的Rowkey,並且按照這個Rowkey升序排列Cuboid中所有的行。

設計良好的Rowkey將更有效地完成資料的查詢過濾和定位,減少IO次數,提高查詢速度,維度在rowkey中的次序,對查詢效能有顯著的影響。

Row key的設計原則如下:

1)被用作過濾的維度放在前邊。

2)基數大的維度放在基數小的維度前邊。

6.5 併發粒度優化

當Segment中某一個Cuboid的大小超出一定的閾值時,系統會將該Cuboid的資料分片到多個分割槽中,以實現Cuboid資料讀取的並行化,從而優化Cube的查詢速度。具體的實現方式如下:構建引擎根據Segment估計的大小,以及引數“kylin.hbase.region.cut”的設定決定Segment在儲存引擎中總共需要幾個分割槽來儲存,如果儲存引擎是HBase,那麼分割槽的數量就對應於HBase中的Region數量。kylin.hbase.region.cut的預設值是5.0,單位是GB,也就是說對於一個大小估計是50GB的Segment,構建引擎會給它分配10個分割槽。使用者還可以通過設定kylin.hbase.region.count.min(預設為1)和kylin.hbase.region.count.max(預設為500)兩個配置來決定每個Segment最少或最多被劃分成多少個分割槽。

由於每個Cube的併發粒度控制不盡相同,因此建議在Cube Designer 的Configuration Overwrites(上圖所示)中為每個Cube量身定製控制併發粒度的引數。假設將把當前Cube的kylin.hbase.region.count.min設定為2,kylin.hbase.region.count.max設定為100。這樣無論Segment的大小如何變化,它的分割槽數量最小都不會低於2,最大都不會超過100。相應地,這個Segment背後的儲存引擎(HBase)為了儲存這個Segment,也不會使用小於兩個或超過100個的分割槽。我們還調整了預設的kylin.hbase.region.cut,這樣50GB的Segment基本上會被分配到50個分割槽,相比預設設定,我們的Cuboid可能最多會獲得5倍的併發量。

6.6 Kylin BI工具整合

可以與Kylin結合使用的視覺化工具很多,例如:

ODBC:與Tableau、Excel、PowerBI等工具整合

JDBC:與Saiku、BIRT等Java工具整合

RestAPI:與JavaScript、Web網頁整合

Kylin開發團隊還貢獻了Zepplin的外掛,也可以使用Zepplin來訪問Kylin服務。

6.6.1 JDBC

1)新建專案並匯入依賴 

   <dependencies>
        <dependency>
            <groupId>org.apache.kylin</groupId>
            <artifactId>kylin-jdbc</artifactId>
            <version>3.0.2</version>
        </dependency>
    </dependencies>

2)編碼

package com.atguigu;
import java.sql.*;
public class TestKylin {

    public static void main(String[] args) throws Exception {
        //Kylin_JDBC 驅動
        String KYLIN_DRIVER = "org.apache.kylin.jdbc.Driver";

        //Kylin_URL
        String KYLIN_URL = "jdbc:kylin://hadoop102:7070/FirstProject";

        //Kylin的使用者名稱
        String KYLIN_USER = "ADMIN";

        //Kylin的密碼
        String KYLIN_PASSWD = "KYLIN";

        //新增驅動資訊
        Class.forName(KYLIN_DRIVER);

        //獲取連線
        Connection connection = DriverManager.getConnection(KYLIN_URL, KYLIN_USER, KYLIN_PASSWD);

        //預編譯SQL
        PreparedStatement ps = connection.prepareStatement("SELECT sum(sal) FROM emp group by deptno");

        //執行查詢
        ResultSet resultSet = ps.executeQuery();

        //遍歷列印
        while (resultSet.next()) {
            System.out.println(resultSet.getInt(1));
        }
    }
}

3)結果展示

2.6.2 Zepplin

1)Zepplin安裝與啟動

(1)將zeppelin-0.8.0-bin-all.tgz上傳至Linux
(2)解壓zeppelin-0.8.0-bin-all.tgz之/opt/module

[Mark@hadoop102 sorfware]$ tar -zxvf zeppelin-0.8.0-bin-all.tgz -C /opt/module/
(3)修改名稱
[Mark@hadoop102 module]$ mv zeppelin-0.8.0-bin-all/ zeppelin
(4)啟動
[Mark@hadoop102 zeppelin]$ bin/zeppelin-daemon.sh start

可登入網頁檢視,web預設埠號為8080

http://hadoop102:8080

2)配置Zepplin支援Kylin

(1)點選右上角anonymous選擇Interpreter

(2)搜尋Kylin外掛並修改相應的配置

(3)修改完成點選Save完成