開源的分佈式分析引擎,提供Hadoop/Spark之上的SQL查詢接口及多維分析(MOLAP)能力以支持超大規模數據,能在亞秒內查詢巨大的Hive表;linux
Kylin的主要特色包括支持SQL接口、支持超大規模數據集、亞秒級響應、可伸縮性、高吞吐率、BI工具集成等。web
MR Hive
M(多維)OLAP鏈接分析處理的引擎
Hive--->Kylin--->Hbase算法
1. Kylin架構
第一部分:sql
Metadata(元數據)和Cube Build Engine構建引擎(作分析運算),離線-提早算-預計算apache
第二部分:對外查詢(實時)輸出:
REST Server(接收請求)-->
Query Engine(sql語法解析)
Routing(鏈接HBase)windows
須要調用使用的場景:架構
第三方App REST-API-->基於http協議
BI tools:Tableau..企業級商業智能-可視化界面-->基於jdbc、ODBC(windows/ linux)app
2. Kylin工做原理
本質上是MOLAP(Multidimension On-Line Analysis Processing)Cube,也就是多維立方體分析;分佈式
Kylin的工做原理就是對數據模型作Cube預計算,並利用計算的結果加速查詢:ide
1)指定數據模型,定義維度和度量;
2)預計算Cube,計算全部Cuboid並保存爲物化視圖;
預計算過程是Kylin從Hive中讀取原始數據,按照咱們選定的維度進行計算,並將結果集保存到Hbase中,默認的計算引擎爲MapReduce,能夠選擇Spark做爲計算引擎。一次build的結果,咱們稱爲一個Segment。構建過程當中會涉及多個Cuboid的建立,具體建立過程由kylin.cube.algorithm參數決定,參數值可選 auto,layer 和 inmem, 默認值爲 auto,即 Kylin 會經過採集數據動態地選擇一個算法 (layer or inmem),若是用戶很瞭解 Kylin 和自身的數據、集羣,能夠直接設置喜歡的算法。
3)執行查詢,讀取Cuboid,運行,產生查詢結果。
肯定分析角度-即維度(觀察數據的角度)
具體聚合運算:count, avg, sum-即度量(被聚合(觀察)的統計值,也就是聚合運算的結果)
4個維度組合: abcd abc abc bcd ab cd ac bd a b c d 零維... n個維度---組合--->2^n個cuboid
一個N維的Cube,是由1個N維子立方體、N個(N-1)維子立方體、N*(N-1)/2個(N-2)維子立方體、......、N個1維子立方體和1個0維子立方體構成,總共有2^N個子立方體組成
每種維度組合--->cuboid
全部維度組合的cuboid做爲一個總體---->cube(立方體)
核心算法
①分層算 MR--逐層構建算法(layer)
高維---->低維; 數據基於高維,遞進過程
缺點:每層都有mr; 每層都要從hdfs讀取,大量IO; 簡單繁瑣
在逐層算法中,按維度數逐層減小來計算,每一個層級的計算(除了第一層,它是從原始數據聚合而來),是基於它上一層級的結果來計算的。
每一輪的計算都是一個MapReduce任務,且串行執行;一個N維的Cube,至少須要N次MapReduce Job。
②快速構建
須要算全部維度,一次mr便可; 多個切片-->多個map數; 作全部keyboid運算; 全部map彙總及cube結果
省去mr資源調度;減小了io; map已經沒重複的key,reducer只需對每一個map去重減小了reducer的工做量;
與舊算法相比,快速算法主要有兩點不一樣:
1) Mapper會利用內存作預聚合,算出全部組合;Mapper輸出的每一個Key都是不一樣的,這樣會減小輸出到Hadoop MapReduce的數據量,Combiner也再也不須要;
2)一輪MapReduce便會完成全部層次的計算,減小Hadoop任務的調配。
關於這兩個算法麒麟會自動選擇;
3. Kylin環境搭建
/etc/profile
#JAVA_HOME export JAVA_HOME=/opt/module/jdk1.8.0_144 export PATH=$PATH:$JAVA_HOME/bin #HADOOP_HOME export HADOOP_HOME=/opt/module/hadoop-2.7.2 export PATH=$PATH:$HADOOP_HOME/bin export PATH=$PATH:$HADOOP_HOME/sbin #HIVE_HOME export HIVE_HOME=/opt/module/hive export PATH=$PATH:$HIVE_HOME/bin ##HBASE_HOME export HBASE_HOME=/opt/module/hbase-1.3.1 export PATH=$PATH:$HBASE_HOME/bin #KYLIN_HOME export KYLIN_HOME=/opt/module/kylin export PATH=$PATH:$KYLIN_HOME/bin
1)將apache-kylin-2.5.1-bin-hbase1x.tar.gz上傳到Linux 2)解壓apache-kylin-2.5.1-bin-hbase1x.tar.gz到/opt/module [kris@hadoop101 sorfware]$ tar -zxvf apache-kylin-2.5.1-bin-hbase1x.tar.gz -C /opt/module/ 注意:須要在/etc/profile文件中配置HADOOP_HOME,HIVE_HOME,HBASE_HOME並source使其生效。 3)啓動 [kris@hadoop101 kylin]$ bin/kylin.sh start
啓動Kylin以前要保證HDFS,YARN,ZK,HBASE相關進程是正常運行的。
http://hadoop101:7070/kylin 查看Web頁面
用戶名爲:ADMIN,密碼爲:KYLIN(系統已填)
4. 建立項目
employee實事表纔會參與真正運算,dept維表不參與
model模型分如下2種:
① 當全部維表都直接鏈接到「 事實表」上時,整個圖解就像星星同樣,故將該模型稱爲星形模型
星狀模型是直接關聯;
② 當有一個或多個維表沒有直接鏈接到事實表上,而是經過其餘維錶鏈接到事實表上時,其圖解就像多個雪花鏈接在一塊兒,故稱雪花模型。
雪花模型是主從間接關聯;
建立分區表:
create table emp_partition(empno int, ename string, job string, mgr int, sal double, comm double, deptno int) partitioned by(hire_date string) row format delimited fields terminated by '\t'; 動態分區應該手動開啓: set hive.exec.dynamic.partition.mode=nonstrict;
動態插入數據 insert into table emp_partition partition(hire_date) select empno, ename, job, mgr, sal, comm, deptno, hiredate from emp;
① 建立module項目名稱:project_partition
主表--FactTable: default.emp_partition
從表--Add Lookup Table:emp_partition inner join dept
維度--Select dimension columns:EMP_PARTITION-->job,mgr,hire_date ; DEPT-->dname
度量--Select measure columns: EMP_PARTITION--->sal
② 建立Cube
Cube Designer
合併
與動量cute作呼應,分區必須是日期;選分區表:hire_date
Kylin查詢
在New Query中輸入查詢語句並Submit
數據圖表展現及能夠導出
5. 可視化
JDBC
新建項目並導入依賴
<dependencies> <dependency> <groupId>org.apache.kylin</groupId> <artifactId>kylin-jdbc</artifactId> <version>2.5.1</version> </dependency> </dependencies>
public class TestKylin { public static void main(String[] args) throws ClassNotFoundException, SQLException { //kylin的JDBC驅動類 String Kylin_Driver = "org.apache.kylin.jdbc.Driver"; String Kylin_Url = "jdbc:kylin://hadoop101:7070/HelloWorld"; String Kylin_User = "ADMIN"; String Kylin_Password = "KYLIN"; Class.forName(Kylin_Driver); //①添加驅動信息 Connection connection = DriverManager.getConnection(Kylin_Url, Kylin_User, Kylin_Password);//②
//③預編譯SQL PreparedStatement preparedStatement = connection.prepareStatement("select job, count(*), sum(sal) from EMP inner join DEPT ON EMP.DEPTNO = DEPT.DEPTNO group by job"); ResultSet resultSet = preparedStatement.executeQuery(); //④執行查詢 while (resultSet.next()){ //⑤遍歷打印 String job = resultSet.getString(1); int count = resultSet.getInt(2); double sum_total = resultSet.getDouble(3); System.out.println(job + "\t" + count + "\t" + sum_total); } } }
可視化工具 Zepplin安裝與啓動
1)將zeppelin-0.8.0-bin-all.tgz上傳至Linux 2)解壓zeppelin-0.8.0-bin-all.tgz之/opt/module [kris@hadoop101 sorfware]$ tar -zxvf zeppelin-0.8.0-bin-all.tgz -C /opt/module/ 3)修更名稱 [kris@hadoop101 module]$ mv zeppelin-0.8.0-bin-all/ zeppelin 4)啓動 [kris@hadoop101 zeppelin]$ bin/zeppelin-daemon.sh start 可登陸網頁查看,web默認端口號爲8080 http://hadoop101:8080
key橫座標;
values縱座標
%kylin select job, dname, count(*), sum(sal) from EMP inner join DEPT ON EMP.DEPTNO = DEPT.DEPTNO group by job, dname;
6. Cube構建優化
在構建維度數量較多的Cube時,尤爲要注意Cube的剪枝優化(即減小Cuboid的生成)。
找出問題Cube
Expansion Rate即膨脹率;
通常來講,Cube的膨脹率應該在0%~1000%之間,若是一個Cube的膨脹率超過1000%,那麼Cube管理員應當開始挖掘其中的緣由。一般,膨脹率高有如下幾個方面的緣由。
1)Cube中的維度數量較多,且沒有進行很好的Cuboid剪枝優化,致使Cuboid數量極多;
2)Cube中存在較高基數的維度,致使包含這類維度的每個Cuboid佔用的空間都很大,這些Cuboid累積形成總體Cube體積變大;
3)存在比較佔用空間的度量,例如Count Distinct,所以須要在Cuboid的每一行中都爲其保存一個較大的寄存器,最壞的狀況將會致使Cuboid中每一行都有數十KB,從而形成整個Cube的體積變大;
檢查Cube中哪些Cuboid 最終被預計算了,咱們稱其爲被物化(Materialized)的Cuboid。同時,這種方法還能給出每一個Cuboid所佔空間的估計值。因爲該工具須要在對數據進行必定階段的處理以後才能估算Cuboid的大小,所以通常來講只能在Cube構建完畢以後再使用該工具。
因爲同一個Cube的不一樣Segment之間僅是輸入數據不一樣,模型信息和優化策略都是共享的,因此不一樣Segment中哪些Cuboid被物化哪些沒有被物化都是同樣的。所以只要Cube中至少有一個Segment,那麼就能使用以下的命令行工具去檢查這個Cube中的Cuboid狀態:
[kris@hadoop101 kylin]$ bin/kylin.sh org.apache.kylin.engine.mr.common.CubeStatsReader cube_partition Sampling percentage: 100 Mapper overlap ratio: 1.0 Mapper number: 1 Length of dimension DEFAULT.EMP_PARTITION.JOB is 1 Length of dimension DEFAULT.EMP_PARTITION.MGR is 1 Length of dimension DEFAULT.EMP_PARTITION.DEPTNO is 1 Length of dimension DEFAULT.EMP_PARTITION.HIRE_DATE is 1 |---- Cuboid 1111, est row: 14, est MB: 0 |---- Cuboid 0111, est row: 14, est MB: 0, shrink: 100% |---- Cuboid 0011, est row: 14, est MB: 0, shrink: 100% |---- Cuboid 0001, est row: 13, est MB: 0, shrink: 92.86% |---- Cuboid 0010, est row: 3, est MB: 0, shrink: 21.43% |---- Cuboid 0101, est row: 14, est MB: 0, shrink: 100% |---- Cuboid 0100, est row: 7, est MB: 0, shrink: 50% |---- Cuboid 0110, est row: 9, est MB: 0, shrink: 64.29% |---- Cuboid 1011, est row: 14, est MB: 0, shrink: 100% |---- Cuboid 1001, est row: 14, est MB: 0, shrink: 100% |---- Cuboid 1000, est row: 5, est MB: 0, shrink: 35.71% |---- Cuboid 1010, est row: 9, est MB: 0, shrink: 64.29% |---- Cuboid 1101, est row: 14, est MB: 0, shrink: 100% |---- Cuboid 1100, est row: 8, est MB: 0, shrink: 57.14% |---- Cuboid 1110, est row: 10, est MB: 0, shrink: 71.43% 每一個節點表明一個Cuboid,每一個Cuboid都由一連串1或0的數字組成,若是數字爲0,則表明這個Cuboid中不存在相應的維度;若是數字爲1,則表明這個Cuboid中存在相應的維度。 最高維度1111 3個維度0111 2維 收縮比例: |---- Cuboid 0011, est row: 14, est MB: 0, shrink: 100%(至關於父維度0111是沒有收縮的,應該去掉這個節點,它和0111如出一轍) |---- Cuboid 0001, est row: 13, est MB: 0, shrink: 92.86% (相對於它的父維度收縮了,基本上沒收縮;減小的) 兩個列分組更精細即父維度更精細,子維度相比於父維度應該差異更大,若是差異很小就應該砍掉; 砍的維度越多,Cuboid越少;
構建增量cube
hive中的數據會逐漸增長,cube的構建也須要不斷執行,但每次構建cube時,都要把已分析過的舊數據和新數據都從新分析。好比,數據累加了一年,天天作一次數據更新,隨之作cube構建,則每次cube面對的數據量都在加大,第366天的分析,要面對第366天 + 以前365天的數據總和。
但願每次構建cube時,不用全量構建,即不用把全部原始hive表從新構建,而是把新增的hive數據構建一個segment便可。
見上建立項目:建立hive分區表--->module中指定分區列(分區列必須爲時間列)--->cube增量構建
hive cube -->Segment -->Segment
-->Segment ... 全量構建(full-build) 增量構建() hive cube -->Segment1(2019-2-12) -->Segment2(2019-3-12)
因爲hive中數據變動,kylin會去進行同步,同步一次叫一個segment,每次的segment就是一段一段;
cube關聯着hive表,一個cube可能關聯屢次segment,關聯一次就有一個segment
物化視圖的概念
合併
若是任由增量cube,長期生成segment,則勢必致使segment過多,聚合量過大,查詢性能太低。
因此cube管理員必須制定 segment的合併計劃,減小segment數量!
手動合併
在cube中選擇"build"的菜單位置,選擇"merge"便可觸發手動合併;
以後能夠選擇要合併的時間區間,提交任務便可
自動合併
經過在cube中設置閾值,讓cube自動觸發segment合併
自動合併(從大到小,如先看28天再看7天;7天合併1次,28天合併一次)作按期的合併
若是有時間跨度達到28天就合併1次;
例如每4天作1次構建,合併一次,作完第7次的構建以後,它和前6次的段就佔滿了28天,第7次時就佔滿了28天的間隔,則Segment合併一次;
當沒有知足跨度達到28天,再判斷有沒有連續佔滿7天的,(它是會先檢查大的,大的28天沒有,若是7天知足了,就合併);每出現1次新的Segment就會去判斷一次;
Retention Threshold中默認值爲0,意思是,不丟棄任何segment;如改成20,保留最近20天的Segment,不在這個區間的就捨棄;
構建以前優化:砍掉 Cuboid
優化核心即剪掉不必的cuboid,把它的數量減小點就會更快
① 聚合組Aggregation Groups
默認的包含全部的維度,即最全的立方體; 聚合組之間不交叉
根據業務的維度組合,劃分出具備強依賴的組合,這些組合稱之爲聚合組,在聚合組內,維度之間的組合會預計算,聚合組之間並不交叉預計算,從而減小Cuboid的數量.
若是用戶僅僅關注維度 AB 組合和維度 CD 組合 那麼該 Cube 則能夠被分化成兩個聚合組,分別是聚合組 AB 和聚合組 CD
② 層級維度Hierarchy Dimensions:
層級之間是包含關係
保留比較全的維度,其餘的子節點就砍掉;
層級維度是在聚合組內選的;cube的構建是以聚合組爲單位的,有幾個聚合組就決定了全部Cuboid組合的程度
只有聚合組中的維度纔會進行組合;根據層級設置,立方體會去剪掉多餘的Cuboid;保留全的維度,剪掉子維度;
用戶選擇的維度中經常會出現具備層級關係的維度。例如對於國家(country)、省份(province)和城市(city)這三個維度,從上而下來講國家/省份/城市之間分別是一對多的關係。
也就是說,用戶對於這三個維度的查詢能夠歸類爲如下三類: 1. group by country 2. group by country, province(等同於group by province) 3. group by country, province, city(等同於 group by city) 若是ABCD 四個維度中ABC這三個被設置爲層級維度, abc=ac=bc 則 abcd=acd=bcd,因此剪掉acd,bcd,保留abcd足以, 則最終生成的cube:
③ 強制維度Mandatory Dimensions
在全部的維度組合內都有有這個強制維度
若是發如今全部運算中,都會涉及某個維度,則此維度能夠被設置爲強制維度。
假設共有3個維度:A B C
-
通常狀況下的維度組合爲以下左圖,共有8中可能,則有8次運算;
-
但若是正真會被用到的運算中都包含A維度,並把A設置爲前置維度,則維度組合爲以下右圖,
共需4次運算;
在後續的查詢中是否每次group by都會包含某維度
④ 聯合維度Joint Dimensions:
A B C爲聯合維度,3個維度在一塊纔有意義;
用戶有時並不關心維度之間各類細節的組合方式,例如用戶的查詢語句中僅僅會出現 group by A, B, C,而不會出現 group by A, B 或者 group by C 等等這些細化的維度組合。這一類問題就是聯合維度所解決的問題。例如將維度 A、B 和 C 定義爲聯合維度,Apache Kylin 就僅僅會構建 Cuboid ABC,而 Cuboid AB、BC、A 等等Cuboid 都不會被生成。
A B C爲聯合維度,則要麼都在,要麼都不在,以下圖,最終的Cuboid 數目從 16 減小到 4。
⑤ 衍生(推導)維度:
這類維度的意思是可推導的維度,須要該維度對應的一個或者多個列能夠和維度表的主鍵是一對一的,這種維度能夠大大減小cuboid個數
Fact表:A(a,b,c)
Lookup表:B(x,y,z)
若是維度c中,每種狀況都惟一對應一種 x,y。即 abc==abxy,或者說全部xy的組合均可以替換爲c。
因此能夠將 x,y 設置爲derived維度,能夠減小cuboid的個數。
在查詢時:select xx from xx group by x,y;會被kylin等價轉換爲select ... group by c;
A
B C
衍生(推導)維度必須來自從表(維表)
強映射
normal維度來自主表
derived從表的維度默認會被外鍵(與主鍵一一對應)推導出來;若是在某種狀況下不合理能夠改edit改成normal
推導維度不必選聚合組,默認也不會讓咱們選,;