编者按:本文节选自华章科技大数据技术丛书 《Apache Kylin 权威指南(第 2 版)》一书中的部分章节。
安装和启动 Apache Kylin
如果数据已经在 Hive 中准备好,并已经满足 2.2 节介绍的条件,那么就可以开始安装和使用 Apache Kylin 了。本节将介绍 Apache Kylin 的安装环境及启动方法。
环境准备
众所周知,Apache Kylin 依赖于 Hadoop 集群处理大量数据集。因此在安装 Apache Kylin 之前必须准备 Hadoop 环境。由于 Apach Hadoop 版本管理混乱,推荐安装 Cloudera CDH 或 Hortonworks HDP 等商业 Hadoop 发行版。
必要组件
准备好 Hadoop 环境之后,还需要安装一些应用以支持 Apache Kylin 的分析查询,其中必不可少的有 YARN、HDFS、MapReduce、Hive、HBase、Zookeeper 和其他一系列服务以保证 Apache Kylin 的运行稳定可靠。
启动 Apache Kylin
一切准备就绪之后,就能够启动 Apache Kylin 了。首先从 Apache Kylin 下载一个适用 Hadoop 版本的二进制文件,解压相应的二进制文件,并配置环境变量 KYLIN_HOME 指向 Kylin 文件夹。之后运行“$KYLIN_HOME/bin/kylin.sh start”脚本启动 Apache Kylin。
Apache Kylin 启动后,可以通过浏览器“http://:7070/kylin”进行访问。其中,“”为具体的机器名、IP 地址或域名,默认端口为“7070”,初始用户名和密码为“ADMIN/KYLIN”。服务器启动后,您可以通过查看“$KYLIN_HOME/logs/kylin.log”获得运行日志。
设计 Cube
如果数据已经在 Hive 中准备好,并已经满足 2.3 节介绍的条件,那么就可以开始设计和创建 Cube 了,本节将按常规的步骤介绍 Cube 是如何创建的。
导入 Hive 表定义
登录 Apache Kylin 的 Web 界面,创建新的或选择一个已有项目后,需要做的就是将 Hive 表的定义导入 Apache Kylin。
点击 Web 界面的“Model”→“Data source”下的“Load Hive Table Metadata”图标,然后输入表的名称(可以一次导入多张表,以逗号分隔表名)(如图 1 所示),点击按钮“Sync”,Apache Kylin 就会使用 Hive 的 API 从 Hive 中获取表的属性信息。
图 1 输入 Hive 表名
导入成功后,表的结构信息会以树状形式显示在页面的左侧,可以点击展开或收缩,如图 2 所示。
图 2 完成导入的 Hive 表
同时,Apache Kylin 会在后台触发一个 MapReduce 任务,计算此表每个列的基数。通常稍过几分钟后刷新页面,就会看到基数信息显示出来,如图 3 所示。
图 3 计算得到的各列基数
需要注意的是,这里 Apache Kylin 对基数的计算采用的是 HyperLogLog 的近似算法,与精确值略有误差,但作为参考值已经足够。
创建数据模型
有了表信息后,就可以开始创建数据模型了。数据模型(Data Model)是 Cube 的基础,主要根据分析需求进行设计。有了数据模型以后,定义 Cube 的时候就可以直接从此模型定义的表和列中进行选择了,省去了重复指定连接(JOIN)条件的步骤。基于一个数据模型可以创建多个 Cube,方便减少用户的重复性工作。
在 Apache Kylin 界面的“Model”页面,点击“New”→“New Model”命令,开始创建数据模型。给模型输入名称后,选择一个事实表(必需的),然后添加维度表(可选),如图 4 所示。
图 4 添加事实表
添加维度表的时候,首先选择表之间的连接关系,同时选择表之间的连接类型:是 inner jion 还是 left jion,并为创建的维度表输入别名。同时可以选择是否将其以快照(Snapshot)形式存储到内存中以供查询。当维度表小于 300MB 时,推荐启用维度表以快照形式存储,以简化 Cube 计算和提高系统整体效率。当维度表超过 300MB 上限时,则建议关闭维度表快照,以提升 Cube 构建的稳定性与查询的性能。然后选择连接的主键和外键,这里也支持多主键,如图 5 所示。
图 5 添加维度表
接下来选择用作维度和度量的列。这里只是选择一个范围,不代表这些列将来一定要用作 Cube 的维度或度量,你可以把所有可能会用到的列都选进来,后续创建 Cube 的时候,将只能从这些列中进行选择。
选择维度列时,维度可以来自事实表或维度表,如图 6 所示。
图 6 选择维度列
选择度量列时,度量只能来自事实表或不加载进内存的维度表,如图 7 所示。
图 7 选择度量列
最后一步,是为模型补充分割时间列信息和过滤条件。如果此模型中的事实表记录是按时间增长的,那么可以指定一个日期/时间列作为模型的分割时间列,从而可以让 Cube 按此列做增量构建,关于增量构建的具体内容参见第 4 章。
过滤(Filter)条件是指,如果想把一些记录忽略掉,那么这里可以设置一个过滤条件。Apache Kylin 在向 Hive 请求源数据的时候,会带上此过滤条件。如图 8 所示,会只保留金额(price)大于 0 的记录。
图 8 选择分区列和设定过滤条件
最后,点击“Save”保存此数据模型,随后它将出现在“Model”的列表中。
创建 Cube
本节简单介绍了创建 Cube 时的各种配置选项,但是由于篇幅限制,这里没有对 Cube 的配置和优化进行进一步展开介绍。读者可以在后续的章节(如第 3 章“Cube 优化”)中找到关于 Cube 的配置和优化的更详细的介绍。接下来开始 Cube 的创建。点击“New”→“New Cube”命令会开启一个包含若干步骤的向导。
第一步,选择要使用的数据模型,并为此 Cube 输入一个唯一的名称(必需的)和描述(可选)(如图 9 所示);这里还可以输入一个邮件通知列表,以在构建完成或出错时收到通知。如果不想接收在某些状态的通知,可以从“Notification Events”中将其去掉。
图 9 设置 Cube 基本信息
第二步,添加 Cube 的维度。点击“Add Dimension”按钮添加维度,Apache Kylin 会用一个树状结构呈现出所有列,用户只需勾选想要的列即可,同时需要为每个维度输入名字,可以设定是普通维度或是衍生(Derived)维度(如图 10 所示)。如果被设定为衍生维度的话,由于这些列值都可以从该维度表的主键值中衍生出来,所以实际上只有主键列会被 Cube 加入计算。而在 Apache Kylin 的具体实现中,往往采用事实表上的外键替代主键进行计算和存储。但是逻辑上可以认为衍生列来自维度表的主键。
第三步,创建度量。Apache Kylin 支持的度量有 SUM、MIN、MAX、COUNT、COUNT_DISTINCT、TOP_N、EXTENDED_COLUMN、PERCENTILE 等。默认 Apache Kylin 会创建一个 Count(1)度量。
图 10 添加 Cube 的维度
可以通过点击“Bulk Add Measure”按钮批量添加度量。目前对于批量添加度量,Apache Kylin 只支持 SUM、MIN、MAX 等简单函数。只需要选择度量类型,然后再选择需要计算的列,如图 11 所示。
图 11 批量添加度量
如果需要添加复杂度量,可以点击“+Measure”按钮来添加新的度量。请选择需要的度量类型,然后再选择适当的参数(通常为列名)。图 12 所示为一个 SUM(price)的示例。
重复以上操作,创建所需要的度量。Apache Kylin 可以支持在一个 Cube 中有上百个的度量,添加完所有度量后,点击“Next”按钮,如图 13 所示。
图 12 添加度量
图 13 度量列表
第四步,进行关于 Cube 数据刷新的设置(如图 14 所示)。在这里可以设置自动合并的阈值、自动合并触发时保留的阈值、数据保留的最小时间,以及第一个 Segment 的起点时间(如果 Cube 有分割时间列),详细内容请参考第 4 章。
第五步,高级设置。在此页面可以设置维度聚合组和 Rowkey 属性。
默认 Apache Kylin 会把所有维度放在同一个聚合组(Aggregation Group,也称维度组)中,如果维度数较多(如>15),建议用户根据查询的习惯和模式,点击“New Aggregation Group+”命令,将维度分布到多个聚合组中。通过使用多个聚合组,可以大大降低 Cube 中的 Cuboid 数量。
图 14 进行刷新设置
举例说明,一个 Cube 有(M+N)个维度,如果把这些维度都放置在一个组里,那么默认会有 2(M+N)个 Cuboid;如果把这些维度分为两个不相交的聚合组,第一个组有 M 个维度,第二个组有 N 个维度,那么 Cuboid 的总数量将被减至 2M + 2N,比之前的 2(M+N)极大地减少了。
在单个聚合组中,可以对维度设置一些高级属性,如 Mandatory Dimensions、Hierarchy Dimensions、Joint Dimensions 等。这几种属性都是为优化 Cube 的计算而设计的,了解这些属性的含义对于更好地使用 Cube 至关重要。
强制维度(Mandatory Dimensions):指的是那些总是会出现在 Where 条件或 Group By 语句里的维度。通过指定某个维度为强制维度,Apache Kylin 可以不预计算那些不包含此维度的 Cuboid,从而减少计算量。
层级维度(Hierarchy Dimensions):是指一组有层级关系的维度,如“国家”“省”“市”,这里“国家”是高级别的维度,“省”“市”依次是低级别的维度。用户会按高级别维度进行查询,也会按低级别维度进行查询,但当查询低级别维度时,往往会带上高级别维度的条件,而不会孤立地审视低维度的数据。例如,用户会点击“国家”作为维度来查询汇总数据,也可能点击“国家”+“省”,或者“国家”+“省”+“市”来进行查询,但是不会跨越“国家”直接点击“省”或“市”来进行查询。通过指定层级维度,Apache Kylin 可以略过不满足此模式的 Cuboid。
联合维度(Joint Dimensions):是将多个维度视作一个维度,在进行组合计算的时候,它们要么一起出现,要么均不出现,通常适用于以下几种情形:
总是一起查询的维度;
彼此之间有一定映射关系,如 USER_ID 和 EMAIL;
基数很低的维度,如性别、布尔类型的属性。
如图 15 所示,先通过在“Includes”中选择要添加的维度到本聚合组中,然后根据模型特征和查询模式,设置高级维度属性。“Hierarchy Dimensions”和“Joint Dimensions”可以设置多组,但要注意,一个维度出现在某个属性中后,将不能再设置另一种属性。但是一个维度,可以出现在多个聚合组中。
图 15 高级设置
在 Apache Kylin 中是以 Key-Value 的形式将 Cube 的构建结果存储到 Apache HBase 中的。我们知道,HBase 是一种单索引、支持超宽表的数据存储引擎。HBase 的 Rowkey,即行键是用来检索其他列的唯一索引。Apache Kylin 需要按照多个维度来对度量进行检索,因此在存储到 HBase 的时候,需要将多个维度值进行拼接组成 Rowkey。图 16 中介绍了 Apache Kylin 将 Cube 存储在 HBase 中的原理。
图 16 Cube 存储到 HBase
由于同一维度中的数值长短不一,如国家名,短的如“中国”,长的如“巴布亚新几内亚”,因此将多个不同列的值进行拼接的时候,要么添加分隔符,要么通过某种编码使各个列所占的宽度固定。Apache Kylin 为了能够在 HBase 上高效地进行存储和检索,会使用第二种方式对维度值进行编码。维度编码的优势如下:
压缩信息存储空间;
提高扫描效率,减少解析开销。
编码(Encoding)代表了该维度的值使用何种方式进行编码,默认采用字典(Dictionary)编码技术。而合适的编码能够减少维度对空间的占用。例如,我们可以把所有的日期用三个字节进行编码,相比于使用字符串,或者使用长整数形式进行存储,我们的编码方式能够大大减少每行 Cube 数据的体积。而 Cube 中可能存在数以亿计的行,累加起来使用编码节约的空间将是非常庞大的。
目前 Apache Kylin 支持的编码方式有以下几种。
Dictionary 编码:字典编码是将所有此维度下的值构建成一张映射表,从而大大节约存储空间。另外,字典是保持顺序的,这样可以使得在 HBase 中进行比较查询的时候,依然使用编码后的值,而无须解码。Dictionary 的优势是,产生的编码非常紧凑,尤其在维度的值基数小且长度大的情况下,Dictionary 编码特别节约空间。由于产生的字典在使用时加载进构建引擎和查询引擎,所以在维度的基数大、长度也大的情况下,容易造成构建引擎或者查询引擎的内存溢出。在 Apache Kylin 中,字典编码允许的基数上限默认是 500 万(由其参数“kylin.dictionary.max.cardinality”配置)。
Date 编码:将日期类型的数据使用三个字节进行编码,支持从 0000-01-01 到 9999-01-01 中的每一个日期。
Time 编码:仅支持表示从 1970-01-01 00:00:00 到 2038-01-19 03:14:07 的时间,且 Timestamp 类型的维度经过编码和反编码之后,会失去毫秒信息,所以说 Time 编码仅仅支持到秒。但是 Time 编码的优势是每个维度仅使用四个字节,相比普通的长整数编码节约了一半空间。如果能够接受秒级的时间精度,可以选择 Time 来编码代表时间的维度。
Integer 编码:Integer 编码适合于对 int 或 bigint 类型的值进行编码,它无须额外存储,同时可以支持很大的基数。使用时需要提供一个额外的参数“Length”来代表需要多少个字节。“Length”的长度为 1~8。如果用来编码 int32 类型的整数,可以将“Length”设为“4”;如果用来编 int64 类型的整数,可以将“Length”设为“8”。在多数情况下,如果我们知道一个整数类型维度的可能值都很小,那么就能使用“Length”为“2”甚至是“1”的 int 编码来存储,这能够有效避免存储空间的浪费。
Fixed_length 编码:该编码需要提供一个额外的参数“Length”来代表需要多少个字节。对于基数大、长度也大的维度来说,使用 Dict 可能不能正常执行,于是可以采用一段固定长度的字节来存储代表维度值的字节数组,该数组为字符串形式的维度值的 UTF-8 字节。如果维度值的长度大于预设的 Length,那么超出的部分将会被截断。此编码方式其实只是将原始值截断或补齐成相同长度的一组字节,没有额外的转换,所以空间效率较差,通常只是一种权宜手段。
在未来,Apache Kylin 还有可能为特定场景、特定类型的维度量身定制特别的编码方式,如在很多行业,身份证号码可能是一个重要的维度。但是身份证号码由于其特殊性而不能使用整数类型的编码(身份证号码的最后一位可能是 X),其高基数的特点也决定了其不能使用 Dict 编码,在目前的版本中只能使用 Fixed_length 编码,但显然 Fixed_length 不能充分利用身份证号码中大部分字节是数字的特性来进行深度编码,因此存在一定程度的存储空间的浪费。
同时,各个维度在 Rowkey 中的顺序,也会对查询的性能产生较明显的影响。在这里用户可以根据查询的模式和习惯,通过拖曳的方式调整各个维度在 Rowkey 上的顺序(如图 17 所示)。一般原则是,将过滤频率高的列放置在过滤频率低的列之前,将基数高的列放置在基数低的列之前。这样做的好处是,充分利用过滤条件来缩小在 HBase 中扫描的范围,从而提高查询的效率。
图 17 Rowkey 设置
在构建 Cube 时,可以通过维度组合白名单(Mandatory Cuboids)确保想要构建的 Cuboid 能被成功构建(如图 18 所示)。
图 18 指定维度组合白名单
Apache Kylin 支持对于复杂的 COUNT DISTINCT 度量进行字典构建,以保证查询性能。目前提供两种字典格式,即 Global Dictionary 和 Segment Dictionary(如图 19 所示)。
图 19 添加高级字典
其中,Global Dictionary 可以将一个非 integer 的值转成 integer 值,以便 bitmap 进行去重,如果你要计算 COUNT DISTINCT 的列本身已经是 integer 类型,那就不需要定义 Global Dictionary。并且 Global Dictionary 会被所有 segment 共享,因此支持跨 segments 做上卷去重操作。
而 Segment Dictionary 虽然也是用于精确计算 COUNT DISTINCT 的字典,但与 Global Dictionary 不同的是,它是基于一个 segment 的值构建的,因此不支持跨 segments 的汇总计算。如果你的 cube 不是分区的或者能保证你的所有 SQL 按照 partition column 进行 group by, 那么最好使用 Segment Dictionary 而不是 Global Dictionary,这样可以避免单个字典过大的问题。
Apache Kylin 目前提供的 Cube 构建引擎有两种:MapReduce 和 Spark(如图 20 所示)。如果你的 Cube 只有简单度量(如 SUM、 MIN、MAX),建议使用 Spark。如果 Cube 中有复杂类型度量(如 COUNT DISTINCT、 TOP_N),建议使用 MapReduce。
图 20 构建引擎设置
为了提升构建性能,你可以在 Advanced Snapshot Table 中将维表设置为全局维表,同时提供不同的存储类型(如图 21 所示)。
在构建时 Apache Kylin 允许在 Advanced Column Family 中对度量进行分组(如图 22 所示)。如果有超过一个的 COUNT DISTINCT 或 Top_N 度量, 你可以将它们放在更多列簇中,以优化与 HBase 的 I/O。
图 21 全局维表设置
图 22 度量分组设置
第五步,为 Cube 配置参数。和其他 Hadoop 工具一样,Apache Kylin 使用了很多配置参数,用户可以根据具体的环境、场景等配置不同的参数进行灵活调优。Apache Kylin 全局的参数值可以在 conf/kylin.properties 文件中进行配置;如果 Cube 需要覆盖全局设置的话,需在此页面指定。点击“+Property”按钮,然后输入参数名和参数值,如图 23 所示,指定“kylin.hbase.region.cut”的值为“1”,这样,此 Cube 在存储的时候,Apache Kylin 将会按每个 HTable Region 存储空间为 1GB 来创建 HTable Region。如果用户希望任务从 YARN 中获取更多内存,可以设置 kylin.engine.mr.config-override.mapreduce.map.memory.mb、kylin.engine.mr.config-override.mapreduce.map.java.opts 等 mapreduce 相关参数。如果用户希望 Cube 的构建任务使用不同的 YARN 资源队列,可以设置 kylin.engine.mr.config-override.mapreduce.job.queuename。这些配置均可以在 Cube 级别重写。
图 23 覆盖默认参数
然后点击“Next”按钮到最后一个确认页面,如有修改,点“Prev”按钮返回进行修改,最后点“Save”按钮进行保存,一个 Cube 就创建完成了。创建好的 Cube 会显示在“Cubes”列表中,如要对 Cube 的定义进行修改,只需点“Edit”按钮就可以修改。也可以展开此 Cube 行以查看更多信息,如 JSON 格式的元数据、访问权限、通知列表等。
图书简介:https://item.jd.com/12566389.html
相关阅读:
评论