日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

kylin调优,项目中错误总结,知识点总结,kylin jdbc driver + 数据库连接池druid + Mybatis项目中的整合,shell脚本执行kylin restapi 案例

發布時間:2024/9/27 数据库 23 豆豆

關于本篇文章的說明:
本篇文章為筆者辛苦勞作用了一整天總結出來的文檔,大家閱讀轉發的時候請不要吝嗇寫上筆者:涂作權 和 原文地址。

由于筆者所在環境沒有人用過kylin,筆者也是自學官網,閱讀書籍 將kylin用于實際項目,期間遇到了很多很多關于kylin使用的問題。為了讓后面的人在使用kylin實踐的時候能夠少走彎路,在此生成kylin的調優,錯誤總結,知識點文檔,這篇文檔應該是目前網上最全的kylin調優和總結文檔了(除了官網)。

以下文章內容主要來自官網,書籍,博文,網友,社區,同學,以及實際項目。

1 調優方案

1.1 調優:如何提高訪問連接并發(運維層面)

根據書籍中的介紹,kylin單個的實例,支持的訪問連接并發是70個左右,所以,為了讓kylin能夠支持更多的訪問并發,可以通過增加實例的方式實現。將單實例的Kylin變成集群方式,增加query節點的個數。
官網介紹的方式:
http://kylin.apache.org/docs/install/kylin_cluster.html

說明:
A:假設有3臺機器,分別是machine1,machine2,machine3。其中Machine的運行模式是all(即擁有 執行job+執行query的角色 (個人理解)),另外的machine2和machine3為query(主要用于查詢)。
B:注意,kylin2.0以后,kylin支持了多個job的方式,具體方式可以參考文檔進行相關配置。

1.2 調優:解決kylin預處理過程gc問題(運維層面)

Kylin是基于預處理技術,如果公司資金雄厚,服務器配置高,內存大,那就不要吝嗇內存了。給kylin足夠的內存分配,能夠減少很多問題。

如果處理的好,可以結合任務調度系統,比如azkaban,通過shell的方式將kylin的內存在數據處理空閑的時候,將內存多分配給kylin。

關于此部分的介紹,官網給出的建議是:
http://kylin.apache.org/docs/install/configuration.html

Allocate More Memory for Kylin There are two sample settings for KYLIN_JVM_SETTINGS are given in $KYLIN_HOME/conf/setenv.sh. The default setting use relatively less memory. You can comment it and then uncomment the next line to allocate more memory for Kyligence Enterprise. The default configuration is:export KYLIN_JVM_SETTINGS="-Xms1024M -Xmx4096M -Xss1024K -XX:MaxPermSize=512M -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$KYLIN_HOME/logs/kylin.gc.$$ -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=64M" # export KYLIN_JVM_SETTINGS="-Xms16g -Xmx16g -XX:MaxPermSize=512m -XX:NewSize=3g -XX:MaxNewSize=3g -XX:SurvivorRatio=4 -XX:+CMSClassUnloadingEnabled -XX:+CMSParallelRemarkEnabled -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode -XX:CMSInitiatingOccupancyFraction=70 -XX:+UseCMSInitiatingOccupancyOnly -XX:+DisableExplicitGC -XX:+HeapDumpOnOutOfMemoryError -verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps -Xloggc:$KYLIN_HOME/logs/kylin.gc. $$ -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=10 -XX:GCLogFileSize=64M"

筆者配置:

[xxx conf]# pwd /data/installed/apache-kylin-2.3.1-bin/conf [xxxx conf]# vim setenv.sh

1.3 調優+錯誤總結:配置build引擎支持Spark (運維層面)

在kylin中支持以Spark作為預處理的方式,在內存足夠的情況下,建議配置build引擎。使用Spark,默認的build引擎使用的是mapreduce.

由于筆者使用的hadoop版本是3.0.1(原生),當前最高版本是:v2.5.2,發現使用Kylin的時候,會報jar沖突問題,因為我環境使用的是3.x的jar包,但是在kylin發行版本目前還使用的是基于hadoop2.x的Spark。所以失敗了。

但是,若使用的是CDH,可以使用,apache-kylin-2.5.2-bin-cdh60.tar.gz for beta版本進行安裝試用。

支持Spark的配置:http://kylin.apache.org/docs/tutorial/cube_spark.html,關于具體步驟,本文不進行詳細敘述。

1.4 調優:kylin出現reduce階段內存異常問題(hadoop運維層面)

在kylin執行cube build的過程中,可能會出現內存溢出的問題,這個問題其中一個原因是hadoop的虛擬參數配置不合理導致的。
這里在$HADOOP_HOME/etc/Hadoop/yarn-site.xml 中的配置類似如下:

<!--是否啟動一個線程檢查每個任務正使用的虛擬內存量,如果任務超出分配值,則直接將其殺掉,默認是true--> <property><name>yarn.nodemanager.vmem-check-enabled</name><value>false</value> </property> <!-- 任務每使用1MB物理內存,最多可使用虛擬內存,默認是2.1 --> <property><name>yarn.nodemanager.vmem-pmem-ratio</name><value>5</value> </property><!-- 每個節點可用內存,單位MB --> <property><name>yarn.nodemanager.resource.memory-mb</name><!--<value>16384</value>--><value>20480</value><discription>每個節點可用內存,單位MB</discription> </property><!-- 單個任務可申請最少內存,默認1024MB --> <property><name>yarn.scheduler.minimum-allocation-mb</name><value>1024</value> </property><!-- 單個任務可申請最大內存,默認8192MB --> <property><name>yarn.scheduler.maximum-allocation-mb</name><!--<value>16384</value>--><value>20480</value> </property>

yarn.nodemanager.vmem-pmem-ratio :虛擬內存大小的一個系數,通過調整這個參數,可以增大虛擬內存的值,避免kylin在cube build的過程中出現失敗。

此外,也要調整:$HADOOP_HOME/etc/Hadoop/mapred-site.xml中如下的值:

<property><name>mapreduce.map.java.opts</name><!--<value>-Xms3g -Xmx6g</value>--><value>-Xms3g -Xmx10g</value> </property> <property><!-- mapreduce.reduce.java.opts 這個值一般是mapreduce.map.java.opts的兩倍 --><name>mapreduce.reduce.java.opts</name><!--<value>-Xms6g -Xmx12g</value>--><value>-Xms6g -Xmx16g</value> </property><!-- 每個Map任務的物理內存限制,這個值 * yarn.nodemanager.vmem-pmem-ratio 就是虛擬內存的大小--> <property><name>mapreduce.map.memory.mb</name><!--<value>6144</value>--><value>10240</value> </property> <property><name>mapreduce.reduce.input.buffer.percent</name><value>0.5</value> </property><!-- 每個Reduce任務的物理內存限制,一般還是機器內存的80% --> <property><name>mapreduce.reduce.memory.mb</name><!--<value>12288</value>--><value>16384</value> </property>

其中官網的介紹是:

1.5 將cuboid數據轉為HFile

這一步啟動一個MR任務來講cuboid文件(序列文件格式)轉換為HBase的HFile格式。Kylin通過cube統計數據計算HBase的region數目,默認情況下每5GB數據對應一個region。Region越多,MR使用的reducer也會越多。如果你觀察到reducer數目較小且性能較差,你可以將“conf/kylin.properties”里的以下參數設小一點,比如:

kylin.hbase.region.cut=2 kylin.hbase.hfile.size.gb=1

如果你不確定一個region應該是多大時,聯系你的HBase管理員。

1.6 調優:解決kylin cube過程中的hive小文件問題(運維層面)

Kylin中自帶文件合并,下面的過程可以考慮設置(這個筆者沒有驗證過,有的博文中建議下面方式進行設置,但是官網是另外一種說法)
官網:

一些博文上的寫法:

[xxx conf]# pwd /xxxx/apache-kylin-2.3.1-bin/conf [xxxx conf]# vim kylin_hive_conf.xml

該文件原本的配置如下:

<property><name>hive.merge.mapfiles</name><value>false</value><description>Disable Hive's auto merge</description> </property><property><name>hive.merge.mapredfiles</name><value>false</value><description>Disable Hive's auto merge</description> </property>

修改成:

<property><name>hive.merge.mapfiles</name><value>true</value><description>Enable Hive's auto merge</description> </property><property><name>hive.merge.mapredfiles</name><value>true</value><description>Enable Hive's auto merge</description> </property>

1.7 調優:hive建表過程(數倉層面)

kylin使用的是一種預處理方式,這種方式有別于hive、spark-sql、presto、hbase、impala、druid等的即時查詢方案,kylin能夠在機器內存配置較少的情況下完成多維查詢,對于有多維分析需求(OLAP)的項目,是一個很不錯的選擇。

但是,不要覺得kylin在調優過程中只要保證了kylin的model和cube創建的好就能夠提升kylin的大大效率。對于kylin的數據來源hive中的hive表創建不好,會導致kylin cube build過程很漫長,這個筆者深有體會,優化的好的能夠將build過程由1天多減少到分鐘級別。

使用kylin進行多維查詢,能夠讓不熟悉HBASE二級索引,預分區,HBASE調優,協處理等的開發人員減少很多時間。

在此,筆者建議kylin的hive數據表在創建的時候增加分區(partitioned),筆者的與分區格式類似如下:

drop table if exists tb_table; CREATE TABLE IF NOT EXISTS tb_table ( Xxxxxxx 此處建表語句略去, addTime bigint comment '數據生成的時間,時間戳,秒值', createDate bigint comment '創建天,時間格式為yyyyMMdd的integer值,由addTime通過from_unixtime(actionTime,'yyyyMMdd') as createDate 得出' ) partitioned by(pt_createDate integer comment '創建天,時間格式為yyyyMMdd的integer值,分區時間') ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' STORED AS TEXTFILE;

其中pt_createDate 是數據入庫時間。這個值很重要,在建立Model的時候,一定要使用這個時間作為partition,而不要使用數據生成時間createDate,否則可能會出現hive中的數據在kylin增量預處理之后,kylin的數據條數小于hive的數據條數,導致分析結果偏少的問題。

1.8 調優:hive表數據類型導致kylin統計如sum出錯的問題(數倉層面)

在hive進行sum的時候,有時候發現不管怎么設置,數據值總是1或者一些莫名其妙的值,導致這個現象的其中一個原因就是使用了hive中一個數據類型定義為tinyint的列作為度量列。所以,在使用hive建表的時候,可以將這種字段設置成integer,然后再進行處理,發現結果正確了。
類似:

is_active_member integer comment '是否是活躍會員,1:是,0不是', 由之前的tinyint改成integer

1.9 調優:group by 字段值,計算每個分組sum的查詢速度調優(數倉層面)

kylin有一個坑,可能是設計問題,就是kylin對sum(case when 字段列 then 1 else 0 end) totalNum的支持很爛,它不支持。

為了處理這種場景,建議對所有以上場景或者類似group by然后計算sum結果的場景,都在數據處理結果,將這種結果1 or 0的狀態計算好,存儲在hive表中。類似筆者的一個Spark sql程序片段:

spark.sql("INSERT INTO TABLE tb_table partition(pt_createDate=" + pt_createDate + ") " +"SELECT " +" (case when st.registWay=10 then 1 else 0 end) as selfRegiste," +" (case when st.registWay=20 then 1 else 0 end) as agentRegiste," +" (case when st.registWay=30 then 1 else 0 end) as youxShopRegiste," +" (case when st.registWay=40 then 1 else 0 end) as salesmanRegiste," +" (case when st.registWay=50 then 1 else 0 end) as headShopRegiste," +" from_unixtime(registTime,'yyyyMMdd') as createDate " +"FROM " +" tb_table_temp "); spark.stop();

也就是說將registWay 的分組求總和統計變成 selfRegiste 、agentRegiste 、youxShopRegiste、salesmanRegiste、headShopRegiste 的sum求和。通過這種方式之后,發現項目查詢速度有很大的提升,可能有原來的n秒級,變成毫秒級別。

1.10 調優:使用和hive相同的partition column

在創建model的時候,指定類似如下的分區列:

使用增量build cube的方式。

1.11 調優:定期清理Kylin cube build過程中產生的中間文件

在kylin 在cube build過程中會產生很多臨時文件,現象是:在hdfs中的/hbase/data/default,會產生很多時間為過往時間的文件,

可以使用一下命令查看磁盤占用大小:

[xxxx apache-kylin-2.3.1-bin]# hdfs dfs -du -s -h /hbase/data/default WARNING: HADOOP_PREFIX has been replaced by HADOOP_HOME. Using value of HADOOP_PREFIX.## 13.1 G 35.9 G /hbase/data/default [xxxx apache-kylin-2.3.1-bin]#

其中:13.1 G 表示的是一個節點中暫用磁盤的大小,35.9 G

如果這個臨時中間文件不處理,最終將導致http://namenodeip:hdfs對應的port/dfshealth.html#tab-datanode:

官網介紹:
Kylin 在構建 cube 期間會在 HDFS 上生成中間文件;除此之外,當清理/刪除/合并 cube 時,一些 HBase 表可能被遺留在 HBase 卻以后再也不會被查詢;雖然 Kylin 已經開始做自動化的垃圾回收,但不一定能覆蓋到所有的情況;你可以定期做離線的存儲清理:
步驟:
1. 檢查哪些資源可以清理,這一步不會刪除任何東西:

export KYLIN_HOME=/path/to/kylin_home ${KYLIN_HOME}/bin/kylin.sh org.apache.kylin.tool.StorageCleanupJob --delete false

請將這里的 (version) 替換為你安裝的 Kylin jar 版本。
2. 你可以抽查一兩個資源來檢查它們是否已經沒有被引用了;然后加上“–delete true”選項進行清理。

${KYLIN_HOME}/bin/kylin.sh org.apache.kylin.tool.StorageCleanupJob --delete true

完成后,Hive 里的中間表, HDFS 上的中間文件及 HBase 中的 HTables 都會被移除。
3. 如果您想要刪除所有資源;可添加 “–force true” 選項:

${KYLIN_HOME}/bin/kylin.sh org.apache.kylin.tool.StorageCleanupJob --force true --delete true

完成后,Hive 中所有的中間表, HDFS 上所有的中間文件及 HBase 中的 HTables 都會被移除。

1.12 調優:減少Cube Dimensions維度數

做多維數據分析的時候,一般都要涉及到SQL,在這個過程中適當控制一些SQL,使用盡可能少的字段列以實現相同的數據查詢需求。
因為維度列越多,cuboid的數量越多,需要的內存越多,cube build的時候時間也越長,生成的數據也越大。對于有n個維度的cube,組合字后會產生22…*(第n個2)體量的數據。
也就是說減少如下的Dimensions數量:

1.13 調優:定義measure列

對于定義measure,結果將在cube build前就預處理好,作為度量列的字段不要在Cube的Dimensions中出現,以減少Cuboid的數量 。這里包括兩處:
A:Model創建過程中指定好Measures列,例如:

B:增加Cube Measures列的值

1.14 調優+錯誤總結:解決sum的時候結果莫名其妙的問題

出現這個現象的原因是在該定義measure的列上沒有定義相關的度量值。具體添加方式如上面的:定義measure列

1.15 調優:定期merge cube

在kylin的model下的cube后見面的:

另外:設置好合適的Merge周期

1.16 調優:對于維度多于12個場景

在Advanced Setting中對維度進行Aggregation Groups分組。
也就是說在下面的維度列進行分組設置。

每組只填寫好真正需要的維度列。添加新的分組的時候,可以使用:

在設置的時候一定要記著2的n次方這個問題。盡可能減少n(維度數量)這個值。

1.17 調優:創建中間平表(來自官網)

這一步將數據從源Hive表提取出來(和所有join的表一起)并插入到一個中間平表。如果Cube是分區的,Kylin會加上一個時間條件以確保只有在時間范圍內的數據才會被提取。你可以在這個步驟的log查看相關的Hive命令,比如:

hive -e "USE default; DROP TABLE IF EXISTS kylin_intermediate_airline_cube_v3610f668a3cdb437e8373c034430f6c34;CREATE EXTERNAL TABLE IF NOT EXISTS kylin_intermediate_airline_cube_v3610f668a3cdb437e8373c034430f6c34 (AIRLINE_FLIGHTDATE date,AIRLINE_YEAR int,AIRLINE_QUARTER int,...,AIRLINE_ARRDELAYMINUTES int) STORED AS SEQUENCEFILE LOCATION 'hdfs:///kylin/kylin200instance/kylin-0a8d71e8-df77-495f-b501-03c06f785b6c/kylin_intermediate_airline_cube_v3610f668a3cdb437e8373c034430f6c34';SET dfs.replication=2; SET hive.exec.compress.output=true; SET hive.auto.convert.join.noconditionaltask=true; SET hive.auto.convert.join.noconditionaltask.size=100000000; SET mapreduce.job.split.metainfo.maxsize=-1;INSERT OVERWRITE TABLE kylin_intermediate_airline_cube_v3610f668a3cdb437e8373c034430f6c34 SELECT AIRLINE.FLIGHTDATE ,AIRLINE.YEAR ,AIRLINE.QUARTER ,... ,AIRLINE.ARRDELAYMINUTES FROM AIRLINE.AIRLINE as AIRLINE WHERE (AIRLINE.FLIGHTDATE >= '1987-10-01' AND AIRLINE.FLIGHTDATE < '2017-01-01');

在Hive命令運行時,Kylin會用conf/kylin_hive_conf.properties里的配置,比如保留更少的冗余備份和啟用Hive的mapper side join。需要的話可以根據集群的具體情況增加其他配置。

如果cube的分區列(在這個案例中是”FIGHTDATE”)與Hive表的分區列相同,那么根據它過濾數據能讓Hive聰明地跳過不匹配的分區。因此強烈建議用Hive的分區列(如果它是日期列)作為cube的分區列。這對于那些數據量很大的表來說幾乎是必須的,否則Hive不得不每次在這步掃描全部文件,消耗非常長的時間。

1.18 調優:重新分發中間表(來自官網)

在之前的一步之后,Hive在HDFS上的目錄里生成了數據文件:有些是大文件,有些是小文件甚至空文件。這種不平衡的文件分布會導致之后的MR任務出現數據傾斜的問題:有些mapper完成得很快,但其他的就很慢。針對這個問題,Kylin增加了這一個步驟來“重新分發”數據,這是示例輸出:

total input rows = 159869711 expected input rows per mapper = 1000000 num reducers for RedistributeFlatHiveTableStep = 160

重新分發表的命令:

hive -e "USE default; SET dfs.replication=2; SET hive.exec.compress.output=true; SET hive.auto.convert.join.noconditionaltask=true; SET hive.auto.convert.join.noconditionaltask.size=100000000; SET mapreduce.job.split.metainfo.maxsize=-1; set mapreduce.job.reduces=160; set hive.merge.mapredfiles=false;INSERT OVERWRITE TABLE kylin_intermediate_airline_cube_v3610f668a3cdb437e8373c034430f6c34 SELECT * FROM kylin_intermediate_airline_cube_v3610f668a3cdb437e8373c034430f6c34 DISTRIBUTE BY RAND(); "

首先,Kylin計算出中間表的行數,然后基于行數的大小算出重新分發數據需要的文件數。默認情況下,Kylin為每一百萬行分配一個文件。在這個例子中,有1.6億行和160個reducer,每個reducer會寫一個文件。在接下來對這張表進行的MR步驟里,Hadoop會啟動和文件相同數量的mapper來處理數據(通常一百萬行數據比一個HDFS數據塊要小)。如果你的日常數據量沒有這么大或者Hadoop集群有足夠的資源,你或許想要更多的并發數,這時可以將conf/kylin.properties里的kylin.job.mapreduce.mapper.input.rows設為小一點的數值,比如:

kylin.job.mapreduce.mapper.input.rows=500000

其次,Kylin會運行 “INSERT OVERWRITE TABLE … DISTRIBUTE BY “ 形式的HiveQL來分發數據到指定數量的reducer上。

在很多情況下,Kylin請求Hive隨機分發數據到reducer,然后得到大小相近的文件,分發的語句是”DISTRIBUTE BY RAND()”。

如果你的cube指定了一個高基數的列,比如”USER_ID”,作為”分片”維度(在cube的“高級設置”頁面),Kylin會讓Hive根據該列的值重新分發數據,那么在該列有著相同值的行將被分發到同一個文件。這比隨機要分發要好得多,因為不僅重新分布了數據,并且在沒有額外代價的情況下對數據進行了預先分類,如此一來接下來的cube build處理會從中受益。在典型的場景下,這樣優化可以減少40%的build時長。在這個案例中分發的語句是”DISTRIBUTE BY USER_ID”:

請注意: 1)“分片”列應該是高基數的維度列,并且它會出現在很多的cuboid中(不只是出現在少數的cuboid)。 使用它來合理進行分發可以在每個時間范圍內的數據均勻分布,否則會造成數據傾斜,從而降低build效率。典型的正面例子是:“USER_ID”、“SELLER_ID”、“PRODUCT”、“CELL_NUMBER”等等,這些列的基數應該大于一千(遠大于reducer的數量)。 2)”分片”對cube的存儲同樣有好處,不過這超出了本文的范圍。

1.19 調優:提取事實表的唯一列(來自官網)

在這一步驟Kylin運行MR任務來提取使用字典編碼的維度列的唯一值。
實際上這步另外還做了一些事情:通過HyperLogLog計數器收集cube的統計數據,用于估算每個cuboid的行數。如果你發現mapper運行得很慢,這通常表明cube的設計太過復雜,請參考

優化cube設計來簡化cube。如果reducer出現了內存溢出錯誤,這表明cuboid組合真的太多了或者是YARN的內存分配滿足不了需要。如果這一步從任何意義上講不能在合理的時間內完成,你可以放棄任務并考慮重新設計cube,因為繼續下去會花費更長的時間。

你可以通過降低取樣的比例(kylin.job.cubing.inmen.sampling.percent)來加速這個步驟,但是幫助可能不大而且影響了cube統計數據的準確性,所有我們并不推薦。

1.20 調優:構建維度字典(來自官網)

有了前一步提取的維度列唯一值,Kylin會在內存里構建字典。通常這一步比較快,但如果唯一值集合很大,Kylin可能會報出類似“字典不支持過高基數”。對于UHC類型的列,請使用其他編碼方式,比如“fixed_length”、“integer”等等。

1.21 調優:構建基礎cuboid,調整map大小 和reduce的數量

這一步用Hive的中間表構建基礎的cuboid,是“逐層”構建cube算法的第一輪MR計算。Mapper的數目與第二步的reducer數目相等;Reducer的數目是根據cube統計數據估算的:默認情況下每500MB輸出使用一個reducer;如果觀察到reducer的數量較少,你可以將kylin.properties里的“kylin.job.mapreduce.default.reduce.input.mb”設為小一點的數值以獲得過多的資源,比如:

kylin.job.mapreduce.default.reduce.input.mb=200

1.22 調優:設置好Mandatory Dimensions 列

這種維度意味著每次查詢的group by中都會攜帶的,將某一個dimension設置為mandatory可以將cuboid的個數減少一半

因為我們確定每一次group by都會攜帶字段A,將A設置成Mandatory Dimensions后,那么就可以省去所有不包含A這個維度的cuboid了

好的技術文章:
http://kyligence.io/zh/2017/04/21/apache-kylin-advanced-setting-mandatory-dimension-principle/

1.23 調優:設置Joint Dimensions

很好的一篇博文:
http://kyligence.io/zh/2017/04/07/apache-kylin-advanced-setting-joint-dimension-principle/

1.24 調優:設置Hierarchy Dimension

以下文章很好的介紹了如何關于Hierarchy Dimension的調優策略

http://kyligence.io/zh/2017/04/14/apache-kylin-advanced-setting-hierarchy-dimension-principle/

1.25 調優:Configuration Overwrites 高級設置

參考官網更詳細介紹:
http://kylin.apache.org/cn/docs/install/advance_settings.html

另外在里面最好設置數據壓縮方式,以減少磁盤占用

1.26 調優:改變kylin中Advanced Setting的維度順序

對于kylin中頻繁使用,或著一定使用的維度列,在設置Includes的時候,將這些配置的靠前一些。因為kylin內部機制是越靠前的越優先被找到,從而加快查詢速度。

就是上面紅色區域的維度列的順序。

1.27 調優:Build Cube With Spark

kylin.engine.spark.rdd-partition-cut-mb = 10 (默認 200)

直接影響 spark 的分區數,首先大概清楚 cuboid 數據總大小,例如 6032mb,那么 partitions = 6032/10 = 600,即會產生 600 個小文件,隨后在 step8 跑 mr 時,就會拉起 600 個 map,使得 服務器負載驟增,發生報警。

調整參數后執行,如何跟蹤服務器情況?只需跟蹤 step8 的 mr 情況即可
① http://bgnode1:8088/cluster/scheduler 找到對應的 application
② %of Cluster 是否過高
③ 進入詳情查看 map 數量是否過多,若過多則很可能是 rdd-partition-cut-mb 設置過 小導致,此時要調大參數 因此,合理的調整 rdd-partition-cut-mb 能防止機器報警。 這一步是對每一層的 cuboid 依次進行計算并寫入 hdfs,耗時會比較長

kylin.engine.spark-conf.spark.executor.cores = 2 kylin.engine.spark-conf.spark.executor.memory = 4G

這兩個參數自行根據數據大小來調整,cores 和 memory 都不是越大越好,需根據要 build 的數據量,再三調整測試最優值。

1.28 調優:Rowkey調優

為什么要優化 Rowkey? Apache Kylin 使用 HBase 做為 Cube 的存儲引擎。而 HBase 是 Key-Value 數據庫,這個 Key 在 HBase 中稱為 Rowkey。為了能夠支持按多個維度進行查詢,Kylin 需要將多個維度值以某 種次序組成 Rowkey。HBase Scan Range,排在 Rowkey 靠前部分的維度,將比排在靠后部分 的維度更易于做篩選,查詢效率更高。

那些維度適合排在前部分?

  • 基數高的排前面 在 Load Hive Table 時,勾選 Calculate column cardinality,即可在 load 時計算各字段的基 數,并在 Data Source -> Tables -> 點擊相應的 table 查看
  • 1.29 調優:在查詢中被用做過濾條件的維度放在非過濾條件維度的前面

    這一個環節如果 rowkey 沒設計好,會導致以下問題:

  • Cuboid 轉 hfile 后,會因數據分布不均勻,導致單點問題,使得服務器內存過高,觸發報 警
  • Hbase 尋址慢,查詢性能下降 除了各維度在 Rowkey 上的次序外,維度的編碼方法對于空間占用及查詢性能也有著顯 著的影響。 合適的編碼能減少維度對空間的占用,同時編碼值也會加速查詢過濾。
  • 1.30 調優:羅列幾個顯著影響性能的參數

    以下都是默認值:

    kylin.engine.spark.rdd-partition-cut-mb = 10
    kylin.engine.spark-conf.spark.executor.memory = 4G
    kylin.storage.hbase.region-cut-gb = 5

    官網提供的可設置參數:http://kylin.apache.org/docs/install/configuration.html

    1.31 調優:其它調優思路

    通過./kylin.sh org.apache.kylin.engine.mr.common.CubeStatsReader [cubeName] 查看 cuboid 總大小,然后再根據以下步驟進行對參數的調整:

    1. 3 種降維選項是否有根據業務實際情況調整 2. 有沒合理的使用分區列 3. 小文件是否過多 4. reducer 是否過少 5. spark partitions 是否合適 6. spark 的 excutor 內存和 cores 數量分配是否合理 7. cuboid 文件轉 hfile 時,map 是否過多,reducer 是否過少(region 塊的大小和數量是否合 理)

    1.32 調優:輸出壓縮(來自官網)

    使用 Snappy 壓縮 HBase Cube:

    另一個選項為 Gzip:

    壓縮輸出的結果為:

    Snappy 和 Ggzip 的區別在時間上少于 1% 但是在大小上有 18% 差別

    1.33 調優:壓縮Hive表(來自官網)

    時間分布如下:

    按概念分組的詳細信息 :

    67 % 用來 build / process flat 表且遵守 30% 用來 build cube
    大量時間用在了第一步。
    這種時間分布在有很少的 measures 和很少的 dim (或者是非常優化的) 的 cube 中是很典型的
    嘗試在 Hive 輸入表中使用 ORC 格式和壓縮(Snappy):

    前三步 (Flat Table) 的時間已經提升了一半。
    其他列式格式可以被測試:

    ? ORC
    ? 使用 Snappy 的 ORC 壓縮
    但結果比使用 Sequence 文件的效果差。
    請看:Shaofengshi in MailList 關于這個的評論
    第二步是重新分配 Flat Hive 表:

    是一個簡單的 row count,可以做出兩個近似值

    • 如果其不需要精確,fact 表的 row 可以被統計→ 這可以與步驟 1 并行執行 (且 99% 的時間將是精確的)

      ? 將來的版本中 (KYLIN-2165 v2.0),這一步將使用 Hive 表數據實現。

    1.34 調優:Hive 表 (失敗) 分區(來自官網)

    Rows 的分布為:

    TableROWS
    Fact Table3.900.00
    Dim2.100

    build flat 表的查詢語句 (簡單版本):

    SELECT ,DIM_DATE.X ,DIM_DATE.y ,FACT_POSICIONES.BALANCE FROM FACT_POSICIONES INNER JOIN DIM_DATE ON ID_FECHA = .ID_FECHA WHERE (ID_DATE >= '2016-12-08' AND ID_DATE < '2016-12-23')

    這里存在的問題是,Hive 只使用 1 個 Map 創建 Flat 表。重要的是我們要改變這種行為。解決方案是在同一列將 DIM 和 FACT 分區
    ? 選項 1:在 Hive 表中使用 id_date 作為分區列。這有一個大問題:Hive metastore 意味著幾百個分區而不是幾千個 (在 Hive 9452 中有一個解決該問題的方法但現在還未完成)
    ? 選項 2:生成一個新列如 Monthslot。

    為 dim 和 fact 表添加同一個列
    現在,用這個新的條件 join 表來更新數據模型

    生成 flat 表的新查詢類似于:

    SELECT *FROM FACT_POSICIONES **INNER JOIN** DIM_DATE ON ID_FECHA = .ID_FECHA AND MONTHSLOT=MONTHSLOT

    用這個數據模型 rebuild 新 cube
    結果,性能更糟了 😦。嘗試了幾種方法后,還是沒找到解決方案

    問題是分區沒有被用來生成幾個 Mappers

    (我和 ShaoFeng Shi 檢查了這個問題。他認為問題是這里只有很少的 rows 而且我們不是使用的真實的 Hadoop 集群。請看這個 tech note)。
    結果摘要

    調整進度如下:

    • Hive 輸入表壓縮了
    • HBase 輸出壓縮了
    • 應用了 cardinality (Joint,Derived,Hierarchy 和 Mandatory) 減少的技術
    • 為每一個 Dim 個性化 Dim 編碼器并選擇了 Dim 在 Row Key 中最好的順序
      現在,這里有三種類型的 cubes:
    • 在 dimensions 中使用低 cardinality 的 Cubes(如 cube 4,大多數時間用在 flat 表這一步)
    • 在 dimensions 中使用高 cardinality 的 Cubes(如 cube 6,大多數時間用于 Build cube,flat 表這一步少于 10%)
    • 第三種類型,超高 cardinality (UHC) 其超出了本文的范圍

    1.35 調優:用高 cardinality Dimensions 的 Cube


    在這個用例中 72% 的時間用來 build Cube
    這一步是 MapReduce 任務,您可以在 > 看 YARN 中關于這一步的日志
    Map – Reduce 的性能怎樣能提升呢? 簡單的方式是增加 Mappers 和 Reduces (等于增加了并行數) 的數量。

    注意: YARN / MapReduce 有很多參數配置和適應您的系統。這里的重點只在于小部分。
    (在我的系統中我可以分配 12 – 14 GB 和 8 cores 給 YARN 資源):
    ? yarn.nodemanager.resource.memory-mb = 15 GB
    ? yarn.scheduler.maximum-allocation-mb = 8 GB
    ? yarn.nodemanager.resource.cpu-vcores = 8 cores
    有了這些配置我們并行列表的最大理論級別為 8。然而這里有一個問題:“3600 秒后超時了”

    參數 mapreduce.task.timeout (默認為 1 小時) 定義了 Application Master (AM) 在沒有 ACK of Yarn Container 的情況下發生的最大時間。一旦這次通過了,AM 殺死 container 并重新嘗試 4 次 (都是同一個結果)
    問題在哪? 問題是 4 個 mappers 啟動了,但每一個 mapper 需要超過 4 GB 完成
    ? 解決方案 1:增加 RAM 給 YARN
    ? 解決方案 2:增加在 Mapper 步驟中使用的 vCores 數量來減少 RAM 使用
    ? 解決方案 3:您可以通過 node 為 YARN 使用最大的 RAM(yarn.nodemanager.resource.memory-mb) 并為每一個 container 使用最小的 RAM 進行實驗(yarn.scheduler.minimum-allocation-mb)。如果您為每一個 container 增加了最小的 RAM,YARN 將會減少 Mappers 的數量。

    在最后兩個用例中結果是相同的:減少并行化的級別 ==>

    • 現在我們只啟動 3 個 mappers 且同時啟動,第四個必須等待空閑時間
    • 3 個 mappers 將 ram 分散在它們之間,結果它們就會有足夠的 ram 完成 task
      一個正常的 “Build Cube” 步驟中您將會在 YARN 日志中看到相似的消息:

      如果您沒有周期性的看見這個,也許您在內存中遇到了瓶頸。

    1.36 調優:提升 cube 響應時間

    我們嘗試使用不同 aggregations groups 來提升一些非常重要 Dim 或有高 cardinality 的 Dim 的查詢性能。
    在我們的用例中定義 3 個 Aggregations Groups:

  • “Normal cube”
  • 使用日期 Dim 和 Currency 的 Cube(就像 mandatory)
  • 使用日期 Dim 和 Carteras_Desc 的 Cube(就像 mandatory)



    比較未使用 / 使用 AGGs:

    使用多于 3% 的時間 build cube 以及 0.6% 的 space,使用 currency 或 Carteras_Desc 的查詢會快很多。
  • 1.37 調優:將多表的查詢業務處理成寬表查詢

    在kylin中,將多表的統計分析轉變成寬表的統計分析,經過驗證,發現效率有相當大的提升。也就是說,將之前分布在多個表中的數據,最終經過拉平,從不同的表中取出所需的數據,轉換成寬表。

    2 Kylin錯誤總結,知識點

    2.1 錯誤總結:變更kylin.metadata.url的值之后問題(運維層面)

    在kylin安裝過程中,如果變更了kylin.metadata.url,比如:

    kylin.metadata.url=bigdata

    那么在$KYLIN_HOME/bin/kylin.sh start的時候會報錯。解決辦法是:

    cd $KYLIN_HOME mkdir bigdata

    然后再啟動kylin,發現已經可以啟動成功了。

    2.2 知識點:Kylin通過JDBC Driver連接

    Jar的maven依賴:

    <kylin-jdbc.version>2.3.1</kylin-jdbc.version><!-- 查詢kylin jdbc driver --> <dependency><groupId>org.apache.kylin</groupId><artifactId>kylin-jdbc</artifactId><version>${kylin-jdbc.version}</version> </dependency>

    Spring Cloud項目中的數據庫連接池配置

    spring.datasource.name=data-center #使用druid數據源 spring.datasource.type=com.alibaba.druid.pool.DruidDataSource #數據源連接url spring.datasource.url=jdbc:kylin://xxx.xxx.xxx.xxx:7070/kylinProject spring.datasource.username=ADMIN spring.datasource.password=KYLIN spring.datasource.driver-class-name=org.apache.kylin.jdbc.Driver spring.datasource.filters=stat spring.datasource.maxActive=60 spring.datasource.initialSize=10 spring.datasource.maxWait=60000 spring.datasource.minIdle=10 spring.datasource.timeBetweenEvictionRunsMillis=60000 spring.datasource.minEvictableIdleTimeMillis=300000 spring.datasource.validationQuery=SELECT 1 spring.datasource.testWhileIdle=true spring.datasource.testOnBorrow=false spring.datasource.testOnReturn=false spring.datasource.poolPreparedStatements=true spring.datasource.maxOpenPreparedStatements=10

    可以使用MyBatis寫SQL的方式獲取到Kylin中的數據。
    SQL示例:

    <select id="selectMemberDataStatisticsByPage" resultType="xxx.MemberDataStatisticsDto">SELECTareaName as areaName,agentName as agentName,COUNT(agentId) as totalMemberNum,SUM(commonMember) as commonMemberNum,SUM(storedMember) as storedMemberNum,SUM(popularizeMember) as popularizeMemberNumFROMtb_member_buyback_cycle<trim prefix="WHERE" suffixOverrides="AND"><if test="areaCode != null and areaCode != '' ">areaCode LIKE #{areaCode} AND</if><if test="agentId != null and agentId != '' ">agentId=#{agentId} AND</if><if test="startTime != null"><![CDATA[addTime >= #{startTime} AND]]></if><if test="endTime != null"><![CDATA[addTime <= #{endTime} AND]]></if></trim>GROUP BYareaName,agentNameLIMIT ${pageSize} OFFSET ${(page - 1) * pageSize} </select>

    2.3 錯誤總結:分頁問題

    Kylin中分頁查詢和MySQL中的方式不太一樣,使用下面的語法:

    LIMIT ${pageSize} OFFSET ${(page - 1) * pageSize}

    這個語法和Phoenix的查詢語法一樣。

    但是,需要注意的是,這里的為pageSize,為{pageSize},為pageSize符號,而MyBatis中防注入的是通過#,所以需要在傳遞參數的時候做好相應的控制。如果寫成了#發現最后獲取不到自己想獲取的值(這個地方可能是其它原因)。

    2.4 錯誤總結:版本兼容問題

    在筆者部署線上環境過程中,筆者使用的hive是hive-2.3.2 (原生),然后使用最新的: apache-kylin-2.5.2-source-release.zip ,發現其中出現了hive中有數據,但是直到kylin cube build完成之后也不能將數據拉取到kylin,發現Source Records 的條數為0,然后筆者將版本降低到:apache-kylin-2.3.1,問題現象不再出現,cube build正常了。

    2.5 知識點:Cube的構建參數查看方法

    各層代表不同數量級的維度組合。每一層的計算都是一個單獨的Map Reduce任務。

    2.5.1 Cube的構建參數查看方法

    可以看出,cuboid越多,build cube就越慢,可通過命令查看cuboid個數:

    ./kylin.sh org.apache.kylin.engine.mr.common.CubeStatsReader [cubeName]

    在這里可以看出,該cube在構建之后得到的cuboids為63,大小約188mb

    2.5.2 Build區間的數據源大小,可以在下圖查看


    可以通過上面的提示看出:

    Source Table Size:3.06GB :原始數據大小 Expansion Rate:211.61% :現在的大小時原始數據的211.61%倍

    一般Cube的膨脹率應該在0%~1000%之間,如果Cube的膨脹率超過了1000%,那么就需要查詢其中的原因了,導致膨脹率高的原因一般為以下幾點:

    A:Cube的維度數量較多了,沒有進行良好的剪枝降維 B:Cube中存在較高基數的維度,導致這類維度每個Cuboid占用的空間很大,從而造成Cube體積變大 C:存在比較占用空間的(度量就是被聚合的統計值,也是聚合運算的結果),例如Count distinct、max()、sum(),需要在cuboid的每一行中都為其保存一個較大的寄存器,導致整個體積變大。

    Cube體積直接影響整個build性能,所以在創建時需要再三注意有無可減少的度量和維度。

    如果有 10 個維度,那么就會生成 2^10=1024-1 個 Cuboid,如果有 20 個維度那么將會 生 成 2^20=1048576-1 個 Cuboid , 是 指 數 級 增 長 , kylin.properties 中 參 數 kylin.cube.aggrgroup.max-combination=4096,也就是說當 Cuboid 數量大于 4096 時, Cube 定義是無法保存的的,會報 TooManyCuboidException 異常。所以默認維度不能超過 12 個,若非得超過 12 個,那必須降維:

    3 Kylin RestAPI使用

    使用kylin Rest API在shell腳本中執行cube build/rebuid

    Centos7上安裝jq工具

    Jq源碼位置:https://github.com/stedolan/jq

    下載安裝地址:https://stedolan.github.io/jq/download/

    Centos下安裝jq
    wget -O jq https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64
    chmod +x ./jq
    cp jq /usr/bin

    3.1 一個shell腳本案例:

    env.sh 內容:#!/bin/bash#kylin的參數 export kylinUserInfo="--user ADMIN:KYLIN" export kylinCubeUrl="http://xxx:7070/kylin/api/cubes/" export kylinJobsUrl="http://xxxx:7070/kylin/api/jobs/" export startTime="2015-01-01 00:00" export startTimeTimeStamp=`date -d "$startTime" +%s` export startTimeTimeStampMs=$(($startTimeTimeStamp * 1000)) export endTime=`date +%Y-%m-%d -d "+1days"` export endTimeTimeStamp=`date -d "$endTime" +%s` #將時間戳編程毫秒值 export endTimeTimeStampMs=$(($endTimeTimeStamp * 1000))export tradeInfoArgs="dataName=tradeInfo&dataType=" #$dataType"&dataTime="$yesterday #json的url信息存儲的文件路徑 export tradeInfoJsonUrls=$current/tmpfile/tradeInfoJsonUrls #json的url存儲位置前綴 export tradeInfoJsonUrlPrefix=$current/tmpfile/tradeInfoJsonUrlPrefix export tradeAnalyzeCubeName="xxxx" export tradeCollectMoneyCubeName="xxxx" #用于存儲是否下載了的變量文件 export tradeInfoVariableFile=$current/tmpfile/tradeInfoVariableFile
    #!/bin/bashsource /etc/profile#引用公共文件中定義的參數變量 source $PWD/env.shjobId=#是否執行過初始化程序了的控制邏輯 function isInited() {#如果文件存在,讀取相應的數據類型if [[ `ls $tradeInfoVariableFile | grep tradeInfoVariableFile | grep -v grep` != "" ]];thendataType=`cat $tradeInfoVariableFile | grep kylinTradeAnalyzeCubeInited | sed 's/kylinTradeAnalyzeCubeInited=//g'`#如果沒有,說明這個Spark程序還沒有初始化過 if [[ $dataType == "" ]];thenecho -e "\n" >> $tradeInfoVariableFileecho "kylinTradeAnalyzeCubeInited=inited" >> $tradeInfoVariableFilereturn 0;elsereturn 1;fielsemkdir -p $current/tmpfilecd $current/tmpfile#如果沒有這個文件,則是在這個文件中添加echo "kylinTradeAnalyzeCubeInited=inited" > $tradeInfoVariableFilereturn 0;fi }#Spark處理 function kylinHandler() {isInitedif [[ $? == 0 ]];then#上傳數據文件到HDFS中cd $current#1、Disable Cubecurl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset=utf-8" $kylinCubeUrl$tradeAnalyzeCubeName/disableecho ""echo ""#2、Purge Cubecurl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset=utf-8" $kylinCubeUrl$tradeAnalyzeCubeName/purgeecho ""echo ""#3、Enable Cubecurl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset=utf-8" $kylinCubeUrl$tradeAnalyzeCubeName/enableecho ""echo ""#4、Build cubecubeBuildInfo=`curl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset=utf-8" -d '{ "startTime":'$startTimeTimeStampMs',"endTime":'$endTimeTimeStampMs', "buildType": "BUILD"}' $kylinCubeUrl$tradeAnalyzeCubeName/build`echo ""echo ""elsecubeBuildInfo=`curl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset=utf-8" -d '{"endTime":'$endTimeTimeStampMs', "buildType": "BUILD"}' $kylinCubeUrl$tradeAnalyzeCubeName/rebuild`echo ""echo ""fiecho "cube build的狀態結果:"echo $cubeBuildInfoecho ""echo ""#查看是否build好了,如果build好了,發現last_build_time變成了build的最后時間了。jobId=$(echo $cubeBuildInfo |jq '.uuid')echo $jobId > $jobIdsed -i 's/"//g' $jobIdrealJobId=`cat $jobId`echo $realJobIdrm -rf $jobIdecho ""echo ""while :dosleep 1mcubeJobInfo=`curl -X GET --user ADMIN:KYLIN $kylinJobsUrl$realJobId`echo "獲取cube job運行的狀態"echo $cubeJobInfoecho ""echo ""jobStatus=$(echo $cubeJobInfo | jq ".job_status")echo "jobStatus"echo $jobStatus > $realJobIdsed -i 's/"//g' $realJobIdrealJobStatus=`cat $realJobId`echo "$realJobStatus"echo ""if [[ $realJobStatus == "NEW" ]];thenecho "kylin cube build job status:NEW; sleep 1m;"elif [[ $realJobStatus == "PENDING" ]];thenecho "kylin cube build job status:PENDING; sleep 1m;"elif [[ $realJobStatus == "RUNNING" ]];thenecho "kylin cube build job status:RUNNING; sleep 1m;"elif [[ $realJobStatus == "STOPPED" ]];thenecho "kylin cube build job status:STOPPED"#如果stop了,停掉kylin腳本的運行break;elif [[ $realJobStatus == "FINISHED" ]];thenecho "kylin cube build job status:FINISHED"break;elif [[ $realJobStatus == "ERROR" ]];thenecho "kylin cube build job status:ERROR"break;elif [[ $realJobStatus == "DISCARDED" ]];thenecho "kylin cube build job status:DISCARDED"break;else echo "kylin cube build job status:OTHER UNKNOWN STATUS"break;fidone#刪除文件rm -rf $realJobId }#上傳數據文件到HDFS中 kylinHandler#清理Linux系統中不用的垃圾暫用的內存 sync echo 3 > /proc/sys/vm/drop_caches

    4 參考資料

    http://kylin.apache.org/cn/
    http://kyligence.io/zh/blog-zh/

    總結

    以上是生活随笔為你收集整理的kylin调优,项目中错误总结,知识点总结,kylin jdbc driver + 数据库连接池druid + Mybatis项目中的整合,shell脚本执行kylin restapi 案例的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。