作者杨正

导语

作为 Kylin 的忠实用户,58 集团从最初的 Kylin 1.5.3 到今年上半年实现的 1.5 版本 Cube 到 2.6 版本的迁移工作,已经使用 Kylin 近五年了。但随着业务的快速增长,58 集团面临着 HBase 集群的运维压力和机房无法扩容的负载压力等新的挑战。通过下文中的方案,58 集团现已有效解决了上述问题。让我们跟随 58 集团大数据部的杨正一起来共同学习探讨 Kylin 跨集群维护的最佳实践吧!

01

Kylin 在 58 集团的现状与发展历程

1. 使用现状

58 集团自 16 年开始引进 Kylin,服务于多个业务线与商业数据产品,被广泛应用于流量、用户行为、推荐等分析场景中。目前生产环境部署的是基于社区 2.6.0 修改的内部版本,已有 600 个 Cube,320 T 存储,每日输入数据量 120 亿条,使用的 HBase 表 1 万多张,5 万多 Region,单日最高 25 万次查询,90% 左右的查询响应时间小于 0.5s。




kylin需要hbase吗 hbase和kylin_元数据


2. 发展历程

16 年开始使用 Kylin 1.5.3,19 年初开始使用 Kylin 2.6.0,2020 年上半年完成 1.5 版本 Cube 到 2.6 版本的迁移工作。主要工作如下:

  • 多租户支持优化
  • Kylin 的调度、监控和管理系统
  • 动态用户加载 (KYLIN-4241)
  • 可选择任务构建点 (KYLIN-4249)
  • 节点服务发现 (KYLIN-4256)
  • 增加 http 监控指标接口 (KYLIN-4294)
  • 引入新版 Hive 全局字典新特性
  • 支持跨集群存储查询能力
  • ......

02

Kylin 跨集群项目背景

目前在 58 集团有两个 HBase 集群,分别部署在 A 机房和 B 机房。Kylin 一直使用的是 A 机房的 HBase 集群,但是 A 机房的机架数达到了物理上限,没办法继续扩容。

随着 Kylin 业务的快速增长,HBase 集群以每月 1000 左右张表,5000 左右个 Region 的增速在上涨,A 机房 HBase 集群的运维压力越来越大。

为了应对快速增长的业务需求,我们希望将 Kylin 的部分预计算数据存储到 B 机房的 HBase 集群。如果将 Kylin 的所有预计算数据迁移到 B 机房的 HBase 集群,迁移成本会过高,并且以后可能还会遇到单机房机器增长瓶颈,于是我们开始实现 Kylin 的多 HBase 集群存储与查询的方案。


kylin需要hbase吗 hbase和kylin_列式存储原理_02


03

Kylin 跨集群实现原理

1. 可插拔的架构


kylin需要hbase吗 hbase和kylin_列式存储原理_03


如上图所示,Kylin 使用了可插拔的架构,支持 Hive、Kafka 和 REBMS 等数据源,对外支持 REST、JDBC/ODBC 接口,使用 Hive、MR、Spark 等多种计算引擎计算各个维度组合下的聚合值,最后将预计算的数据存储到 HBase 中( Kylin 4.0 以前默认使用 HBase 作为存储引擎)。

一些基础概念:

  • Cuboid:一种维度组合
  • Cube:数据立方体,即所有维度组合,由所有 Cuboid 组成
  • Segment:一个 Cube 一般根据时间分区划分为多个 Segment

2. 跨集群存储

Segment 构建流程:


kylin需要hbase吗 hbase和kylin_数据_04


Segment 合并流程:


kylin需要hbase吗 hbase和kylin_元数据_05


涉及到与 HBase 连接相关的步骤有:

  • 创建 HBase 表;
  • Cuboids 数据转 HFile 文件(需要获取 HBase 配置);
  • BulkLoad 任务;
  • Lookup 表的存储与查询;
  • Merge 任务垃圾清理时,删除无用的 HTable;
  • 获取 HBase 的 HDFS 存储的地方;

以上步骤都需要获取 HBase 连接,然后再做相应的操作,如创建表、获取 HBase 配置等。再获取 HBase 连接时,会根据系统配置 kylin.storage.url 来创建 Connection,单一的 Connection 显然无法满足跨集群存储的需要。

因此我们修改了这部分逻辑,再获取 HBase Connection 时,我们根据 Cube 的配置来创建 Connection,并放入缓存池中。这样不同的 Cube 即可以使用不同的 HBase 集群来做相应的操作。

配置重写说明:

Kylin 除了 $KYLIN_HOME/conf/ 目录下的全局配置外,同时支持项目级别和 Cube 级别的配置重写。配置重写的优先级关系为:Cube 级别配置重写 > 项目级别配置重写 > 全局配置文件。

将 Segment 所属集群写入元数据:

kylin需要hbase吗 hbase和kylin_kylin需要hbase吗_06


构建 Segment 时,会根据当前 Cube 的 storage url 配置来选择 HBase 集群进行存储,构建结束时,会更新元数据,此时我们将 Segment 所属 HBase 集群写入到 Segment 的元数据信息中,便于展示。查询时也会用到这个元数据信息。

3. 跨集群查询

Kylin 查询流程:

kylin需要hbase吗 hbase和kylin_kylin_07


如上是一个 Kylin 完整的查询流程,红色方框代表 HBase 查询部分。一次查询可能会向 HBase 发送多个 Scan 请求,将从多个 Segment 扫描得到的数据,做进一步的聚合得到结果返回给用户。

我们的跨集群版本,是支持同一个 Cube 不同 Segment 存储在不同的 HBase 集群的。既然 Segment 存储在不同的集群,那么也必须具备一次查询从多个 HBase 集群扫描结果的能力。

kylin需要hbase吗 hbase和kylin_kylin_08


如上图所示,一次查询可能会分为多个 Scan 任务,根据元数据中 Segment 所属集群,向对应的 HBase 表发送 Scan 请求,最后对所有 Scan 的结果做进一步处理。

协处理器适配问题:

Kylin 使用了 HBase 协处理器来优化查询性能。Cube 构建到创建表时,会为表部署协处理器。

初期,我们的两个 HBase 集群版本不一致,分别为 1.0 和 1.4 版本。使用同一个 corprocess jar 包,发现不能同时兼容两个集群。于是我们分别基于 HBase1.0 和 HBase1.4 编译了两个版本的 kylin-corprocess.jar,创建 HBase 表时,选择对应版本的 kylin-corprocess.jar 进行部署。

04

跨集群支持工作

1. 集群负载与跨集群信息可视化

我们在 Kylin 管理平台页面,添加了跨集群信息展示,比如 Kylin 表所在 RsGroup 的负载情况,所有 Segment 的分布情况,所有 Cube 当前使用的存储集群和一些明细信息。Kylin 管理员可以快速了解到 HBase 整体负载情况,和某个 Cube 的 Segment 分布情况等信息。

2. 清理工具升级

Kylin 运行一段时间后,有部分数据会因为不再使用而变成垃圾数据,这些数据会占用 HDFS,HBase,kylin-meta 表的空间,有必要进行清理。跨集群功能上线后,垃圾数据也会存储在多个集群,因此清理工具我们也做了修改,比如遍历找到两个 HBase 集群所有无用的表,再清理。

05

总结与展望

Kylin 跨集群存储与查询的实现,有效的解决了我们因机房无法扩容带来的负载压力。支持同一个 Cube 的多个 Segment 存储到不同的 HBase 集群,同时支持 Cube 级别 / 项目级别和全局配置默认的存储集群,可以根据集群负状态,灵活的进行 HBase 集群的切换,并且完全对用户透明。

使用 HBase 作为 Kylin 的预计算结果存储还有诸多问题,例如不支持二级索引、不是真正的列式存储、无法做到分布式查询等问题,限制了 Kylin 的一些能力。目前 Kylin 4.0 Alpha 版本已经发布,此版本开始使用 Parquet 作为存储,SparkSQL 作为查询和构建引擎,可以极大的提升 Kylin 的性能和稳定性,我们也正在积极的参与到 4.0 的开发中,期待早日落地。

参考文章

作者杨正