热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

kylin调优,项目中错误总结,知识点总结,kylinjdbcdriver+数据库连接池druid+Myba

关于本篇文章的说明:本篇文章为笔者辛苦劳作用了一整天总结出来的文档,大家阅读转发的时候请不要吝啬写上笔者:涂作权和原文地址。由于笔者所在环
       

关于本篇文章的说明:
本篇文章为笔者辛苦劳作用了一整天总结出来的文档,大家阅读转发的时候请不要吝啬写上笔者:涂作权 和 原文地址。

由于笔者所在环境没有人用过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"

  • 1
  • 2

笔者配置:

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

  • 1
  • 2
  • 3

在这里插入图片描述

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 中的配置类似如下:

    yarn.nodemanager.vmem-check-enabled    false    yarn.nodemanager.vmem-pmem-ratio    5     yarn.nodemanager.resource.memory-mb          20480     每个节点可用内存,单位MB     yarn.scheduler.minimum-allocation-mb     1024     yarn.scheduler.maximum-allocation-mb          20480

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31

yarn.nodemanager.vmem-pmem-ratio :虚拟内存大小的一个系数,通过调整这个参数,可以增大虚拟内存的值,避免kylin在cube build的过程中出现失败。

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

     mapreduce.map.java.opts          -Xms3g -Xmx10g          mapreduce.reduce.java.opts          -Xms6g -Xmx16g      mapreduce.map.memory.mb            10240      mapreduce.reduce.input.buffer.percent      0.5      mapreduce.reduce.memory.mb            16384

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

其中官网的介绍是:
在这里插入图片描述

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=2kylin.hbase.hfile.size.gb=1

  • 1
  • 2

如果你不确定一个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

  • 1
  • 2
  • 3

该文件原本的配置如下:

    hive.merge.mapfiles    false    Disable Hive's auto merge    hive.merge.mapredfiles    false    Disable Hive's auto merge

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

修改成:

    hive.merge.mapfiles    true    Enable Hive's auto merge    hive.merge.mapredfiles    true    Enable Hive's auto merge

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

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;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

其中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

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();

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

也就是说将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/defaultWARNING: 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]#

  • 1
  • 2
  • 3
  • 4
  • 5

其中: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

  • 1
  • 2

请将这里的 (version) 替换为你安装的 Kylin jar 版本。
2. 你可以抽查一两个资源来检查它们是否已经没有被引用了;然后加上“–delete true”选项进行清理。

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

  • 1

完成后,Hive 里的中间表, HDFS 上的中间文件及 HBase 中的 HTables 都会被移除。
3. 如果您想要删除所有资源;可添加 “–force true” 选项:

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

  • 1

完成后,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 SEQUENCEFILELOCATION &#39;hdfs:///kylin/kylin200instance/kylin-0a8d71e8-df77-495f-b501-03c06f785b6c/kylin_intermediate_airline_cube_v3610f668a3cdb437e8373c034430f6c34&#39;;SET dfs.replication&#61;2;SET hive.exec.compress.output&#61;true;SET hive.auto.convert.join.noconditionaltask&#61;true;SET hive.auto.convert.join.noconditionaltask.size&#61;100000000;SET mapreduce.job.split.metainfo.maxsize&#61;-1;INSERT OVERWRITE TABLE kylin_intermediate_airline_cube_v3610f668a3cdb437e8373c034430f6c34 SELECTAIRLINE.FLIGHTDATE,AIRLINE.YEAR,AIRLINE.QUARTER,...,AIRLINE.ARRDELAYMINUTESFROM AIRLINE.AIRLINE as AIRLINEWHERE (AIRLINE.FLIGHTDATE >&#61; &#39;1987-10-01&#39; AND AIRLINE.FLIGHTDATE <&#39;2017-01-01&#39;);

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

在Hive命令运行时&#xff0c;Kylin会用conf/kylin_hive_conf.properties里的配置&#xff0c;比如保留更少的冗余备份和启用Hive的mapper side join。需要的话可以根据集群的具体情况增加其他配置。

如果cube的分区列(在这个案例中是”FIGHTDATE”)与Hive表的分区列相同&#xff0c;那么根据它过滤数据能让Hive聪明地跳过不匹配的分区。因此强烈建议用Hive的分区列&#xff08;如果它是日期列&#xff09;作为cube的分区列。这对于那些数据量很大的表来说几乎是必须的&#xff0c;否则Hive不得不每次在这步扫描全部文件&#xff0c;消耗非常长的时间。

1.18 调优&#xff1a;重新分发中间表&#xff08;来自官网&#xff09;

在之前的一步之后&#xff0c;Hive在HDFS上的目录里生成了数据文件&#xff1a;有些是大文件&#xff0c;有些是小文件甚至空文件。这种不平衡的文件分布会导致之后的MR任务出现数据倾斜的问题&#xff1a;有些mapper完成得很快&#xff0c;但其他的就很慢。针对这个问题&#xff0c;Kylin增加了这一个步骤来“重新分发”数据&#xff0c;这是示例输出:

total input rows &#61; 159869711expected input rows per mapper &#61; 1000000num reducers for RedistributeFlatHiveTableStep &#61; 160

  • 1
  • 2
  • 3

重新分发表的命令&#xff1a;

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

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

首先&#xff0c;Kylin计算出中间表的行数&#xff0c;然后基于行数的大小算出重新分发数据需要的文件数。默认情况下,Kylin为每一百万行分配一个文件。在这个例子中&#xff0c;有1.6亿行和160个reducer&#xff0c;每个reducer会写一个文件。在接下来对这张表进行的MR步骤里&#xff0c;Hadoop会启动和文件相同数量的mapper来处理数据(通常一百万行数据比一个HDFS数据块要小)。如果你的日常数据量没有这么大或者Hadoop集群有足够的资源&#xff0c;你或许想要更多的并发数&#xff0c;这时可以将conf/kylin.properties里的kylin.job.mapreduce.mapper.input.rows设为小一点的数值&#xff0c;比如:

kylin.job.mapreduce.mapper.input.rows&#61;500000

  • 1

其次&#xff0c;Kylin会运行 “INSERT OVERWRITE TABLE … DISTRIBUTE BY “ 形式的HiveQL来分发数据到指定数量的reducer上。

在很多情况下&#xff0c;Kylin请求Hive随机分发数据到reducer&#xff0c;然后得到大小相近的文件&#xff0c;分发的语句是”DISTRIBUTE BY RAND()”。

如果你的cube指定了一个高基数的列&#xff0c;比如”USER_ID”&#xff0c;作为”分片”维度(在cube的“高级设置”页面)&#xff0c;Kylin会让Hive根据该列的值重新分发数据&#xff0c;那么在该列有着相同值的行将被分发到同一个文件。这比随机要分发要好得多&#xff0c;因为不仅重新分布了数据&#xff0c;并且在没有额外代价的情况下对数据进行了预先分类&#xff0c;如此一来接下来的cube build处理会从中受益。在典型的场景下&#xff0c;这样优化可以减少40%的build时长。在这个案例中分发的语句是”DISTRIBUTE BY USER_ID”&#xff1a;

请注意: 1)“分片”列应该是高基数的维度列&#xff0c;并且它会出现在很多的cuboid中&#xff08;不只是出现在少数的cuboid&#xff09;。 使用它来合理进行分发可以在每个时间范围内的数据均匀分布&#xff0c;否则会造成数据倾斜&#xff0c;从而降低build效率。典型的正面例子是&#xff1a;“USER_ID”、“SELLER_ID”、“PRODUCT”、“CELL_NUMBER”等等&#xff0c;这些列的基数应该大于一千(远大于reducer的数量)。 2)”分片”对cube的存储同样有好处&#xff0c;不过这超出了本文的范围。

1.19 调优&#xff1a;提取事实表的唯一列&#xff08;来自官网&#xff09;

在这一步骤Kylin运行MR任务来提取使用字典编码的维度列的唯一值。
实际上这步另外还做了一些事情&#xff1a;通过HyperLogLog计数器收集cube的统计数据&#xff0c;用于估算每个cuboid的行数。如果你发现mapper运行得很慢&#xff0c;这通常表明cube的设计太过复杂&#xff0c;请参考

优化cube设计来简化cube。如果reducer出现了内存溢出错误&#xff0c;这表明cuboid组合真的太多了或者是YARN的内存分配满足不了需要。如果这一步从任何意义上讲不能在合理的时间内完成&#xff0c;你可以放弃任务并考虑重新设计cube&#xff0c;因为继续下去会花费更长的时间。

你可以通过降低取样的比例&#xff08;kylin.job.cubing.inmen.sampling.percent&#xff09;来加速这个步骤&#xff0c;但是帮助可能不大而且影响了cube统计数据的准确性&#xff0c;所有我们并不推荐。

1.20 调优&#xff1a;构建维度字典&#xff08;来自官网&#xff09;

有了前一步提取的维度列唯一值&#xff0c;Kylin会在内存里构建字典。通常这一步比较快&#xff0c;但如果唯一值集合很大&#xff0c;Kylin可能会报出类似“字典不支持过高基数”。对于UHC类型的列&#xff0c;请使用其他编码方式&#xff0c;比如“fixed_length”、“integer”等等。

1.21 调优&#xff1a;构建基础cuboid,调整map大小 和reduce的数量

这一步用Hive的中间表构建基础的cuboid&#xff0c;是“逐层”构建cube算法的第一轮MR计算。Mapper的数目与第二步的reducer数目相等&#xff1b;Reducer的数目是根据cube统计数据估算的&#xff1a;默认情况下每500MB输出使用一个reducer&#xff1b;如果观察到reducer的数量较少&#xff0c;你可以将kylin.properties里的“kylin.job.mapreduce.default.reduce.input.mb”设为小一点的数值以获得过多的资源&#xff0c;比如:

kylin.job.mapreduce.default.reduce.input.mb&#61;200

  • 1

1.22 调优&#xff1a;设置好Mandatory Dimensions 列

这种维度意味着每次查询的group by中都会携带的&#xff0c;将某一个dimension设置为mandatory可以将cuboid的个数减少一半

因为我们确定每一次group by都会携带字段A&#xff0c;将A设置成Mandatory Dimensions后&#xff0c;那么就可以省去所有不包含A这个维度的cuboid了

好的技术文章&#xff1a;
http://kyligence.io/zh/2017/04/21/apache-kylin-advanced-setting-mandatory-dimension-principle/

1.23 调优&#xff1a;设置Joint Dimensions

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

1.24 调优&#xff1a;设置Hierarchy Dimension

以下文章很好的介绍了如何关于Hierarchy Dimension的调优策略

  • 1

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

1.25 调优&#xff1a;Configuration Overwrites 高级设置

参考官网更详细介绍&#xff1a;
http://kylin.apache.org/cn/docs/install/advance_settings.html

另外在里面最好设置数据压缩方式&#xff0c;以减少磁盘占用

1.26 调优&#xff1a;改变kylin中Advanced Setting的维度顺序

对于kylin中频繁使用&#xff0c;或着一定使用的维度列&#xff0c;在设置Includes的时候&#xff0c;将这些配置的靠前一些。因为kylin内部机制是越靠前的越优先被找到&#xff0c;从而加快查询速度。
在这里插入图片描述
就是上面红色区域的维度列的顺序。

1.27 调优&#xff1a;Build Cube With Spark

kylin.engine.spark.rdd-partition-cut-mb &#61; 10 (默认 200)
在这里插入图片描述
直接影响 spark 的分区数&#xff0c;首先大概清楚 cuboid 数据总大小&#xff0c;例如 6032mb,那么 partitions &#61; 6032/10 &#61; 600&#xff0c;即会产生 600 个小文件&#xff0c;随后在 step8 跑 mr 时&#xff0c;就会拉起 600 个 map,使得 服务器负载骤增&#xff0c;发生报警。

调整参数后执行&#xff0c;如何跟踪服务器情况&#xff1f;只需跟踪 step8 的 mr 情况即可
① http://bgnode1:8088/cluster/scheduler 找到对应的 application
② %of Cluster 是否过高
③ 进入详情查看 map 数量是否过多&#xff0c;若过多则很可能是 rdd-partition-cut-mb 设置过 小导致&#xff0c;此时要调大参数 因此&#xff0c;合理的调整 rdd-partition-cut-mb 能防止机器报警。 这一步是对每一层的 cuboid 依次进行计算并写入 hdfs&#xff0c;耗时会比较长
在这里插入图片描述

kylin.engine.spark-conf.spark.executor.cores &#61; 2 kylin.engine.spark-conf.spark.executor.memory &#61; 4G

  • 1
  • 2

这两个参数自行根据数据大小来调整&#xff0c;cores 和 memory 都不是越大越好&#xff0c;需根据要 build 的数据量&#xff0c;再三调整测试最优值。

1.28 调优&#xff1a;Rowkey调优

为什么要优化 Rowkey? Apache Kylin 使用 HBase 做为 Cube 的存储引擎。而 HBase 是 Key-Value 数据库&#xff0c;这个 Key 在 HBase 中称为 Rowkey。为了能够支持按多个维度进行查询&#xff0c;Kylin 需要将多个维度值以某 种次序组成 Rowkey。HBase Scan Range&#xff0c;排在 Rowkey 靠前部分的维度&#xff0c;将比排在靠后部分 的维度更易于做筛选&#xff0c;查询效率更高。

那些维度适合排在前部分?

  1. 基数高的排前面 在 Load Hive Table 时&#xff0c;勾选 Calculate column cardinality&#xff0c;即可在 load 时计算各字段的基 数&#xff0c;并在 Data Source -> Tables -> 点击相应的 table 查看

1.29 调优&#xff1a;在查询中被用做过滤条件的维度放在非过滤条件维度的前面

这一个环节如果 rowkey 没设计好&#xff0c;会导致以下问题&#xff1a;

  1. Cuboid 转 hfile 后&#xff0c;会因数据分布不均匀&#xff0c;导致单点问题&#xff0c;使得服务器内存过高&#xff0c;触发报 警
  2. Hbase 寻址慢&#xff0c;查询性能下降 除了各维度在 Rowkey 上的次序外&#xff0c;维度的编码方法对于空间占用及查询性能也有着显 著的影响。 合适的编码能减少维度对空间的占用&#xff0c;同时编码值也会加速查询过滤。

1.30 调优&#xff1a;罗列几个显著影响性能的参数

以下都是默认值&#xff1a;

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

官网提供的可设置参数&#xff1a;http://kylin.apache.org/docs/install/configuration.html

1.31 调优&#xff1a;其它调优思路

通过./kylin.sh org.apache.kylin.engine.mr.common.CubeStatsReader [cubeName] 查看 cuboid 总大小&#xff0c;然后再根据以下步骤进行对参数的调整&#xff1a;

1. 3 种降维选项是否有根据业务实际情况调整 2. 有没合理的使用分区列 3. 小文件是否过多 4. reducer 是否过少 5. spark partitions 是否合适 6. spark 的 excutor 内存和 cores 数量分配是否合理 7. cuboid 文件转 hfile 时&#xff0c;map 是否过多&#xff0c;reducer 是否过少&#xff08;region 块的大小和数量是否合 理&#xff09;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
2 Kylin错误总结&#xff0c;知识点

2.1 错误总结&#xff1a;变更kylin.metadata.url的值之后问题&#xff08;运维层面&#xff09;

在kylin安装过程中&#xff0c;如果变更了kylin.metadata.url&#xff0c;比如&#xff1a;

kylin.metadata.url&#61;bigdata

  • 1

那么在$KYLIN_HOME/bin/kylin.sh start的时候会报错。解决办法是&#xff1a;

cd $KYLIN_HOMEmkdir bigdata

  • 1
  • 2

然后再启动kylin,发现已经可以启动成功了。

2.2 知识点&#xff1a;Kylin通过JDBC Driver连接

Jar的maven依赖&#xff1a;

2.3.1   org.apache.kylin   kylin-jdbc   ${kylin-jdbc.version}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

Spring Cloud项目中的数据库连接池配置

spring.datasource.name&#61;data-center#使用druid数据源spring.datasource.type&#61;com.alibaba.druid.pool.DruidDataSource#数据源连接urlspring.datasource.url&#61;jdbc:kylin://xxx.xxx.xxx.xxx:7070/kylinProjectspring.datasource.username&#61;ADMINspring.datasource.password&#61;KYLINspring.datasource.driver-class-name&#61;org.apache.kylin.jdbc.Driverspring.datasource.filters&#61;statspring.datasource.maxActive&#61;60spring.datasource.initialSize&#61;10spring.datasource.maxWait&#61;60000spring.datasource.minIdle&#61;10spring.datasource.timeBetweenEvictionRunsMillis&#61;60000spring.datasource.minEvictableIdleTimeMillis&#61;300000spring.datasource.validationQuery&#61;SELECT 1spring.datasource.testWhileIdle&#61;truespring.datasource.testOnBorrow&#61;falsespring.datasource.testOnReturn&#61;falsespring.datasource.poolPreparedStatements&#61;truespring.datasource.maxOpenPreparedStatements&#61;10

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

可以使用MyBatis写SQL的方式获取到Kylin中的数据。
SQL示例&#xff1a;

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33

2.3 错误总结&#xff1a;分页问题

Kylin中分页查询和MySQL中的方式不太一样&#xff0c;使用下面的语法&#xff1a;

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

这个语法和Phoenix的查询语法一样。

但是&#xff0c;需要注意的是&#xff0c;这里的为pageSize&#xff0c;为pageSize&#xff0c;为pageSize&#xff0c;为pageSize&#xff0c;为 pageSize&#xff0c;为      {pageSize}&#xff0c;为pageSize&#xff0c; pageSize&#xff0c;     pageSize&#xff0c;pageSize&#xff0c;符号&#xff0c;而MyBatis中防注入的是通过#&#xff0c;所以需要在传递参数的时候做好相应的控制。如果写成了#发现最后获取不到自己想获取的值&#xff08;这个地方可能是其它原因&#xff09;。

2.4 错误总结&#xff1a;版本兼容问题

在笔者部署线上环境过程中&#xff0c;笔者使用的hive是hive-2.3.2 &#xff08;原生&#xff09;&#xff0c;然后使用最新的&#xff1a; apache-kylin-2.5.2-source-release.zip &#xff0c;发现其中出现了hive中有数据&#xff0c;但是直到kylin cube build完成之后也不能将数据拉取到kylin&#xff0c;发现Source Records 的条数为0&#xff0c;然后笔者将版本降低到&#xff1a;apache-kylin-2.3.1&#xff0c;问题现象不再出现&#xff0c;cube build正常了。

2.5 知识点&#xff1a;Cube的构建参数查看方法

在这里插入图片描述

各层代表不同数量级的维度组合。每一层的计算都是一个单独的Map Reduce任务。

2.5.1  Cube的构建参数查看方法

可以看出&#xff0c;cuboid越多&#xff0c;build cube就越慢&#xff0c;可通过命令查看cuboid个数&#xff1a;

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

  • 1

在这里插入图片描述

在这里可以看出&#xff0c;该cube在构建之后得到的cuboids为63&#xff0c;大小约188mb

2.5.2 Build区间的数据源大小&#xff0c;可以在下图查看

在这里插入图片描述
可以通过上面的提示看出&#xff1a;

Source Table Size:3.06GB    :原始数据大小Expansion Rate:211.61%    :现在的大小时原始数据的211.61%倍

  • 1
  • 2

一般Cube的膨胀率应该在0%~1000%之间&#xff0c;如果Cube的膨胀率超过了1000%&#xff0c;那么就需要查询其中的原因了&#xff0c;导致膨胀率高的原因一般为以下几点&#xff1a;

A:Cube的维度数量较多了&#xff0c;没有进行良好的剪枝降维B:Cube中存在较高基数的维度&#xff0c;导致这类维度每个Cuboid占用的空间很大&#xff0c;从而造成Cube体积变大C:存在比较占用空间的(度量就是被聚合的统计值&#xff0c;也是聚合运算的结果),例如Count distinct、max()、sum(),需要在cuboid的每一行中都为其保存一个较大的寄存器&#xff0c;导致整个体积变大。

  • 1
  • 2
  • 3

Cube体积直接影响整个build性能&#xff0c;所以在创建时需要再三注意有无可减少的度量和维度。

如果有 10 个维度&#xff0c;那么就会生成 2^10&#61;1024-1 个 Cuboid&#xff0c;如果有 20 个维度那么将会 生 成 2^20&#61;1048576-1 个 Cuboid &#xff0c; 是 指 数 级 增 长 &#xff0c; kylin.properties 中 参 数 kylin.cube.aggrgroup.max-combination&#xff1d;4096&#xff0c;也就是说当 Cuboid 数量大于 4096 时&#xff0c; Cube 定义是无法保存的的&#xff0c;会报 TooManyCuboidException 异常。所以默认维度不能超过 12 个&#xff0c;若非得超过 12 个&#xff0c;那必须降维&#xff1a;

3 Kylin RestAPI使用

使用kylin Rest API在shell脚本中执行cube build/rebuid

Centos7上安装jq工具

Jq源码位置&#xff1a;https://github.com/stedolan/jq

下载安装地址&#xff1a;https://stedolan.github.io/jq/download/

Centos下安装jq
wget -O jq https://github.com/stedolan/jq/releases/download/jq-1.5/jq-linux64
chmod &#43;x ./jq
cp jq /usr/bin

3.1 一个shell脚本案例&#xff1a;

env.sh 内容&#xff1a;#!/bin/bash#kylin的参数export kylinUserInfo&#61;"--user ADMIN:KYLIN"export kylinCubeUrl&#61;"http://xxx:7070/kylin/api/cubes/"export kylinJobsUrl&#61;"http://xxxx:7070/kylin/api/jobs/"export startTime&#61;"2015-01-01 00:00"export startTimeTimeStamp&#61;&#96;date -d "$startTime" &#43;%s&#96;export startTimeTimeStampMs&#61;$(($startTimeTimeStamp * 1000))export endTime&#61;&#96;date &#43;%Y-%m-%d -d "&#43;1days"&#96;export endTimeTimeStamp&#61;&#96;date -d "$endTime" &#43;%s&#96;#将时间戳编程毫秒值export endTimeTimeStampMs&#61;$(($endTimeTimeStamp * 1000))export tradeInfoArgs&#61;"dataName&#61;tradeInfo&dataType&#61;"    #$dataType"&dataTime&#61;"$yesterday#json的url信息存储的文件路径export tradeInfoJsonUrls&#61;$current/tmpfile/tradeInfoJsonUrls#json的url存储位置前缀export tradeInfoJsonUrlPrefix&#61;$current/tmpfile/tradeInfoJsonUrlPrefixexport tradeAnalyzeCubeName&#61;"xxxx"export tradeCollectMoneyCubeName&#61;"xxxx"#用于存储是否下载了的变量文件export tradeInfoVariableFile&#61;$current/tmpfile/tradeInfoVariableFile

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27

#!/bin/bashsource /etc/profile#引用公共文件中定义的参数变量source $PWD/env.shjobId&#61;#是否执行过初始化程序了的控制逻辑function isInited() {   #如果文件存在&#xff0c;读取相应的数据类型   if [[ &#96;ls $tradeInfoVariableFile | grep tradeInfoVariableFile | grep -v grep&#96; !&#61; "" ]];then  dataType&#61;&#96;cat $tradeInfoVariableFile | grep kylinTradeAnalyzeCubeInited | sed &#39;s/kylinTradeAnalyzeCubeInited&#61;//g&#39;&#96;     #如果没有&#xff0c;说明这个Spark程序还没有初始化过   if [[ $dataType &#61;&#61; "" ]];then      echo -e "\n" >> $tradeInfoVariableFile   echo "kylinTradeAnalyzeCubeInited&#61;inited" >> $tradeInfoVariableFile   return 0;  else      return 1;  fi else     mkdir -p $current/tmpfile  cd $current/tmpfile     #如果没有这个文件&#xff0c;则是在这个文件中添加  echo "kylinTradeAnalyzeCubeInited&#61;inited" > $tradeInfoVariableFile  return 0; fi }#Spark处理function kylinHandler() {    isInited if [[ $? &#61;&#61; 0 ]];then     #上传数据文件到HDFS中  cd $current  #1、Disable Cube  curl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset&#61;utf-8" $kylinCubeUrl$tradeAnalyzeCubeName/disable  echo ""  echo ""    #2、Purge Cube  curl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset&#61;utf-8" $kylinCubeUrl$tradeAnalyzeCubeName/purge  echo ""  echo ""    #3、Enable Cube  curl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset&#61;utf-8" $kylinCubeUrl$tradeAnalyzeCubeName/enable  echo ""  echo ""    #4、Build cube  cubeBuildInfo&#61;&#96;curl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset&#61;utf-8" -d &#39;{ "startTime":&#39;$startTimeTimeStampMs&#39;,"endTime":&#39;$endTimeTimeStampMs&#39;, "buildType": "BUILD"}&#39; $kylinCubeUrl$tradeAnalyzeCubeName/build&#96;  echo ""  echo "" else     cubeBuildInfo&#61;&#96;curl -X PUT $kylinUserInfo -H "Content-Type: application/json;charset&#61;utf-8" -d &#39;{"endTime":&#39;$endTimeTimeStampMs&#39;, "buildType": "BUILD"}&#39; $kylinCubeUrl$tradeAnalyzeCubeName/rebuild&#96;  echo ""  echo "" fi     echo "cube build的状态结果:" echo $cubeBuildInfo echo "" echo "" #查看是否build好了&#xff0c;如果build好了&#xff0c;发现last_build_time变成了build的最后时间了。 jobId&#61;$(echo $cubeBuildInfo |jq &#39;.uuid&#39;) echo $jobId > $jobId sed -i &#39;s/"//g&#39; $jobId realJobId&#61;&#96;cat $jobId&#96; echo $realJobId rm -rf $jobId echo "" echo ""  while : do     sleep 1m     cubeJobInfo&#61;&#96;curl -X GET --user ADMIN:KYLIN $kylinJobsUrl$realJobId&#96;  echo "获取cube job运行的状态"  echo $cubeJobInfo  echo ""     echo ""       jobStatus&#61;$(echo $cubeJobInfo | jq ".job_status")  echo "jobStatus"  echo $jobStatus > $realJobId  sed -i &#39;s/"//g&#39; $realJobId  realJobStatus&#61;&#96;cat $realJobId&#96;  echo "$realJobStatus"     echo ""      if [[ $realJobStatus &#61;&#61; "NEW" ]];then      echo "kylin cube build job status&#xff1a;NEW; sleep 1m;"  elif [[ $realJobStatus &#61;&#61; "PENDING" ]];then      echo "kylin cube build job status&#xff1a;PENDING; sleep 1m;"  elif [[ $realJobStatus &#61;&#61; "RUNNING" ]];then      echo "kylin cube build job status&#xff1a;RUNNING; sleep 1m;"  elif [[ $realJobStatus &#61;&#61; "STOPPED" ]];then      echo "kylin cube build job status&#xff1a;STOPPED"   #如果stop了&#xff0c;停掉kylin脚本的运行   break;  elif [[ $realJobStatus &#61;&#61; "FINISHED" ]];then      echo "kylin cube build job status&#xff1a;FINISHED"   break;     elif [[ $realJobStatus &#61;&#61; "ERROR" ]];then      echo "kylin cube build job status&#xff1a;ERROR"   break;     elif [[ $realJobStatus &#61;&#61; "DISCARDED" ]];then      echo "kylin cube build job status&#xff1a;DISCARDED"   break;  else       echo "kylin cube build job status&#xff1a;OTHER UNKNOWN STATUS"   break;  fi done  #删除文件 rm -rf $realJobId}#上传数据文件到HDFS中kylinHandler#清理Linux系统中不用的垃圾暂用的内存syncecho 3 > /proc/sys/vm/drop_caches

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
4 参考资料

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

           

再分享一下我老师大神的人工智能教程吧。零基础&#xff01;通俗易懂&#xff01;风趣幽默&#xff01;还带黄段子&#xff01;希望你也加入到我们人工智能的队伍中来&#xff01;https://blog.csdn.net/jiangjunshow


推荐阅读
author-avatar
汽车一族coolboy_518
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有