Apache Kylin从入门到精通

Kylin

文章目录

  • Kylin
    • 一、概述
      • 1.1 Kylin定义
      • 1.2 Kylin架构
      • 1.3 Kylin特点
      • 1.4 Apache Kylin4 概述
        • 为什么选择 Parquet 替换 HBase?
        • 预计算结果在 Kylin4.0 中如何存储?
        • Kylin 4.0 的构建引擎
        • Kylin 4.0 的查询引擎
        • Kylin 4.0 与 Kylin 3.1 功能对比
        • Kylin 4.0 性能表现
        • 如何升级
        • Kylin 4.0 查询和构建调优
        • Kylin 4.0 用户案例
    • 二、Kylin环境搭建(4.x)
      • 软件要求
      • 硬件要求
      • Hadoop 环境
      • Kylin 安装
      • 提前准备
      • Web页面介绍
        • 支持的浏览器
        • 登录系统
        • 创建工程
        • 选择数据源
        • 创建Model
        • 创建Cube
        • Cube构建与监控
        • WEB UI查询SQL
    • 三、SSB数据实际测试
        • 生成SBB基准测试数据
        • Mysql查询、Hive查询、Kylin查询对比
    • 四、Kylin使用注意事项
        • 只能按照构建Model的连接条件写SQL查询
        • 只能按照构建 Cube 时选择的维度字段分组统计
        • 只能统计构建Cube 时选择的度量值字段
    • 五、Kylin每日自动构建Cube
    • 六、BI工具集成
      • JDBC
      • Zepplin
        • 安装与启动
        • 访问
        • 配置Kylin
        • 使用Zepplin查询Kylin

一、概述

1.1 Kylin定义

​ Apache Kylin™是一个开源的、分布式的分析型数据仓库,提供Hadoop/Spark 之上的 SQL 查询接口及多维分析(OLAP)能力以支持超大规模数据,最初由 eBay 开发并贡献至开源社区。它能在亚秒内查询巨大的表。

1.2 Kylin架构

在这里插入图片描述

  1. REST Service

    ​ REST Server 是一套面向应用程序开发的入口点,旨在实现针对 Kylin 平台的应用开发

    工作。 此类应用程序可以提供查询、获取结果、触发 cube 构建任务、获取元数据以及获取

    用户权限等等。另外可以通过 Restful 接口实现 SQL 查询。

  2. 查询引擎(Query Engine)

    ​ 当 cube 准备就绪后,查询引擎就能够获取并解析用户查询。它随后会与系统中的其它

    组件进行交互,从而向用户返回对应的结果。

  3. 路由器(Routing)

    ​ 在最初设计时曾考虑过将 Kylin 不能执行的查询引导去 Hive 中继续执行,但在实践后

    发现 Hive 与 Kylin 的速度差异过大,导致用户无法对查询的速度有一致的期望,很可能大

    多数查询几秒内就返回结果了,而有些查询则要等几分钟到几十分钟,因此体验非常糟糕。

    最后这个路由功能在发行版中默认关闭。

  4. 元数据管理工具(Metadata)

    ​ Kylin 是一款元数据驱动型应用程序。元数据管理工具是一大关键性组件,用于对保存

    在 Kylin 当中的所有元数据进行管理,其中包括最为重要的 cube 元数据。其它全部组件的

    正常运作都需以元数据管理工具为基础。 Kylin 的元数据存储在 hbase (3.x版本)中。

  5. 任务引擎(Cube Build Engine)

    ​ 这套引擎的设计目的在于处理所有离线任务,其中包括 shell 脚本、Java API 以及 Map

    Reduce 任务等等。任务引擎对 Kylin 当中的全部任务加以管理与协调,从而确保每一项任务

    都能得到切实执行并解决其间出现的故障。

1.3 Kylin特点

​ Kylin 的主要特点包括支持 SQL 接口、支持超大规模数据集、亚秒级响应、可伸缩性、

高吞吐率、BI 工具集成等。

  1. 标准 SQL 接口:Kylin 是以标准的 SQL 作为对外服务的接口。

  2. 支持超大数据集:Kylin 对于大数据的支撑能力可能是目前所有技术中最为领先的。

    早在 2015 年 eBay 的生产环境中就能支持百亿记录的秒级查询,之后在移动的应用场景中

    又有了千亿记录秒级查询的案例。

  3. 亚秒级响应:Kylin 拥有优异的查询相应速度,这点得益于预计算,很多复杂的计算,

    比如连接、聚合,在离线的预计算过程中就已经完成,这大大降低了查询时刻所需的计算量,

    提高了响应速度。

  4. 可伸缩性和高吞吐率:单节点 Kylin 可实现每秒 70 个查询,还可以搭建 Kylin 的集

    群。

  5. BI 工具集成:

    Kylin 可以与现有的 BI 工具集成,具体包括如下内容。

    ODBC:与 Tableau、Excel、PowerBI 等工具集成

    JDBC:与 Saiku、BIRT 等 Java 工具集成

    RestAPI:与 JavaScript、Web 网页集成

    Kylin 开发团队还贡献了 Zepplin 的插件,也可以使用 Zepplin 来访问 Kylin 服务。

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 之上面向列族的数据库,查询表现已经算是比较优秀,但是它仍然存在以下几个缺点:

  1. HBase 不是真正的列式存储;

    HBase表数据模型比较特别,也可以简单理解为有行和列的二维表,只是它的列称为“列族”,列族下面又可以在数据写入时指定很多的子列。另外,HBase物理存储上是将整个列族数据存储在一起的。所以,如果HBase中的一张表只有一个列族的话,等于是这个列族包含了这张表的所有列,也就是将表正行的数据连续存储在了一起,就等于是行式存储了。再比如,一张表有多个列族,并且每个列族下仅有一列(虽然HBase不建议这么做),也就是将表的列数据连续存储在了一起,就等于是列式存储了。

  2. HBase 没有二级索引,Rowkey 是它唯一的索引;

  3. HBase 没有对存储的数据进行编码,kylin 必须自己进行对数据编码的过程;

  4. HBase 不适合云上部署和自动伸缩;

  5. HBase 不同版本之间的 API 版本不同,存在兼容性问题(比如,0.98,1.0,1.1,2.0);

  6. HBase 存在不同的供应商版本,他们之间有兼容性问题。

针对以上问题,社区提出了对使用 Apache Parquet + Spark 来代替 HBase 的提议,理由如下:

  1. Parquet 是一种开源并且已经成熟稳定的列式存储格式;
  2. Parquet 对云更加友好,可以兼容各种文件系统,包括 HDFS、S3、Azure Blob store、Ali OSS 等
  3. Parquet 可以很好地与 Hadoop、Hive、Spark、Impala 等集成;
  4. 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
- …

可以看出,与 HBase 相比,采用 Parquet 存储可以很方便地增删 cuboid 而不影响其他数据。利用这种特点,Kylin4 中实现了支持用户手动增删 cuboid 的功能,请参考:How to update cuboid list for a cube

Kylin 4.0 的构建引擎

在 Kylin4 中,Spark Engine 是唯一的构建引擎,与之前版本中的构建引擎相比,存在如下特点:

  1. Kylin4 的构建简化了很多步骤。比如在 Cube Build Job 中, kylin4 只需要资源探测和 cubing 两个步骤,就可以完成构建;
  2. 由于 Parquet 会对存储的数据进行编码,所以在 kylin4 中不再需要维度字典和对维度列编码的过程;
  3. Kylin4 对全局字典做了全新的实现,更多细节请参考:Kylin4 全局字典 ;
  4. Kylin4 会根据集群资源、构建任务情况等对 Spark 进行自动调参;
  5. 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-contexttrue,此时 Sparder 会随 Kylin 一起启动。

Kylin 4.0 与 Kylin 3.1 功能对比

FeatureKylin 3.1.0Kylin 4.0
StorageHBaseParquet
BuildEngineMapReduce/Spark/FlinkNew Spark Engine
MetastoreHBase(Default)/MysqlMysql(Default)
DataSourceKafka/Hive/JDBCHive/CSV
Global DictionaryTwo implementationNew implementation
Cube Optimization ToolCube PlannerCube Planner phase1 and Optimize cube manually
Self-monitoringSystem cube and DashboardSystem cube and Dashboard
PushDown EngineHive/JDBCSpark SQL
Hadoop platformHDP2/HDP3/CDH5/CDH6/EMR5HDP2/CDH5/CDH6/EMR5/EMR6/HDI
Deployment modeSingle node/Cluster/Read and write separationSingle 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

Kylin 4.0 查询和构建调优

对于 Kylin4 的调优,请参考:How to improve cube building and query performance

Kylin 4.0 用户案例

Why did Youzan choose Kylin4

参考链接:
Kylin Improvement Proposal 1: Parquet Storage

二、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,且要保证其有至少 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.xmlhive-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 使其生效。

在我们需要安装的服务器执行以下操作:

  1. 从 Apache Kylin下载网站 下载一个 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
    
  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`
    
  3. 使用脚本下载spark

    $KYLIN_HOME/bin/download-spark.sh
    

    download-spark.sh 脚本只能下载 spark2.4.7, 如果您使用的 kylin 二进制包以 spark3 为后缀,您需要从Spark 官方网站下载 spark3.1.1 的二进制包。

    建议将 spark 二进制包解压后放置在 ${KYLIN_HOME} 目录下,并重命名为 spark,以避免兼容性问题。详情请查看:Refactor hive and hadoop dependency

    如果您自定义配置了 ${SPARK_HOME} 指向环境中的 spark2.4.7/spark3.1.1,请保证环境中的 spark 是可以正常提交以及执行任务的。

  4. 配置 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
    

    你需要修改其中的 Mysql 用户名和密码,以及存储元数据的 database 和 table。并将 mysql jdbc connector mysql-connector-java-5.1.49.jar放在 $KYLIN_HOME/ext 目录下,没有该目录时请自行创建。
    请参考 配置 Mysql 为 Metastore 了解 Mysql 作为 Metastore 的详细配置。

  5. 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
  6. 检查运行环境

    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.
    
  7. 启动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 infowill 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
    

    启动成功可以访问页面:http://r-wb-15:7070/kylin

    默认账号密码(注意大小写区分):ADMIN/KYLIN

    访问页面提示以下页面,说明启动成功。

    在这里插入图片描述

  8. Kylin目录结构·

    • bin: shell 脚本,用于启动/停止 Kylin,备份/恢复 Kylin 元数据,以及一些检查端口、获取 Hive/HBase 依赖的方法等;
    • conf: Hadoop 任务的 XML 配置文件,这些文件的作用可参考配置页面
    • lib: 供外面应用使用的 jar 文件,例如 Hadoop 任务 jar.
    • meta_backups: 执行 bin/metastore.sh backup 后的默认的备份目录;
    • sample_cube 用于创建样例 Cube 和表的文件。
    • spark: 使用kylin脚本下载得到的 spark。
    • tomcat: 自带的 tomcat,用于启动 Kylin 服务。
    • tool: 用于执行一些命令行的jar文件。
  9. 使用 Kylin

    Kylin 启动后您可以通过浏览器 http://<hostname>:7070/kylin 进行访问。
    其中 <hostname> 为具体的机器名、IP 地址或域名,默认端口为 7070。
    初始用户名和密码是 ADMIN/KYLIN
    服务器启动后,您可以通过查看 $KYLIN_HOME/logs/kylin.log 获得运行时日志。

  10. 停止 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.
    

    您可以运行 ps -ef | grep kylin 来查看 Kylin 进程是否已停止。

  11. 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');
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');
  • 从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
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

Web页面介绍

支持的浏览器

Windows: Google Chrome, FireFox

Mac: Google Chrome, FireFox, Safari

登录系统

在这里插入图片描述

创建工程

  1. 点击加号

在这里插入图片描述

  1. 输入项目名称、项目描述,点击Submit提交

在这里插入图片描述

  1. 创建成功

在这里插入图片描述

选择数据源

​ 虽然 Kylin 使用 SQL 作为查询接口并利用 Hive 元数据,Kylin 不会让用户查询所有的 hive 表,因为到目前为止它是一个预构建 OLAP(MOLAP) 系统。为了使表在 Kylin 中可用,使用 “Sync” 方法能够方便地从 Hive 中同步表。

  1. 选择加载数据源方式

在这里插入图片描述

  1. 选择需要加载的表,点击Sync

在这里插入图片描述

  1. 查看同步的数据源

在这里插入图片描述

创建Model

​ 创建 cube 前,需定义一个数据模型。数据模型定义了一个星型(star schema)或雪花(snowflake schema)模型。一个模型可以被多个 cube 使用。

  1. 点击顶部的 Model ,然后点击 Models 标签。点击 +New 按钮,在下拉框中选择 New Model

在这里插入图片描述

  1. 输入 model 的名字和可选的描述,点击Next

在这里插入图片描述

  1. Fact Table 中,为模型选择事实表。

在这里插入图片描述

  1. 【可选】点击 Add Lookup Table 按钮添加一个 lookup 表。选择表名和关联类型(内连接或左连接)

    1

在这里插入图片描述

  1. 点击 New Join Condition 按钮,左边选择事实表的外键,右边选择 lookup 表的主键。如果有多于一个 join 列重复执行。

在这里插入图片描述

在这里插入图片描述

  1. 点击 “OK”,重复2,3步来添加更多的 lookup 表。完成后,点击 “Next”。

在这里插入图片描述

在这里插入图片描述

  1. Dimensions 页面允许选择在子 cube 中用作维度的列(统计分析温度字段),然后点击 Columns 列,在下拉框中选择需要的列。
    在这里插入图片描述

  2. 点击 “Next” 到达 “Measures” 页面,选择作为 measure 的列,其只能从事实表中选择。

这里我没有选择,我只想统计数量,没有求和等其他操作

在这里插入图片描述

  1. 点击 “Next” 到达 “Settings” 页面,如果事实表中的数据每日增长,选择 Partition Date Column 中相应的 日期列以及日期格式,否则就将其留白。

  2. 【可选】选择是否需要 “time of the day” 列,默认情况下为 No。如果选择 Yes, 选择 Partition Time Column 中相应的 time 列以及 time 格式

在这里插入图片描述

  1. 【可选】如果在从 hive 抽取数据时候想做一些筛选,可以在 Filter 中输入筛选条件。

在这里插入图片描述

  1. 点击 Save 然后选择 Yes 来保存 data model。创建完成,data model 就会列在左边 Models 列表中。

在这里插入图片描述

  1. 创建完成可以看到Models

在这里插入图片描述

创建Cube

创建完 data model,可以开始创建 cube。

  1. 点击顶部 Model,然后点击 Models 标签。点击 +New 按钮,在下拉框中选择 New Cube

在这里插入图片描述

  1. 填写Cube 信息,选择 data model,输入 cube 名字;点击 Next 进行下一步

    cube 名字可以使用字母,数字和下划线(空格不允许)。Notification Email List 是运用来通知job执行成功或失败情况的邮箱列表。Notification Events 是触发事件的状态。

在这里插入图片描述

  1. 添加维度

    1.添加真正的维度字段(将来会影响 Cuboid 的个数,并且只能从 model 维度字段里面选择)

    2.后续统计条件字段只能从维度设置字段进行查询

    点击Add Dimension

在这里插入图片描述

在弹窗中显示的事实表和 lookup 表里勾选输入需要的列。Lookup 表的列有2个选项:“Normal” 和 “Derived”(默认)。“Normal” 添加一个普通独立的维度列,“Derived” 添加一个 derived 维度,derived 维度不会计算入 cube,将由事实表的外键推算出。(推荐使用Normal

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  1. 添加度量

    点击 +Measure 按钮添加一个新的度量。

在这里插入图片描述

根据它的表达式共有7种不同类型的度量:SUMMAXMINCOUNTCOUNT_DISTINCT TOP_NPERCENTILE。请合理选择 COUNT_DISTINCTTOP_N 返回类型,它与 cube 的大小相关。

在这里插入图片描述

这里度量值默认有一个count(*),其他的可自行选择。注意:这里的度量值只能从创建模型选择的字段中进行选择。

  1. 更新配置

    这一步骤是为增量构建 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 的开始日期.

在这里插入图片描述

  1. 高级设置

    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 会被跳过计算。

    关于更多维度优化,请阅读这个博客: 新的聚合组

    Rowkeys: 是由维度编码值组成。

    你可以拖拽维度列去调整其在 rowkey 中位置; 位于rowkey前面的列,将可以用来大幅缩小查询的范围。通常建议将 mandantory 维度放在开头, 然后是在过滤 ( where 条件)中起到很大作用的维度;如果多个列都会被用于过滤,将高基数的维度(如 user_id)放在低基数的维度(如 age)的前面。

    此外,你还可以在这里指定使用某一列作为 shardBy 列,kylin4.0 会根据 shardBy 列对存储文件进行分片,分片能够使查询引擎跳过不必要的文件,提高查询性能,最好选择高基列并且会在多个 cuboid 中出现的列作为 shardBy 列。

    Mandatory Cuboids: 维度组合白名单。确保你想要构建的 cuboid 能被构建。

    Cube Engine: cube 构建引擎。Spark构建。

    这里我们使用默认。

  2. 重写配置

    ​ Kylin 允许在 Cube 级别覆盖部分 kylin.properties 中的配置,你可以在这里定义覆盖的属性。如果你没有要配置的,点击 Next 按钮。

在这里插入图片描述

  1. 概览 & 保存

    你可以概览你的 cube 并返回之前的步骤进行修改。点击 Save 按钮完成 cube 创建。

在这里插入图片描述

  1. 可以返回查看Cube信息

在这里插入图片描述
在这里插入图片描述

Cube构建与监控

  1. Models 页面中,点击 cube 栏右侧的 Action 下拉按钮并选择 Build 操作。

在这里插入图片描述

  1. 选择后会出现一个弹出窗口,点击 Start Date 或者 End Date 输入框选择这个增量 cube 构建的起始日期。

    上面如果没有选择分区表的话,这里不会提示选择日期

在这里插入图片描述

  1. 点击 Submit 提交请求。成功之后,你将会在 Monitor 页面看到新建的 job和进度。

    新建的 job 是 “pending” 状态;一会儿,它就会开始运行并且你可以通过刷新 web 页面或者点击刷新按钮来查看进度。

在这里插入图片描述

  1. 等待 job 完成。期间如要放弃这个 job ,点击 Actions -> Discard 按钮。

在这里插入图片描述

  1. 查看Build进度

在这里插入图片描述

在这里插入图片描述

  1. 计算中查看日志,点击Job

在这里插入图片描述

弹出Spark UI新页面,可以看到计算步骤

在这里插入图片描述

  1. 等到 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等组合方式。

下载SSB数据生成工具:http://www.itpub.net/forum.php?mod=attachment&aid=NzA1NTM0fDFiOGIzOWZifDE0NDc0ODQ2MzZ8MHww

环境需要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
    
  2. 查看生成的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>]
    
  3. 生成数据文件

    # 利用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表
    
  4. 创建表结构

    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);
    
  5. 导入数据

    导入之前生成的数据

    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;
    
  6. Hive创建相对应的表

    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');
  7. Sqoop 同步 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 1sqoop 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 1sqoop 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 1sqoop 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 1sqoop 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
    
  8. 标准测试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;
    
  9. 这里我们先用这个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;
    

    Kylin不支持笛卡尔积查询,查询报错如下

    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"
    
  10. Kylin创建Model

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

  1. 创建CUBE

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

一直Next直至完成

  1. build CUBE

在这里插入图片描述

  1. Build 完成

    Build 构建共花了156分钟

在这里插入图片描述

  1. 数据图表展示及导出

在这里插入图片描述

Mysql查询、Hive查询、Kylin查询对比

查询类型耗时
Mysql超时
Kylin1秒以内
Hive74.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=

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

注:我们没有修改 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

  1. 新建项目并导入依赖

    <!-- 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>
    
  2. Java代码

    
    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_URLString 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);//预编译 SQLPreparedStatement 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));}}
    }
    

Zepplin

下载地址:https://zeppelin.apache.org/download.html

安装与启动

  1. 下载

    这个安装包较大,下载的这个版本1.6G

    wget https://dlcdn.apache.org/zeppelin/zeppelin-0.10.1/zeppelin-0.10.1-bin-all.tgz --no-check-certificate
    
  2. zeppelin-0.10.1.tar.gz上传到Linux服务器

  3. 解压、重命名

    tar -zxvf zeppelin-0.10.1-bin-all.tgz
    mv zeppelin-0.10.1-bin-all zeppelin
    
  4. 修改启动参数

    修改文件zeppelin-site.xml

    mv zeppelin-site.xml.template zeppelin-site.xml
    

    修改前:

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

    修改后

    <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>
    
  5. 启动

    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  ]
    

访问

访问地址http://192.168.60.15:17890/

在这里插入图片描述

配置Kylin

  1. 点击右上角 anonymous 选择 Interpreter

    在这里插入图片描述

  2. 搜索Kylin并配置基本信息

    在这里插入图片描述

使用Zepplin查询Kylin

  1. 点击Notebook->Create new note

    在这里插入图片描述

  2. 填写Note NameDefault Interpreter

    在这里插入图片描述

    在这里插入图片描述

    如果上面Default Interpreter没有选择默认的为Kylin,每次输入指定的SQL需要在前面加上%kylin

    在这里插入图片描述

  3. 查询Kylin

    在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/509549.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

排序分析

九大基础排序总结与对比 标签&#xff1a; 数据结构排序算法九大排序2016-06-07 15:43 12646人阅读 评论(6) 收藏 举报分类&#xff1a;data structure版权声明&#xff1a;本文为博主原创文章&#xff0c;未经博主允许不得转载。 目录(?)[] 请尊重个人劳动成果&#xff0c;转…

Flume 实战开发指南

Flume 文章目录FlumeFlume介绍Flume核心概念Flume NG的体系结构SourceChannelSinkFlume的部署类型单一流程多代理流程&#xff08;多个agent顺序连接&#xff09;流的合并&#xff08;多个Agent的数据汇聚到同一个Agent &#xff09;多路复用流&#xff08;多级流&#xff09;l…

Flink Chain任务链分隔

Chain分隔 文章目录Chain分隔如何切断任务链&#xff1f;startNewChain 与 disableChaining区别全局切断任务链(chain)web端效果查看隔离后依赖链忙碌程度什么是Backpressured(被压/反压)&#xff1f;代码样例参考文献如何切断任务链&#xff1f; 由于共享slot的存在&#xff…

KMP 深度讲解next数组的求解

【经典算法】——KMP&#xff0c;深入讲解next数组的求解 前言   之前对kmp算法虽然了解它的原理&#xff0c;即求出P0Pi的最大相同前后缀长度k&#xff1b;但是问题在于如何求出这个最大前后缀长度呢&#xff1f;我觉得网上很多帖子都说的不是很清楚&#xff0c;总感觉没有把…

Yarn 命令详细介绍

文章目录yarn命令根据状态查看Yarn全部运行应用程序根据提交程序代码提交类型查看运行程序yarn top 查看正在运行的状态yarn top整体资源使用查看Yarn web页面工具脚本根据yarn应用名称kill进程根据yarn应用名称查看日志yarn命令 根据状态查看Yarn全部运行应用程序 # 查看全部…

BackPressure详细介绍

BackPressure详细介绍 文章目录BackPressure详细介绍前言什么是反压&#xff1f;为什么需要关注反压&#xff1f;为什么不需要关注反压&#xff1f;如何发现和追踪反压的根源&#xff1f;反压的坏处经常碰到哪些问题会任务反压怎么处理反压&#xff1f;前言 Flink反压已经是老…

给IT新人的15个建议:程序员的辛酸反省与总结!

很多人表面上看着老实巴交的&#xff0c;实际上内心比谁都好强、自负、虚荣、甚至阴险。工作中见的多了&#xff0c;也就习惯了。   有一些人&#xff0c;什么事都写在脸上&#xff0c;表面上经常得罪人&#xff0c;甚至让人讨厌。但是他们所表现的又未必不是真性情。 我相信…

AOE网

博客来源&#xff1a;http://blog.csdn.net/wang379275614/article/details/13990163 认识AOE网 有向图中&#xff0c;用顶点表示活动&#xff0c;用有向边表示活动之间开始的先后顺序&#xff0c;则称这种有向图为AOV网络&#xff1b;AOV网络可以反应任务完成的先后顺序&#…

数据结构前缀,后缀,中缀表达式

[cpp] view plaincopy [cpp] view plaincopy <span style"color: rgb(51, 51, 51); font-family: Arial; font-size: 14px; line-height: 26px; background-color: rgb(255, 255, 255);">举例&#xff1a;</span> (3 4) 5 - 6 就是中缀表达式 - 3…

priority_queueint,vectorint,greaterint优先队列,按照从小到大

原网址&#xff1a; 优先队列 C优先队列的基本使用方法 在优先队列中&#xff0c;优先级高的元素先出队列。 标准库默认使用元素类型的<操作符来确定它们之间的优先级关系。 优先队列的第一种用法&#xff0c;也是最常用的用法&#xff1a; priority_queue<int>qi;通…

Spark stage如何划分

窄依赖和宽依赖 窄依赖&#xff1a; 指父RDD的每一个分区最多被一个子RDD的分区所用&#xff0c;表现为一个父RDD的分区对应于一个子RDD的分区&#xff0c;和两个父RDD的分区对应于一个子RDD 的分区。图中&#xff0c;map/filter和union属于第一类&#xff0c;对输入进行协同…

引出发射和什么是反射和Class类和Class实例、基本类型的字节码对象

引出发射和什么是反射 问题1: 1.对象有编译类型和运行类型Object obj new java.util.Date();编译类型: Object运行类型: java.util.Date需求:通过obj对象,调用java.util.Date类中的toLocaleString方法.obj.toLocaleString(); 此时编译报错, 编译时,会检查该编译类型中是…

获取类中的构造器

需求:通过反射来获取某一个类的构造器: 1):获取该类的字节码对象. 2):从该字节码对象中去找需要获取的构造器. ------------------------------------------------------------------------ Class类获取构造器方法: Constructor类:表示类中构造器的类型,Constructor的实例…

Maxwell读取MySQL数据

文章目录Maxwell 概述1.1 Maxwell 定义1.2 Maxwell工作原理1.2.1 MySQL主从复制过程1.2.2 Maxwell的工作原理1.2.3 **MySQL** **的** binlog1.3 Maxwell和Canal的对比Maxwell使用2.1 Maxwell安装2.1.1 安装地址2.1.2 安装部署2.1.3 MySQL环境准备2.1.4 初始化Maxwell元数据库2.…

Linux-(C/C++)动态链接库生成以及使用(libxxx.so)

Linux中so文件为共享库&#xff0c;与windows下dll类似&#xff0c;不过实现要简单。 so可以供多个进程使用&#xff0c;不同进程调用同一个so文件&#xff0c;所使用so文件不同。 so文件源程序不需要main函数&#xff0c;有也不会被执行。 下面通过一个简单例子&#xff0c;来…

IO之打印流

打印流,打印数据的,打印流只能是输出流: PrintStream: 字节打印流 PrintWriter: 字符打印流 -对于PrintWriter来说,当启用字段刷新之后, 调用println或者printf或者format方法,便会立马刷新操作. 如果没有开启自动刷新,则需要手动刷新或者当缓冲区满的时候,再自动刷新. 使…

IO之 Properties类加载文件

配置文件:资源文件(以.properties作为拓展名的文件)/属性文件: 做项目开发,为何使用配置文件? 把所有的数据存储在代码中,写死了,”硬编码”. 比如:在Java中需要连接数据库,必须拥有数据的账号和密码. 此时我们就得在Java代码中编写,类似的代码: String username”root”…

IO之数据流

数据流,提供了可以读/写任意数据类型的方法: DataOutputStream: 提供了 writeXxx(xxx value)方法. DataInputStream: 提供了 readXxx()方法. 注意: writeXxx和readXxx必须要对应起来, writeByte写出的数据,此时只能使用readByte读取回来.

可视化的状态机(FSM)

状态机这个概念已经在网上的博客和论坛中都已经说烂了&#xff0c;随便一搜都有一大堆。相关的废话就不多说了&#xff0c;在这里主要是分享一下如何可视化的设计状态机&#xff0c;如何增强项目的灵活性。这里通过一个生活中的电梯来了解一下状态机。 电梯逻辑如下图&#xf…

IO之 随机访问文件(RandomAccessFile)

随机访问文件(RandomAccessFile): 表示可以在该文件的任何位置写出和读取数据. API中文解释&#xff1a; 此类的实例支持对随机访问文件的读取和写入。随机访问文件的行为类似存储在文件系统中的一个大型 byte 数组。存在指向该隐含数组的光标或索引&#xff0c;称为文件指针&…