Kylin
# Apache Kylin 使用手册
[toc]
# 文章链接
https://blog.csdn.net/zhangshenghang/article/details/123330462 (opens new window)
# 一、概述
# 1.1 Kylin定义
Apache Kylin™是一个开源的、分布式的分析型数据仓库,提供Hadoop/Spark 之上的 SQL 查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由 eBay 开发并贡献至开源社区。它能在亚秒内查询巨大的表。
# 1.2 Kylin架构
REST Service
REST Server 是一套面向应用程序开发的入口点,旨在实现针对 Kylin 平台的应用开发
工作。 此类应用程序可以提供查询、获取结果、触发 cube 构建任务、获取元数据以及获取
用户权限等等。另外可以通过 Restful 接口实现 SQL 查询。
查询引擎(Query Engine)
当 cube 准备就绪后,查询引擎就能够获取并解析用户查询。它随后会与系统中的其它
组件进行交互,从而向用户返回对应的结果。
路由器(Routing)
在最初设计时曾考虑过将 Kylin 不能执行的查询引导去 Hive 中继续执行,但在实践后
发现 Hive 与 Kylin 的速度差异过大,导致用户无法对查询的速度有一致的期望,很可能大
多数查询几秒内就返回结果了,而有些查询则要等几分钟到几十分钟,因此体验非常糟糕。
最后这个路由功能在发行版中默认关闭。
元数据管理工具(Metadata)
Kylin 是一款元数据驱动型应用程序。元数据管理工具是一大关键性组件,用于对保存
在 Kylin 当中的所有元数据进行管理,其中包括最为重要的 cube 元数据。其它全部组件的
正常运作都需以元数据管理工具为基础。 Kylin 的元数据存储在 hbase (3.x版本)中。
任务引擎(Cube Build Engine)
这套引擎的设计目的在于处理所有离线任务,其中包括 shell 脚本、Java API 以及 Map
Reduce 任务等等。任务引擎对 Kylin 当中的全部任务加以管理与协调,从而确保每一项任务
都能得到切实执行并解决其间出现的故障。
# 1.3 Kylin特点
Kylin 的主要特点包括支持 SQL 接口、支持超大规模数据集、亚秒级响应、可伸缩性、
高吞吐率、BI 工具集成等。
标准 SQL 接口:Kylin 是以标准的 SQL 作为对外服务的接口。
支持超大数据集:Kylin 对于大数据的支撑能力可能是目前所有技术中最为领先的。
早在 2015 年 eBay 的生产环境中就能支持百亿记录的秒级查询,之后在移动的应用场景中
又有了千亿记录秒级查询的案例。
亚秒级响应:Kylin 拥有优异的查询相应速度,这点得益于预计算,很多复杂的计算,
比如连接、聚合,在离线的预计算过程中就已经完成,这大大降低了查询时刻所需的计算量,
提高了响应速度。
可伸缩性和高吞吐率:单节点 Kylin 可实现每秒 70 个查询,还可以搭建 Kylin 的集
群。
BI 工具集成:
Kylin 可以与现有的 BI 工具集成,具体包括如下内容。
ODBC:与 Tableau、Excel、PowerBI 等工具集成
JDBC:与 Saiku、BIRT 等 Java 工具集成
RestAPI:与 JavaScript、Web 网页集成
Kylin 开发团队还贡献了 Zepplin 的插件,也可以使用 Zepplin 来访问 Kylin 服务。
# 1.4 Apache Kylin4 概述
Apache Kylin™是一个开源的、分布式的分析型数据仓库,提供 Hadoop 之上的 SQL 查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由eBay Inc.开发并贡献至开源社区。
Apache Kylin4.0 是 Apache Kylin3.x 之后一次重大的版本更新,它采用了全新的 Spark 构建引擎和 Parquet 作为存储,同时使用 Spark 作为查询引擎。
为了方便用户对 Kylin4.x 有更全面更深层的了解,本篇文档会着重从 Kylin4.x 与之前版本有何异同的角度对 Kylin4.x 做全面概述。文章分为以下几个部分:
- 为什么选择 Parquet 替换 HBase
- 预计算结果在 Kylin4.0 中如何存储
- Kylin 4.0 的构建引擎
- Kylin 4.0 的查询引擎
- Kylin4.0 与 Kylin3.1 功能对比
- Kylin 4.0 性能表现
- Kylin 4.0 查询和构建调优
- Kylin 4.0 用户案例
# 为什么选择 Parquet 替换 HBase?
在 3.x 以及之前的版本中,kylin 一直使用 HBase 作为存储引擎来保存 cube 构建后产生的预计算结果。HBase 作为 HDFS 之上面向列族的数据库,查询表现已经算是比较优秀,但是它仍然存在以下几个缺点:
HBase 不是真正的列式存储;
HBase表数据模型比较特别,也可以简单理解为有行和列的二维表,只是它的列称为“列族”,列族下面又可以在数据写入时指定很多的子列。另外,HBase物理存储上是将整个列族数据存储在一起的。所以,如果HBase中的一张表只有一个列族的话,等于是这个列族包含了这张表的所有列,也就是将表正行的数据连续存储在了一起,就等于是行式存储了。再比如,一张表有多个列族,并且每个列族下仅有一列(虽然HBase不建议这么做),也就是将表的列数据连续存储在了一起,就等于是列式存储了。
HBase 没有二级索引,Rowkey 是它唯一的索引;
HBase 没有对存储的数据进行编码,kylin 必须自己进行对数据编码的过程;
HBase 不适合云上部署和自动伸缩;
HBase 不同版本之间的 API 版本不同,存在兼容性问题(比如,0.98,1.0,1.1,2.0);
HBase 存在不同的供应商版本,他们之间有兼容性问题。
针对以上问题,社区提出了对使用 Apache Parquet + Spark 来代替 HBase 的提议,理由如下:
- Parquet 是一种开源并且已经成熟稳定的列式存储格式;
- Parquet 对云更加友好,可以兼容各种文件系统,包括 HDFS、S3、Azure Blob store、Ali OSS 等
- Parquet 可以很好地与 Hadoop、Hive、Spark、Impala 等集成;
- Parquet 支持自定义索引。
# 预计算结果在 Kylin4.0 中如何存储?
在 Kylin4.x 中,预计算结果以 Parquet 格式存储在文件系统中,文件存储结构对于 I/O 优化很重要,提前对存储目录结构进行设计,就能够在查询时通过目录或者文件名过滤数据文件,避免不必要的扫描。
Kylin4 对 cube 进行构建得到的预计算结果的 Parquet 文件在文件系统中存储的目录结构如下:
- cube_name
- SegmentA
- Cuboid-111
- part-0000-XXX.snappy.parquet
- part-0001-XXX.snappy.parquet
- …
- Cuboid-222
- part-0000-XXX.snappy.parquet
- part-0001-XXX.snappy.parquet
- …
- SegmentB
- Cuboid-111
- part-0000-XXX.snappy.parquet
- part-0001-XXX.snappy.parquet
- …
- Cuboid-222
- part-0000-XXX.snappy.parquet
- part-0001-XXX.snappy.parquet
- …
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
可以看出,与 HBase 相比,采用 Parquet 存储可以很方便地增删 cuboid 而不影响其他数据。利用这种特点,Kylin4 中实现了支持用户手动增删 cuboid 的功能,请参考:How to update cuboid list for a cube (opens new window)
# Kylin 4.0 的构建引擎
在 Kylin4 中,Spark Engine 是唯一的构建引擎,与之前版本中的构建引擎相比,存在如下特点:
- Kylin4 的构建简化了很多步骤。比如在 Cube Build Job 中, kylin4 只需要资源探测和 cubing 两个步骤,就可以完成构建;
- 由于 Parquet 会对存储的数据进行编码,所以在 kylin4 中不再需要维度字典和对维度列编码的过程;
- Kylin4 对全局字典做了全新的实现,更多细节请参考:Kylin4 全局字典 (opens new window) ;
- Kylin4 会根据集群资源、构建任务情况等对 Spark 进行自动调参;
- Kylin4 提高了构建速度。
用户可以通过 kylin.build.spark-conf
开头的配置项手动修改构建相关的 Spark 配置,经过用户手动修改的 Spark 配置项不会再参与自动调参。
# Kylin 4.0 的查询引擎
Kylin4 的查询引擎 Sparder(SparderContext)
是由 spark application 后端实现的新型分布式查询引擎,相比于原来的查询引擎,Sparder 的优势体现在以下几点:
- 分布式的查询引擎,有效避免单点故障;
- 与构建所使用的计算引擎统一为 Spark;
- 对于复杂查询的性能有很大提高;
- 可以从 Spark 的新功能及其生态中获益。
在 Kylin4 中,Sparder 是作为一个 long-running 的 spark application 存在的。 Sparder 会根据 kylin.query.spark-conf
开头的配置项中配置的 Spark 参数来获取 Yarn 资源,如果配置的资源参数过大,可能会影响构建任务甚至无法成功启动 Sparder,如果 Sparder 没有成功启动,则所有查询任务都会失败,用户可以在 kylin WebUI 的 System 页面中检查 Sparder 状态。
默认情况下,用于查询的 spark 参数会设置的比较小,在生产环境中,大家可以适当把这些参数调大一些,以提升查询性能。
kylin.query.auto-sparder-context
参数用于控制是否在启动 kylin 的同时启动 Sparder,默认值为 false,即默认情况下会在执行第一条 SQL 的时候才启动 Sparder,由于这个原因,执行第一条 SQL 的时候的会花费较长时间。
如果你不希望第一条 SQL 的查询速度低于预期,可以设置 kylin.query.auto-sparder-context
为 true
,此时 Sparder 会随 Kylin 一起启动。
# Kylin 4.0 与 Kylin 3.1 功能对比
Feature | Kylin 3.1.0 | Kylin 4.0 |
---|---|---|
Storage | HBase | Parquet |
BuildEngine | MapReduce/Spark/Flink | New Spark Engine |
Metastore | HBase(Default)/Mysql | Mysql(Default) |
DataSource | Kafka/Hive/JDBC | Hive/CSV |
Global Dictionary | Two implementation | New implementation |
Cube Optimization Tool | Cube Planner | Cube Planner phase1 and Optimize cube manually |
Self-monitoring | System cube and Dashboard | System cube and Dashboard |
PushDown Engine | Hive/JDBC | Spark SQL |
Hadoop platform | HDP2/HDP3/CDH5/CDH6/EMR5 | HDP2/CDH5/CDH6/EMR5/EMR6/HDI |
Deployment mode | Single node/Cluster/Read and write separation | Single node/Cluster/Read and write separation |
# Kylin 4.0 性能表现
为了测试 Kylin4.0 的性能,我们分别在 SSB 数据集和 TPC-H 数据集上做了 benchmark,与 Kylin3.1.0 进行对比。测试环境为 4 个节点的 CDH 集群,所使用的 yarn 队列分配了 400G 内存和 128 cpu cores。
SSB(Star Schema Benchmark)是麻省州立大学波士顿校区的研究人员定义的基于现实商业应用的数据模型,用来评价决策支持技术方面应用的性能。
TPC-H是由TPC(Transaction Processing Performance Council)事务处理性能委员会公布的一套针对数据库决策支持能力的测试基准,通过模拟数据库中与业务相关的复杂查询考察数据库的综合处理能力,获取数据库操作的响应时间。
TPCH基准模型中定义了一个数据库模型,容量可以在1GB~10000GB的8个级别中进行选择。数据库模型包括CUSTOMER、LINEITEM、NATION、ORDERS、PART、PARTSUPP、REGION和SUPPLIER 共8张数据表,以及22条SQL查询语句,涉及内容广泛丰富,可以较完整地测试数据库的运算性能。
TPCH的SQL中不乏一些多层嵌套的复杂查询,执行性能较差。对于这些查询,如果能采用更合理的存储方案,设计低复杂度算法并配合并行等手段,将获得更优的性能。但遗憾的是,由于理论体系的限制,很多想法无法用SQL实现,而SQL程序员也因此不关注这些性能优化方法,经常只能忍受数据库的低速运算。
TPC-H 下载:https://github.com/gregrahn/
性能测试对比结果如下: Comparison of build duration and result size(SSB)
测试结果可以体现以下两点:
- kylin4 的构建速度与 kylin3.1.0 的 Spark Engine 相比有明显提升;
- Kylin4 构建后得到的预计算结果 Parquet 文件大小与 HBase 相比有明显减小;
Comparison of query response(SSB and TPC-H)
从查询结果对比中可以看出,对于简单查询,kylin3 与 Kylin4 不相上下,kylin4 略有不足;而对于复杂查询,kylin4 则体现出了明显的优势,查询速度比 kylin3 快很多。 并且,Kylin4 中的简单查询的性能还存在很大的优化空间。在有赞使用 Kylin4 的实践中,对于简单查询的性能可以优化到 1 秒以内。
# 如何升级
请参考文档:How to migrate metadata to Kylin4 (opens new window)
# Kylin 4.0 查询和构建调优
对于 Kylin4 的调优,请参考:How to improve cube building and query performance (opens new window)
# Kylin 4.0 用户案例
Why did Youzan choose Kylin4 (opens new window)
参考链接: Kylin Improvement Proposal 1: Parquet Storage (opens new window)
# 二、Kylin环境搭建(4.x)
# 软件要求
- Hadoop: cdh5.x, cdh6.x, hdp2.x, EMR5.x, EMR6.x, HDI4.x
- Hive: 0.13 - 1.2.1+
- Spark: 2.4.7/3.1.1
- Mysql: 5.1.17 及以上
- JDK: 1.8+
- OS: Linux only, CentOS 6.5+ or Ubuntu 16.0.4+
在 Hortonworks HDP2.4, Cloudera CDH 5.7 and 6.3.2, AWS EMR 5.31 and 6.0, Azure HDInsight 4.0 上测试通过。
我们建议您使用集成的 sandbox 来试用 Kylin 或进行开发,比如 HDP sandbox (opens new window),且要保证其有至少 10 GB 内存。在配置沙箱时,我们推荐您使用 Bridged Adapter 模型替代 NAT 模型。
# 硬件要求
运行 Kylin 的服务器的最低配置为 4 core CPU,16 GB 内存和 100 GB 磁盘。 对于高负载的场景,建议使用 24 core CPU,64 GB 内存或更高的配置。
# Hadoop 环境
Kylin 依赖于 Hadoop 集群处理大量的数据集。您需要准备一个配置好 HDFS, YARN, Hive, Zookeeper, Spark
以及你可能需要的其他服务的 Hadoop 集群供 Kylin 运行。
Kylin 可以在 Hadoop 集群的任意节点上启动。方便起见,您可以在 master 节点上运行 Kylin。但为了更好的稳定性,我们建议您将 Kylin 部署在一个干净的 Hadoop client 节点上,该节点上 Hive,HDFS 等命令行已安装好且 client 配置(如 core-site.xml
,hive-site.xml
及其他)也已经合理的配置且其可以自动和其它节点同步。
运行 Kylin 的 Linux 账户要有访问 Hadoop 集群的权限,包括创建/写入 HDFS 文件夹,Hive 表的权限。
# Kylin 安装
安装 Kylin 前需先部署好 Hadoop、Hive、Zookeeper、Hbase、Spark,并且需要在/etc/profile
中配置以下环境变量 HADOOP_HOME,HIVE_HOME,HBASE_HOME,SPARK_HOME 记
得 source 使其生效。
在我们需要安装的服务器执行以下操作:
从 Apache Kylin下载网站 (opens new window) 下载一个 Apache Kylin 4.0 的二进制文件。可通过如下命令行下载得到:
cd /usr/local/ wget --no-check-certificate https://dlcdn.apache.org/kylin/apache-kylin-4.0.1/apache-kylin-4.0.1-bin-spark2.tar.gz
1
2解压 tar 包,配置环境变量
$KYLIN_HOME
指向 Kylin 文件夹。tar -zxvf apache-kylin-4.0.1-bin-spark2.tar.gz mv apache-kylin-4.0.1-bin-spark2 kylin cd kylin export KYLIN_HOME=`pwd`
1
2
3
4使用脚本下载spark
$KYLIN_HOME/bin/download-spark.sh
1download-spark.sh 脚本只能下载 spark2.4.7, 如果您使用的 kylin 二进制包以 spark3 为后缀,您需要从Spark 官方网站 (opens new window)下载 spark3.1.1 的二进制包。
建议将 spark 二进制包解压后放置在 ${KYLIN_HOME} 目录下,并重命名为 spark,以避免兼容性问题。详情请查看:Refactor hive and hadoop dependency (opens new window)
如果您自定义配置了 ${SPARK_HOME} 指向环境中的 spark2.4.7/spark3.1.1,请保证环境中的 spark 是可以正常提交以及执行任务的。
配置 Mysql 元数据
创建数据库:kylin
Kylin 4.0 使用 Mysql 作为元数据存储,需要在 kylin.properties 中做如下配置:
kylin.metadata.url=kylin_metadata@jdbc,driverClassName=com.mysql.jdbc.Driver,url=jdbc:mysql://192.168.60.10:3306/kylin,username=root,password=123456 kylin.env.zookeeper-connect-string=192.168.60.13
1
2你需要修改其中的 Mysql 用户名和密码,以及存储元数据的 database 和 table。并将 mysql jdbc connector
mysql-connector-java-5.1.49.jar
放在$KYLIN_HOME/ext
目录下,没有该目录时请自行创建。 请参考 配置 Mysql 为 Metastore (opens new window) 了解 Mysql 作为 Metastore 的详细配置。CDH6.x环境配置
# 下载需要的jar包 wget https://cwiki.apache.org/confluence/download/attachments/173081375/hive-exec-1.21.2.3.1.0.0-78.jar?api=v2 wget https://repo1.maven.org/maven2/org/codehaus/woodstox/stax2-api/3.1.4/stax2-api-3.1.4.jar wget https://repo1.maven.org/maven2/commons-configuration/commons-configuration/1.10/commons-configuration-1.10.jar # 进入Kylin目录 cd $KYLIN_HOME # 将准备的jar包放进目录bin/hadoop3_jars/cdh6下 mkdir -p bin/hadoop3_jars/cdh6 mv hive-exec-1.21.2.3.1.0.0-78.jar stax2-api-3.1.4.jar commons-configuration-1.10.jar kylin/bin/hadoop3_jars/cdh6/ # 将Mysql JDBC 驱动放入指定目录 ext 下 mkdir $KYLIN_HOME/ext mv mysql-connector-java-5.7.33.jar $KYLIN_HOME/ext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16检查运行环境
Kylin 运行在 Hadoop 集群上,对各个组件的版本、访问权限及 CLASSPATH 等都有一定的要求,为了避免遇到各种环境问题,您可以运行
$KYLIN_HOME/bin/check-env.sh
脚本来进行环境检测,如果您的环境存在任何的问题,脚本将打印出详细报错信息。如果没有报错信息,代表您的环境适合 Kylin 运行。# 切换到HDFS用户执行检查 [hdfs@r-wb-15 bin]$ ./check-env.sh Retrieving hadoop conf dir... ...................................................[PASS] KYLIN_HOME is set to /home/kylin Checking hive ...................................................[PASS] Checking hadoop shell ...................................................[PASS] Checking hdfs working dir WARNING: log4j.properties is not found. HADOOP_CONF_DIR may be incomplete. ...................................................[PASS] WARNING: log4j.properties is not found. HADOOP_CONF_DIR may be incomplete. WARNING: log4j.properties is not found. HADOOP_CONF_DIR may be incomplete. Checking environment finished successfully. To check again, run 'bin/check-env.sh' manually.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15启动Kylin
运行
$KYLIN_HOME/bin/kylin.sh start
脚本来启动 Kylin,界面输出如下:[hdfs@r-wb-15 kylin]$ bin/kylin.sh start Retrieving hadoop conf dir... ...................................................[PASS] KYLIN_HOME is set to /home/kylin Checking hive ...................................................[PASS] Checking hadoop shell ...................................................[PASS] Checking hdfs working dir WARNING: log4j.properties is not found. HADOOP_CONF_DIR may be incomplete. ...................................................[PASS] WARNING: log4j.properties is not found. HADOOP_CONF_DIR may be incomplete. WARNING: log4j.properties is not found. HADOOP_CONF_DIR may be incomplete. Checking environment finished successfully. To check again, run 'bin/check-env.sh' manually. Retrieving hadoop conf dir... Retrieving Spark dependency... Start replace hadoop jars under /home/kylin/spark/jars. Find platform specific jars:/opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop/client/hadoop-annotations-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop/client/hadoop-auth-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop/client/hadoop-common-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop/hadoop-annotations-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop/hadoop-common-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop/hadoop-auth-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop-hdfs/hadoop-hdfs-client.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop-hdfs/hadoop-hdfs-httpfs.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop-hdfs/hadoop-hdfs-native-client.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop-hdfs/hadoop-hdfs-native-client-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop-hdfs/hadoop-hdfs-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop-hdfs/hadoop-hdfs-httpfs-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop-hdfs/hadoop-hdfs-client-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/hadoop-mapreduce-client-app-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/hadoop-mapreduce-client-core-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/hadoop-mapreduce-client-jobclient-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/hadoop-mapreduce-client-shuffle-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/hadoop-mapreduce-client-common-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop-yarn/hadoop-yarn-common-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop-yarn/hadoop-yarn-api-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop-yarn/hadoop-yarn-server-web-proxy-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop-yarn/hadoop-yarn-client-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../hadoop-yarn/hadoop-yarn-server-common-3.0.0-cdh6.3.2.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../../jars/htrace-core4-4.2.0-incubating.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../../jars/htrace-core4-4.1.0-incubating.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../../jars/woodstox-core-5.0.3.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../../jars/woodstox-core-5.1.0.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../../jars/commons-configuration2-2.1.1.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../../jars/woodstox-core-asl-4.4.1.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../../jars/re2j-1.1.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../../jars/commons-configuration2-2.1.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../../jars/stax2-api-3.1.4.jar /opt/cloudera/parcels/CDH/lib/hadoop-mapreduce/../../jars/re2j-1.0.jar , will replace with these jars under /home/kylin/spark/jars. Copy jars from /home/kylin/bin/hadoop3_jars/cdh6 Done hadoop jars replacement under /home/kylin/spark/jars. (Not all processes could be identified, non-owned process info will not be shown, you would have to be root to see it all.) Start to check whether we need to migrate acl tables Not HBase metadata. Skip check. A new Kylin instance is started by hdfs. To stop it, run 'kylin.sh stop' Check the log at /home/kylin/logs/kylin.log Web UI is at http://r-wb-15:7070/kylin
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启动成功可以访问页面:http://r-wb-15:7070/kylin
默认账号密码(注意大小写区分):ADMIN/KYLIN
访问页面提示以下页面,说明启动成功。
Kylin目录结构·
bin
: shell 脚本,用于启动/停止 Kylin,备份/恢复 Kylin 元数据,以及一些检查端口、获取 Hive/HBase 依赖的方法等;conf
: Hadoop 任务的 XML 配置文件,这些文件的作用可参考配置页面 (opens new window)lib
: 供外面应用使用的 jar 文件,例如 Hadoop 任务 jar.meta_backups
: 执行bin/metastore.sh backup
后的默认的备份目录;sample_cube
用于创建样例 Cube 和表的文件。spark
: 使用kylin脚本下载得到的 spark。tomcat
: 自带的 tomcat,用于启动 Kylin 服务。tool
: 用于执行一些命令行的jar文件。
使用 Kylin
Kylin 启动后您可以通过浏览器
http://<hostname>:7070/kylin
进行访问。 其中<hostname>
为具体的机器名、IP 地址或域名,默认端口为 7070。 初始用户名和密码是ADMIN/KYLIN
。 服务器启动后,您可以通过查看$KYLIN_HOME/logs/kylin.log
获得运行时日志。停止 Kylin
运行
$KYLIN_HOME/bin/kylin.sh stop
脚本来停止 Kylin,界面输出如下:Retrieving hadoop conf dir... KYLIN_HOME is set to /usr/local/apache-kylin-4.0.0-bin Stopping Kylin: 25964 Stopping in progress. Will check after 2 secs again... Kylin with pid 25964 has been stopped.
1
2
3
4
5您可以运行
ps -ef | grep kylin
来查看 Kylin 进程是否已停止。HDFS 目录结构
Kylin 会在 HDFS 上生成文件,默认根目录是 “/kylin/”, 然后会使用 Kylin 集群的元数据表名作为第二层目录名,默认为 “kylin_metadata” (可以在
conf/kylin.properties
中定制).通常,
/kylin/kylin_metadata
目录下按照不同的 project 存放数据,比如 learn_kylin 项目的数据目录为/kylin/kylin_metadata/learn_kylin
, 该目录下通常包括以下子目录: 1.job_tmp
: 存放执行任务过程中生成的临时文件。 2.parquet
: 存放各个 cube 的 cuboid 文件。 3.table_snapshot
: 存放维度表快照。## 三、使用教程
# 提前准备
将数据写入Hive
表中,供测试使用
- 创建hive表
create EXTERNAL TABLE site_base_hive
(
id string,
site_code string,
site_name string,
audit_code string,
culture_code string,
licence_code string,
webopen_date string,
licence_date string,
fire_code string,
business_status int,
stop_business_date string,
licence_status int,
install_status int,
area_code string,
police_station string,
address string,
class_level string,
access_operator string,
legal_person string,
legal_phone string,
principal string,
principal_phone string,
webmaster string,
webmaster_phone string,
audit_vendor string,
charge_system string,
charge_sys_version string,
longitude float,
latitude float,
altitude float,
safety_num string,
ba_terminal_num int,
area_size float,
is_chain int,
del_flag string,
creator_by string,
create_time string,
updator_by string,
update_time string,
site_name_qp string,
site_name_jp string,
legal_person_qp string,
legal_person_jp string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\n'
STORED AS parquet TBLPROPERTIES('parquet.compression'='SNAPPY');
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
create EXTERNAL TABLE offline_hive
(
id string,
checkin_code string,
checkin_type int,
site_code string,
culture_code string,
site_name string,
area_code string,
area string,
credential_type string,
certificate_code string,
nation string,
name string,
sexcode string,
birthday string,
issuing_authority string,
certificate_valid string,
often_address string,
face_status string,
face_audit_result int,
session_id string,
terminalid string,
terminalip string,
terminalname string,
onlinetime bigint,
offlinetime bigint,
mac_address string,
scene_photo string,
similarity DECIMAL,
head_photo string,
is_upload int,
card_type int,
card_no string,
illegal_group_id string,
insert_time string,
update_time string,
data_source string
)
ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t'
LINES TERMINATED BY '\n'
STORED AS parquet TBLPROPERTIES('parquet.compression'='SNAPPY');
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
- 从mysql导入数据到Hive
sqoop import \
--connect jdbc:mysql://192.168.60.10:3306/test_data \
--username root \
--password 123456 \
--table site_base \
--delete-target-dir \
--hive-import \
--hive-database test_data \
--hive-table site_base_hive \
--hive-overwrite \
--fields-terminated-by "\t" \
--as-parquetfile \
# parquet模式下当mysql字段类型与hive字段类型不相同时,需要手动指定导入的类型,否则会报错
--map-column-java webopen_date=String,licence_date=String,stop_business_date=String,create_time=String,update_time=String \
--map-column-hive webopen_date=String,licence_date=String,stop_business_date=String,create_time=String,update_time=String \
-m 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
sqoop import \
--connect jdbc:mysql://192.168.60.10:3306/test_data \
--username root \
--password 123456 \
--table offline \
--delete-target-dir \
--hive-import \
--hive-database test_data \
--hive-table offline_hive \
--hive-overwrite \
--fields-terminated-by "\t" \
--as-parquetfile \
--map-column-java insert_time=String,update_time=String \
--map-column-hive insert_time=String,update_time=String \
-m 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Web页面介绍
# 支持的浏览器
Windows: Google Chrome, FireFox
Mac: Google Chrome, FireFox, Safari
# 登录系统
# 创建工程
点击加号
输入项目名称、项目描述,点击Submit提交
创建成功
# 选择数据源
虽然 Kylin 使用 SQL 作为查询接口并利用 Hive 元数据,Kylin 不会让用户查询所有的 hive 表,因为到目前为止它是一个预构建 OLAP(MOLAP) 系统。为了使表在 Kylin 中可用,使用 “Sync” 方法能够方便地从 Hive 中同步表。
选择加载数据源方式
选择需要加载的表,点击
Sync
查看同步的数据源
# 创建Model
创建 cube 前,需定义一个数据模型。数据模型定义了一个星型(star schema)或雪花(snowflake schema)模型。一个模型可以被多个 cube 使用。
点击顶部的
Model
,然后点击Models
标签。点击+New
按钮,在下拉框中选择New Model
。输入 model 的名字和可选的描述,点击
Next
在
Fact Table
中,为模型选择事实表。【可选】点击
Add Lookup Table
按钮添加一个 lookup 表。选择表名和关联类型(内连接或左连接)点击
New Join Condition
按钮,左边选择事实表的外键,右边选择 lookup 表的主键。如果有多于一个 join 列重复执行。点击 “OK”,重复2,3步来添加更多的 lookup 表。完成后,点击 “Next”。
Dimensions
页面允许选择在子 cube 中用作维度的列(统计分析温度字段),然后点击Columns
列,在下拉框中选择需要的列。点击 “Next” 到达 “Measures” 页面,选择作为 measure 的列,其只能从事实表中选择。
这里我没有选择,我只想统计数量,没有求和等其他操作
点击 “Next” 到达 “Settings” 页面,如果事实表中的数据每日增长,选择
Partition Date Column
中相应的 日期列以及日期格式,否则就将其留白。【可选】选择是否需要 “time of the day” 列,默认情况下为
No
。如果选择Yes
, 选择Partition Time Column
中相应的 time 列以及 time 格式【可选】如果在从 hive 抽取数据时候想做一些筛选,可以在
Filter
中输入筛选条件。点击
Save
然后选择Yes
来保存 data model。创建完成,data model 就会列在左边Models
列表中。创建完成可以看到Models
# 创建Cube
创建完 data model,可以开始创建 cube。
点击顶部
Model
,然后点击Models
标签。点击+New
按钮,在下拉框中选择New Cube
。填写Cube 信息,选择 data model,输入 cube 名字;点击
Next
进行下一步cube 名字可以使用字母,数字和下划线(空格不允许)。
Notification Email List
是运用来通知job执行成功或失败情况的邮箱列表。Notification Events
是触发事件的状态。添加维度
1.添加真正的维度字段(将来会影响 Cuboid 的个数,并且只能从 model 维度字段里面选择)
2.后续统计条件字段只能从维度设置字段进行查询
点击
Add Dimension
在弹窗中显示的事实表和 lookup 表里勾选输入需要的列。Lookup 表的列有2个选项:“Normal” 和 “Derived”(默认)。“Normal” 添加一个普通独立的维度列,“Derived” 添加一个 derived 维度,derived 维度不会计算入 cube,将由事实表的外键推算出。(推荐使用
Normal
)添加
度量
值点击
+Measure
按钮添加一个新的度量。
根据它的表达式共有7种不同类型的度量:
SUM
、MAX
、MIN
、COUNT
、COUNT_DISTINCT
TOP_N
和PERCENTILE
。请合理选择COUNT_DISTINCT
和TOP_N
返回类型,它与 cube 的大小相关。这里度量值默认有一个count(*),其他的可自行选择。注意:这里的度量值只能从创建模型选择的字段中进行选择。
更新配置
这一步骤是为增量构建 cube 而设计的。
Auto Merge Thresholds
: 自动合并小的 segments 到中等甚至更大的 segment。如果不想自动合并,删除默认2个选项。Volatile Range
: 默认为0,会自动合并所有可能的 cube segments,或者用 ‘Auto Merge’ 将不会合并最新的 [Volatile Range] 天的 cube segments。Retention Threshold
: 只会保存 cube 过去几天的 segment,旧的 segment 将会自动从头部删除;0表示不启用这个功能。Partition Start Date
: cube 的开始日期.高级设置
Aggregation Groups
: Cube 中的维度可以划分到多个聚合组中。默认 kylin 会把所有维度放在一个聚合组,当维度较多时,产生的组合数可能是巨大的,会造成 Cube 爆炸;如果你很好的了解你的查询模式,那么你可以创建多个聚合组。在每个聚合组内,使用 “Mandatory Dimensions”, “Hierarchy Dimensions” 和 “Joint Dimensions” 来进一步优化维度组合。Mandatory Dimensions
: 必要维度,用于总是出现的维度。例如,如果你的查询中总是会带有 “ORDER_DATE” 做为 group by 或 过滤条件, 那么它可以被声明为必要维度。这样一来,所有不含此维度的 cuboid 就可以被跳过计算。Hierarchy Dimensions
: 层级维度,例如 “国家” -> “省” -> “市” 是一个层级;不符合此层级关系的 cuboid 可以被跳过计算,例如 [“省”], [“市”]. 定义层级维度时,将父级别维度放在子维度的左边。Joint Dimensions
:联合维度,有些维度往往一起出现,或者它们的基数非常接近(有1:1映射关系)。例如 “user_id” 和 “email”。把多个维度定义为组合关系后,所有不符合此关系的 cuboids 会被跳过计算。关于更多维度优化,请阅读这个博客: 新的聚合组 (opens new window)
Rowkeys
: 是由维度编码值组成。你可以拖拽维度列去调整其在 rowkey 中位置; 位于rowkey前面的列,将可以用来大幅缩小查询的范围。通常建议将 mandantory 维度放在开头, 然后是在过滤 ( where 条件)中起到很大作用的维度;如果多个列都会被用于过滤,将高基数的维度(如 user_id)放在低基数的维度(如 age)的前面。
此外,你还可以在这里指定使用某一列作为 shardBy 列,kylin4.0 会根据 shardBy 列对存储文件进行分片,分片能够使查询引擎跳过不必要的文件,提高查询性能,最好选择高基列并且会在多个 cuboid 中出现的列作为 shardBy 列。
Mandatory Cuboids
: 维度组合白名单。确保你想要构建的 cuboid 能被构建。Cube Engine
: cube 构建引擎。Spark构建。这里我们使用默认。
重写配置
Kylin 允许在 Cube 级别覆盖部分 kylin.properties 中的配置,你可以在这里定义覆盖的属性。如果你没有要配置的,点击
Next
按钮。概览 & 保存
你可以概览你的 cube 并返回之前的步骤进行修改。点击
Save
按钮完成 cube 创建。可以返回查看Cube信息
# Cube构建与监控
在
Models
页面中,点击 cube 栏右侧的Action
下拉按钮并选择Build
操作。选择后会出现一个弹出窗口,点击
Start Date
或者End Date
输入框选择这个增量 cube 构建的起始日期。上面如果没有选择分区表的话,这里不会提示选择日期
点击
Submit
提交请求。成功之后,你将会在Monitor
页面看到新建的 job和进度。新建的 job 是 “pending” 状态;一会儿,它就会开始运行并且你可以通过刷新 web 页面或者点击刷新按钮来查看进度。
等待 job 完成。期间如要放弃这个 job ,点击
Actions
->Discard
按钮。查看
Build
进度计算中查看日志,点击
Job
弹出
Spark UI
新页面,可以看到计算步骤等到 job 100%完成,cube 的状态就会变为 “Ready”, 意味着它已经准备好进行 SQL 查询。在
Model
页,找到 cube,然后点击 cube 名展开消息,在 “Storage” 标签下,列出 cube segments。每一个 segment 都有 start/end 时间;Parquet 文件相关的信息也会列出。
# WEB UI查询SQL
进入Insight
输入需要执行的统计SQL,进行查询。
这里查询用的字段就是我们之前设置的维度字段,如果使用不设置在维度中的字段,会提示报错,找不到该字段
# 三、SSB数据实际测试
# 生成SBB基准测试数据
SSB基准测试包括
1个事实表:lineorder 4个维度表:customer,part,dwdate,supplier 13条标准SQL查询测试语句:统计查询、多表关联、sum、复杂条件、group by、order by等组合方式。
环境需要gcc
yum install -y gcc
1
将工具上传到Linux服务器并解压
[root@r-wb-15 ~]# ll -rw-r--r--. 1 root root 102995 3月 6 14:17 dbgen.zip [root@r-wb-15 ~]# unzip dbgen.zip [root@r-wb-15 ~]# cd dbgen [root@r-wb-15 dbgen]# make
1
2
3
4
5查看生成的
dbgen
是否可用[root@r-wb-15 dbgen]# ./dbgen -h SSBM (Star Schema Benchmark) Population Generator (Version 1.0.0) Copyright Transaction Processing Performance Council 1994 - 2000 USAGE: dbgen [-{vfFD}] [-O {fhmsv}][-T {pcsdla}] [-s <scale>][-C <procs>][-S <step>] dbgen [-v] [-O {dfhmr}] [-s <scale>] [-U <updates>] [-r <percent>]
1
2
3
4
5
6
7生成数据文件
# 利用dbgen生成示例数据,-T指定表,-s指定数据放大系数 ./dbgen -s 8 -T c # CUSTOMER表 ./dbgen -s 24 -T p # PART表 ./dbgen -s 8 -T s # SUPPLIER表 ./dbgen -s 1 -T d # DATE_DIM表 ./dbgen -s 2 -T l # LINEORDER表
1
2
3
4
5
6创建表结构
CREATE TABLE CUSTOMER ( C_CUSTKEY INTEGER, C_NAME VARCHAR(25) NOT NULL, C_ADDRESS VARCHAR(40) NOT NULL, C_CITY VARCHAR(10) NOT NULL, C_NATION VARCHAR(15) NOT NULL, C_REGION VARCHAR(12) NOT NULL, C_PHONE VARCHAR(15) NOT NULL, C_MKTSEGMENT VARCHAR(10) NOT NULL); CREATE TABLE DATES ( D_DATEKEY INTEGER, D_DATE VARCHAR(18) NOT NULL, D_DAYOFWEEK VARCHAR(18) NOT NULL, D_MONTH VARCHAR(9) NOT NULL, D_YEAR INTEGER NOT NULL, D_YEARMONTHNUM INTEGER, D_YEARMONTH VARCHAR(7) NOT NULL, D_DAYNUMINWEEK INTEGER, D_DAYNUMINMONTH INTEGER, D_DAYNUMINYEAR INTEGER, D_MONTHNUMINYEAR INTEGER, D_WEEKNUMINYEAR INTEGER, D_SELLINGSEASON VARCHAR(12) NOT NULL, D_LASTDAYINWEEKFL INTEGER, D_LASTDAYINMONTHFL INTEGER, D_HOLIDAYFL INTEGER, D_WEEKDAYFL INTEGER); CREATE TABLE PART ( P_PARTKEY INTEGER, P_NAME VARCHAR(22) NOT NULL, P_MFGR VARCHAR(6) NOT NULL, P_CATEGORY VARCHAR(7) NOT NULL, P_BRAND VARCHAR(9) NOT NULL, P_COLOR VARCHAR(11) NOT NULL, P_TYPE VARCHAR(25) NOT NULL, P_SIZE INTEGER NOT NULL, P_CONTAINER VARCHAR(10) NOT NULL); CREATE TABLE SUPPLIER ( S_SUPPKEY INTEGER, S_NAME VARCHAR(25) NOT NULL, S_ADDRESS VARCHAR(25) NOT NULL, S_CITY VARCHAR(10) NOT NULL, S_NATION VARCHAR(15) NOT NULL, S_REGION VARCHAR(12) NOT NULL, S_PHONE VARCHAR(15) NOT NULL); CREATE TABLE LINEORDER ( LO_ORDERKEY BIGINT, LO_LINENUMBER BIGINT, LO_CUSTKEY INTEGER NOT NULL, LO_PARTKEY INTEGER NOT NULL, LO_SUPPKEY INTEGER NOT NULL, LO_ORDERDATE INTEGER NOT NULL, LO_ORDERPRIOTITY VARCHAR(15) NOT NULL, LO_SHIPPRIOTITY INTEGER, LO_QUANTITY BIGINT, LO_EXTENDEDPRICE BIGINT, LO_ORDTOTALPRICE BIGINT, LO_DISCOUNT BIGINT, LO_REVENUE BIGINT, LO_SUPPLYCOST BIGINT, LO_TAX BIGINT, LO_COMMITDATE INTEGER NOT NULL, LO_SHIPMODE VARCHAR(10) NOT NULL);
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导入数据
导入之前生成的数据
set autocommit=off; load data infile '/opt/customer.tbl' into table CUSTOMER fields terminated by '|' lines terminated by '| '; commit; load data infile '/opt/lineorder.tbl' into table LINEORDER fields terminated by '|' lines terminated by '| '; commit; load data infile '/opt/supplier.tbl' into table SUPPLIER fields terminated by '|' lines terminated by '| '; commit; load data infile '/opt/part.tbl' into table PART fields terminated by '|' lines terminated by '| '; commit; load data infile '/opt/date.tbl' into table DATES fields terminated by '|' lines terminated by '| '; commit;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20Hive创建相对应的表
create EXTERNAL TABLE CUSTOMER ( C_CUSTKEY int, C_NAME string, C_ADDRESS string, C_CITY string, C_NATION string, C_REGION string, C_PHONE string, C_MKTSEGMENT string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' STORED AS parquet TBLPROPERTIES('parquet.compression'='SNAPPY'); create EXTERNAL TABLE DATES ( D_DATEKEY int, D_DATE string, D_DAYOFWEEK string, D_MONTH string, D_YEAR int, D_YEARMONTHNUM int, D_YEARMONTH string, D_DAYNUMINWEEK int, D_DAYNUMINMONTH int, D_DAYNUMINYEAR int, D_MONTHNUMINYEAR int, D_WEEKNUMINYEAR int, D_SELLINGSEASON string, D_LASTDAYINWEEKFL int, D_LASTDAYINMONTHFL int, D_HOLIDAYFL int, D_WEEKDAYFL int ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' STORED AS parquet TBLPROPERTIES('parquet.compression'='SNAPPY'); create EXTERNAL TABLE LINEORDER ( LO_ORDERKEY bigint, LO_LINENUMBER bigint, LO_CUSTKEY int, LO_PARTKEY int, LO_SUPPKEY int, LO_ORDERDATE int, LO_ORDERPRIOTITY string, LO_SHIPPRIOTITY int, LO_QUANTITY bigint, LO_EXTENDEDPRICE bigint, LO_ORDTOTALPRICE bigint, LO_DISCOUNT bigint, LO_REVENUE bigint, LO_SUPPLYCOST bigint, LO_TAX bigint, LO_COMMITDATE int, LO_SHIPMODE string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' STORED AS parquet TBLPROPERTIES('parquet.compression'='SNAPPY'); create EXTERNAL TABLE PART ( P_PARTKEY int, P_NAME string, P_MFGR string, P_CATEGORY string, P_BRAND string, P_COLOR string, P_TYPE string, P_SIZE int, P_CONTAINER string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' STORED AS parquet TBLPROPERTIES('parquet.compression'='SNAPPY'); create EXTERNAL TABLE SUPPLIER ( S_SUPPKEY int, S_NAME string, S_ADDRESS string, S_CITY string, S_NATION string, S_REGION string, S_PHONE string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY '\t' LINES TERMINATED BY '\n' STORED AS parquet TBLPROPERTIES('parquet.compression'='SNAPPY');
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
87Sqoop
同步Mysql
数据到Hive
sqoop import \ --connect jdbc:mysql://192.168.60.10:3306/test_data \ --username root \ --password 123456 \ --table SUPPLIER \ --delete-target-dir \ --hive-import \ --hive-database test_data \ --hive-table SUPPLIER \ --hive-overwrite \ --fields-terminated-by "\t" \ --as-parquetfile \ -m 1 sqoop import \ --connect jdbc:mysql://192.168.60.10:3306/test_data \ --username root \ --password 123456 \ --table CUSTOMER \ --delete-target-dir \ --hive-import \ --hive-database test_data \ --hive-table CUSTOMER \ --hive-overwrite \ --fields-terminated-by "\t" \ --as-parquetfile \ -m 1 sqoop import \ --connect jdbc:mysql://192.168.60.10:3306/test_data \ --username root \ --password 123456 \ --table DATES \ --delete-target-dir \ --hive-import \ --hive-database test_data \ --hive-table DATES \ --hive-overwrite \ --fields-terminated-by "\t" \ --as-parquetfile \ -m 1 sqoop import \ --connect jdbc:mysql://192.168.60.10:3306/test_data \ --username root \ --password 123456 \ --table LINEORDER \ --delete-target-dir \ --hive-import \ --hive-database test_data \ --hive-table LINEORDER \ --hive-overwrite \ --fields-terminated-by "\t" \ --as-parquetfile \ -m 1 sqoop import \ --connect jdbc:mysql://192.168.60.10:3306/test_data \ --username root \ --password 123456 \ --table PART \ --delete-target-dir \ --hive-import \ --hive-database test_data \ --hive-table PART \ --hive-overwrite \ --fields-terminated-by "\t" \ --as-parquetfile \ -m 1
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标准测试SQL
PROMPT Q1.1 SELECT SUM(LO_EXTENDEDPRICE*LO_DISCOUNT) AS REVENUE FROM LINEORDER, DATES WHERE LO_ORDERDATE = D_DATEKEY AND D_YEAR = 1993 AND LO_DISCOUNT BETWEEN 1 AND 3 AND LO_QUANTITY < 25; PROMPT Q1.2 SELECT SUM(LO_EXTENDEDPRICE*LO_DISCOUNT) AS REVENUE FROM LINEORDER, DATES WHERE LO_ORDERDATE = D_DATEKEY AND D_YEARMONTH = 'Jan1994' AND LO_DISCOUNT BETWEEN 4 AND 6 AND LO_QUANTITY BETWEEN 26 AND 35; PROMPT Q1.3 SELECT SUM(LO_EXTENDEDPRICE*LO_DISCOUNT) AS REVENUE FROM LINEORDER, DATES WHERE LO_ORDERDATE = D_DATEKEY AND D_WEEKNUMINYEAR = 6 AND D_YEAR = 1994 AND LO_DISCOUNT BETWEEN 5 AND 7 AND LO_QUANTITY BETWEEN 26 AND 35; PROMPT Q2.1 SELECT SUM(LO_REVENUE), D_YEAR, P_BRAND FROM LINEORDER, DATES, PART, SUPPLIER WHERE LO_ORDERDATE = D_DATEKEY AND LO_PARTKEY = P_PARTKEY AND LO_SUPPKEY = S_SUPPKEY AND P_CATEGORY = 'MFGR#12' AND S_REGION = 'AMERICA' GROUP BY D_YEAR, P_BRAND ORDER BY D_YEAR, P_BRAND; PROMPT Q2.2 SELECT SUM(LO_REVENUE), D_YEAR, P_BRAND FROM LINEORDER, DATES, PART, SUPPLIER WHERE LO_ORDERDATE = D_DATEKEY AND LO_PARTKEY = P_PARTKEY AND LO_SUPPKEY = S_SUPPKEY AND P_BRAND BETWEEN 'MFGR#2221' AND 'MFGR#2228' AND S_REGION = 'ASIA' GROUP BY D_YEAR, P_BRAND ORDER BY D_YEAR, P_BRAND; PROMPT Q2.3 SELECT SUM(LO_REVENUE), D_YEAR, P_BRAND FROM LINEORDER, DATES, PART, SUPPLIER WHERE LO_ORDERDATE = D_DATEKEY AND LO_PARTKEY = P_PARTKEY AND LO_SUPPKEY = S_SUPPKEY AND P_BRAND= 'MFGR#2239' AND S_REGION = 'EUROPE' GROUP BY D_YEAR, P_BRAND ORDER BY D_YEAR, P_BRAND; PROMPT Q3.1 SELECT C_NATION, S_NATION, D_YEAR, SUM(LO_REVENUE) AS REVENUE FROM CUSTOMER, LINEORDER, SUPPLIER, DATES WHERE LO_CUSTKEY = C_CUSTKEY AND LO_SUPPKEY = S_SUPPKEY AND LO_ORDERDATE = D_DATEKEY AND C_REGION = 'ASIA' AND S_REGION = 'ASIA' AND D_YEAR >= 1992 AND D_YEAR <= 1997 GROUP BY C_NATION, S_NATION, D_YEAR ORDER BY D_YEAR ASC, REVENUE DESC; PROMPT Q3.2 SELECT C_CITY, S_CITY, D_YEAR, SUM(LO_REVENUE) AS REVENUE FROM CUSTOMER, LINEORDER, SUPPLIER, DATES WHERE LO_CUSTKEY = C_CUSTKEY AND LO_SUPPKEY = S_SUPPKEY AND LO_ORDERDATE = D_DATEKEY AND C_NATION = 'UNITED STATES' AND S_NATION = 'UNITED STATES' AND D_YEAR >= 1992 AND D_YEAR <= 1997 GROUP BY C_CITY, S_CITY, D_YEAR ORDER BY D_YEAR ASC, REVENUE DESC; PROMPT Q3.3 SELECT C_CITY, S_CITY, D_YEAR, SUM(LO_REVENUE) AS REVENUE FROM CUSTOMER, LINEORDER, SUPPLIER, DATES WHERE LO_CUSTKEY = C_CUSTKEY AND LO_SUPPKEY = S_SUPPKEY AND LO_ORDERDATE = D_DATEKEY AND (C_CITY='UNITED KI1' OR C_CITY='UNITED KI5') AND (S_CITY='UNITED KI1' OR S_CITY='UNITED KI5') AND D_YEAR >= 1992 AND D_YEAR <= 1997 GROUP BY C_CITY, S_CITY, D_YEAR ORDER BY D_YEAR ASC, REVENUE DESC; PROMPT Q3.4 SELECT C_CITY, S_CITY, D_YEAR, SUM(LO_REVENUE) AS REVENUE FROM CUSTOMER, LINEORDER, SUPPLIER, DATES WHERE LO_CUSTKEY = C_CUSTKEY AND LO_SUPPKEY = S_SUPPKEY AND LO_ORDERDATE = D_DATEKEY AND (C_CITY='UNITED KI1' OR C_CITY='UNITED KI5') AND (S_CITY='UNITED KI1' OR S_CITY='UNITED KI5') AND D_YEARMONTH = 'Dec1997' GROUP BY C_CITY, S_CITY, D_YEAR ORDER BY D_YEAR ASC, REVENUE DESC; PROMPT Q4.1 SELECT D_YEAR, C_NATION, SUM(LO_REVENUE - LO_SUPPLYCOST) AS PROFIT FROM DATES, CUSTOMER, SUPPLIER, PART, LINEORDER WHERE LO_CUSTKEY = C_CUSTKEY AND LO_SUPPKEY = S_SUPPKEY AND LO_PARTKEY = P_PARTKEY AND LO_ORDERDATE = D_DATEKEY AND C_REGION = 'AMERICA' AND S_REGION = 'AMERICA' AND (P_MFGR = 'MFGR#1' OR P_MFGR = 'MFGR#2') GROUP BY D_YEAR, C_NATION ORDER BY D_YEAR, C_NATION; PROMPT Q4.2 SELECT D_YEAR, S_NATION, P_CATEGORY, SUM(LO_REVENUE - LO_SUPPLYCOST) AS PROFIT FROM DATES, CUSTOMER, SUPPLIER, PART, LINEORDER WHERE LO_CUSTKEY = C_CUSTKEY AND LO_SUPPKEY = S_SUPPKEY AND LO_PARTKEY = P_PARTKEY AND LO_ORDERDATE = D_DATEKEY AND C_REGION = 'AMERICA' AND S_REGION = 'AMERICA' AND (D_YEAR = 1997 OR D_YEAR = 1998) AND (P_MFGR = 'MFGR#1' OR P_MFGR = 'MFGR#2') GROUP BY D_YEAR, S_NATION, P_CATEGORY ORDER BY D_YEAR, S_NATION, P_CATEGORY; PROMPT Q4.3 SELECT D_YEAR, S_CITY, P_BRAND, SUM(LO_REVENUE - LO_SUPPLYCOST) AS PROFIT FROM DATES, CUSTOMER, SUPPLIER, PART, LINEORDER WHERE LO_CUSTKEY = C_CUSTKEY AND LO_SUPPKEY = S_SUPPKEY AND LO_PARTKEY = P_PARTKEY AND LO_ORDERDATE = D_DATEKEY AND S_NATION = 'UNITED STATES' AND (D_YEAR = 1997 OR D_YEAR = 1998) AND P_CATEGORY = 'MFGR#14' GROUP BY D_YEAR, S_CITY, P_BRAND ORDER BY D_YEAR, S_CITY, P_BRAND;
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
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174这里我们先用这个sql做测试
SELECT SUM(LO_REVENUE), D_YEAR, P_BRAND FROM LINEORDER, DATES, PART, SUPPLIER WHERE LO_ORDERDATE = D_DATEKEY AND LO_PARTKEY = P_PARTKEY AND LO_SUPPKEY = S_SUPPKEY AND P_CATEGORY = 'MFGR#12' AND S_REGION = 'AMERICA' GROUP BY D_YEAR, P_BRAND ORDER BY D_YEAR, P_BRAND; Kylin不支持笛卡尔积查询,我们转换为JOIN查询 SELECT SUM(LO_REVENUE) AS SUM1, D_YEAR, P_BRAND FROM LINEORDER JOIN DATES ON LO_ORDERDATE = D_DATEKEY JOIN PART ON LO_PARTKEY = P_PARTKEY JOIN SUPPLIER ON LO_SUPPKEY = S_SUPPKEY WHERE P_CATEGORY = 'MFGR#12' AND S_REGION = 'AMERICA' GROUP BY D_YEAR, P_BRAND ORDER BY D_YEAR, P_BRAND;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21Kylin不支持笛卡尔积查询,查询报错如下
Cartesian Join is not supported. while executing SQL: "select * from (SELECT SUM(LO_REVENUE), D_YEAR, P_BRAND FROM LINEORDER, DATES, PART, SUPPLIER WHERE LO_ORDERDATE = D_DATEKEY AND LO_PARTKEY = P_PARTKEY AND LO_SUPPKEY = S_SUPPKEY AND P_CATEGORY = 'MFGR#12' AND S_REGION = 'AMERICA' GROUP BY D_YEAR, P_BRAND ORDER BY D_YEAR, P_BRAND) limit 50000"
1Kylin创建Model
创建CUBE
一直Next直至完成
build CUBE
Build 完成
Build 构建共花了156分钟
数据图表展示及导出
# Mysql查询、Hive查询、Kylin查询对比
查询类型 耗时 Mysql 超时 Kylin 1秒以内 Hive 74.237秒 Mysql查询超时
Kylin查询秒级响应
Hive查询74秒
# 四、Kylin使用注意事项
# 只能按照构建Model的连接条件写SQL查询
在创建Model时候我们会指定表之间的关联关系,这个时候指定的关系,在后面查询SQL也只能查询这种关系的SQL。
如果不按照设定的join
类型,会提示错误
示例:改成LEFT JOIN
去查询,无法返回结果
# 只能按照构建 Cube 时选择的维度字段分组统计
分组统计、查询字段必须在创建Cube
时选择上维度,否则无法当做条件查询。
示例:我们使用未在维度中字段查询,提示报错
# 只能统计构建 Cube 时选择的度量值字段
在统计时候只能统计添加度量值字段(默认会有一个count(*)
来统计数量。)
示例:统计不在度量值的字段会提示报错
# 五、Kylin每日自动构建Cube
Kylin 提供了 Restful API,因次我们可以将构建 cube 的命令写到脚本中,将脚本交给 azkaban 或者 oozie 这样的调度工具,以实现定时调度的功能。
认证密码加密方式:
${Authorization}计算方式:
Base64($username:$password)
Authorization: Basic ${Authorization}
Authorization: Basic QURNSU46S1lMSU4=
2
3
4
5
kylin_cube_build.sh 脚本如下:
#!/bin/bash
#从第 1 个参数获取 cube_name
cube_name=$1 #从第 2 个参数获取构建 cube 时间
if [ -n "$2" ]
then
do_date=$2
else
do_date=`date -d '-1 day' +%F`
fi
#获取执行时间的 00:00:00 时间戳(0 时区)
start_date_unix=`date -d "$do_date 08:00:00" +%s`
#秒级时间戳变毫秒级
start_date=$(($start_date_unix*1000))
#获取执行时间的 24:00 的时间戳
stop_date=$(($start_date+86400000))
curl -X PUT -H "Authorization: Basic QURNSU46S1lMSU4=" -H 'Content-Type: application/json' -d '{"startTime":'$start_date',"endTime":'$stop_date', "buildType":"BUILD"}' http://192.168.60.15:7070/kylin/api/cubes/$cube_name/build
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
注:我们没有修改 kylin 的时区,因此 kylin 内部只识别 0 时区的时间,0 时区的 0 点是
东 8 区的早上 8 点,因此我们在脚本里要写$do_date 08:00:00 来弥补时差问题。
# 六、BI工具集成
可以与 Kylin 结合使用的可视化工具很多,例如:
ODBC:与 Tableau、Excel、PowerBI 等工具集成
JDBC
:与 Saiku、BIRT 等 Java 工具集成
RestAPI:与 JavaScript、Web 网页集成
Kylin 开发团队还贡献了 Zepplin
的插件,也可以使用 Zepplin 来访问 Kylin 服务。
# JDBC
新建项目并导入依赖
<!-- https://mvnrepository.com/artifact/org.apache.kylin/kylin-jdbc --> <dependency> <groupId>org.apache.kylin</groupId> <artifactId>kylin-jdbc</artifactId> <version>4.0.1</version> </dependency>
1
2
3
4
5
6Java代码
import java.sql.*; /** * @author Jast * @description * @date 2022-03-07 11:22 */ public class KylinTest { 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://192.168.60.15: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(LO_REVENUE) AS SUM1, D_YEAR, P_BRAND FROM LINEORDER JOIN DATES ON LO_ORDERDATE = D_DATEKEY JOIN PART ON LO_PARTKEY = P_PARTKEY JOIN SUPPLIER ON LO_SUPPKEY = S_SUPPKEY WHERE P_CATEGORY = 'MFGR#12' AND S_REGION = 'AMERICA' GROUP BY D_YEAR, P_BRAND ORDER BY D_YEAR, P_BRAND;"); //执行查询 ResultSet resultSet = ps.executeQuery(); //遍历打印 while (resultSet.next()) { System.out.println(resultSet.getString(1) + ":" + resultSet.getDouble (2)); } } }
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
# Zepplin
下载地址:https://zeppelin.apache.org/download.html (opens new window)
# 安装与启动
下载
这个安装包较大,下载的这个版本1.6G
wget https://dlcdn.apache.org/zeppelin/zeppelin-0.10.1/zeppelin-0.10.1-bin-all.tgz --no-check-certificate
1将
zeppelin-0.10.1.tar.gz
上传到Linux服务器解压、重命名
tar -zxvf zeppelin-0.10.1-bin-all.tgz mv zeppelin-0.10.1-bin-all zeppelin
1
2修改启动参数
修改文件
zeppelin-site.xml
mv zeppelin-site.xml.template zeppelin-site.xml
1修改前:
<property> <name>zeppelin.server.addr</name> <value>127.0.0.1</value> <description>Server binding address</description> </property> <property> <name>zeppelin.server.port</name> <value>8080</value> <description>Server port.</description> </property>
1
2
3
4
5
6
7
8
9
10
11修改后
<property> <name>zeppelin.server.addr</name> <value>0.0.0.0</value> <description>Server binding address</description> </property> <property> <name>zeppelin.server.port</name> <value>17890</value> <description>Server port.</description> </property>
1
2
3
4
5
6
7
8
9
10
11启动
functions.sh stop-interpreter.sh zeppelin.sh [root@r-wb-15 zeppelin]# bin/zeppelin-daemon.sh start Please specify HADOOP_CONF_DIR if USE_HADOOP is true Log dir doesn't exist, create /root/zeppelin/logs Pid dir doesn't exist, create /root/zeppelin/run Zeppelin start [ OK ]
1
2
3
4
5
6
# 访问
访问地址http://192.168.60.15:17890/
# 配置Kylin
点击右上角 anonymous 选择 Interpreter
搜索
Kylin
并配置基本信息
# 使用Zepplin查询Kylin
点击
Notebook
->Create new note
填写
Note Name
和Default Interpreter
-
如果上面
Default Interpreter
没有选择默认的为Kylin
,每次输入指定的SQL
需要在前面加上%kylin
-
查询
Kylin