
最近因为有业务报表要跑多维分析我接到一个比较折腾的任务在 Hadoop 3.0 HBase 2.0 这套看起来“不是官方推荐组合”的环境上把 Kylin 3.10 完整搭起来并且要能正常建 Cube、跑查询。 折腾几天下来踩了不少坑也把版本冲突、Jar 覆盖、Cube 构建这些关键点都理清了。 这篇就围绕 Kylin 3.10 的部署、Hadoop/HBase 环境适配、第一个 Cube 的完整构建过程来写后续同样准备在 Hadoop 3.x 和 HBase 2.x 上部署 Kylin 的同学可以直接照着走。1. 项目概述与环境选型1.1 Kylin 在技术栈里的定位Kylin 是一个分布式 OLAP 引擎核心思想是“预计算”。 它提前把数据按照多维组合聚合好生成 Cube 存储到 HBase 中查询时直接扫描预计算结果从而做到亚秒级响应。 你可以把它理解成“对查询的缓存”但不是简单的缓存而是针对固定维度和度量的离线聚合结果集。Kylin 在架构上依赖几个东西Hadoop 提供底层 HDFS 存储和 YARN 资源调度Hive 负责管理数据表和 SQL 语义HBase 负责存储构建好的 Cube 和 Kylin 的元数据。 所以搭建 Kylin 之前Hadoop、HBase、Hive 这套底座必须可用。 而我们这次的基础版本是 Hadoop 3.0、HBase 2.0Kylin 包的版本是 3.10。 单看版本Kylin 3.x 更多是配合 Hadoop 2.x 和 HBase 1.x 使用直接拿新版组合主要是兼容性问题。1.2 集群规划与版本确认我这次用的环境是三台物理节点角色分配如下。节点主要角色部署进程kylin-master主节点NameNode、ResourceManager、HMaster、Kylin、Hive Metastore、ZKkylin-slave1从节点DataNode、NodeManager、RegionServer、ZKkylin-slave2从节点DataNode、NodeManager、RegionServer、ZK软件版本如下JDK1.8.0_201Kylin 3.x 必须 JDK 8不要用 11Hadoop3.0.3HBase2.0.2Hive3.0.0用于读取表结构Zookeeper3.4.13Kylin3.10实际安装包可能标注为 apache-kylin-3.10-bin.tar.gz 之类后面按这个版本名说明这里特别提醒Hadoop 3.0 和 HBase 2.0 都不是 Kylin 官方最舒服的版本区间所以在启动 Kylin 之前必须先解决依赖兼容问题不然会遇到各种 ClassNotFound 和 NoSuchMethodError。 这一点后面专门讲。1.3 搭建前的基础准备所有节点先做几项基础配置配置 hosts把三个节点的 IP 和主机名映射写进 /etc/hosts。关闭防火墙和 SELinux避免端口访问异常。配置时间同步大数据组件之间时间不一致会直接导致认证报错。创建统一用户例如 bigdata所有组件都跑在该用户下。配置 SSH 免密登录从 kylin-master 免密到三个节点。JDK 安装过程不多说记得在所有节点设置 JAVA_HOME 并加入 PATH。 另外建议所有软件统一放在 /opt 下目录清晰一些后面覆盖 Jar 的时候也好管理。2. 基础环境安装Hadoop 3.0 HBase 2.02.1 Hadoop 3.0 的安装配置Hadoop 3.0.3 解压到 /opt/hadoop主要修改四个配置文件。core-site.xmlconfiguration property namefs.defaultFS/name valuehdfs://kylin-master:8020/value /property property namehadoop.tmp.dir/name value/data/hadoop/tmp/value /property /configurationhdfs-site.xmlconfiguration property namedfs.replication/name value2/value /property property namedfs.namenode.name.dir/name value/data/hadoop/nn/value /property property namedfs.datanode.data.dir/name value/data/hadoop/dn/value /property property namedfs.namenode.http-address/name valuekylin-master:9870/value /property /configurationyarn-site.xmlconfiguration property nameyarn.nodemanager.aux-services/name valuemapreduce_shuffle/value /property property nameyarn.resourcemanager.hostname/name valuekylin-master/value /property property nameyarn.nodemanager.vmem-check-enabled/name valuefalse/value /property /configuration第三个参数是我习惯性加上的容器物理内存不足时如果 YARN 做虚拟内存校准很容易把 MR 任务杀掉。 大数据组件本来吃内存就厉害关闭这个检查能少踩一个坑。配置完成后在 kylin-master 上执行 hdfs namenode -format然后通过 start-dfs.sh 和 start-yarn.sh 启动集群。 启动后确认 Web UI 可访问NameNode 的默认端口在 Hadoop 3.0 里是 9870ResourceManager 是 8088。 第一次部署最好用 jps 检查进程确认 DataNode 在从节点上正常注册。2.2 HBase 2.0 安装配置HBase 2.0.2 解压到 /opt/hbase修改 hbase-env.sh设置 JAVA_HOME并关闭 HBase 自带的 Zookeeperexport JAVA_HOME/usr/local/jdk1.8.0_201 export HBASE_MANAGES_ZKfalsehbase-site.xml 如下configuration property namehbase.rootdir/name valuehdfs://kylin-master:8020/hbase/value /property property namehbase.cluster.distributed/name valuetrue/value /property property namehbase.zookeeper.quorum/name valuekylin-master,kylin-slave1,kylin-slave2/value /property property namehbase.zookeeper.property.clientPort/name value2181/value /property property namehbase.unsafe.stream.crash.ignore/name valuetrue/value /property /configurationHBase 2.0 的 HMaster 会自己创建 HDFS 上的根目录启动顺序是 Zookeeper - HDFS - HBase。 我习惯用 start-hbase.sh 启动然后执行 hbase shell输入 status看是否返回正常。这里有个经验HBase 2.0 对 Zookeeper 的版本比较敏感我用了 3.4.13如果是 3.5 及以上版本连接会有 SessionExpired 问题建议直接用 3.4.x。2.3 Hive 3.0 与元数据库Kylin 3.10 构建 Cube 的时候需要从 Hive 获取表结构所以 Hive 必须能正常跑起来。 我在 master 上安装 Hive 3.0并使用 MySQL 存储元数据。Hive 的配置点主要是 hive-site.xml需要设置javax.jdo.option.ConnectionURL指向 MySQL 中的 hive 元数据库。hive.metastore.uris设置为 thrift://kylin-master:9083。hive.support.concurrencytrue。hive.zookeeper.quorum指向 Zookeeper 节点。初始化元数据时执行schematool -initSchema -dbType mysql初始化成功后单独启动 metastorenohup hive --service metastore /data/logs/metastore.log 21 Kylin 读取 Hive 表时会通过 metastore 服务如果这个服务没起你在 Kylin Web UI 里看不到任何表而且日志里会报连接拒绝。3. Kylin 3.10 部署与版本兼容处理3.1 解压安装与环境变量把 Kylin 3.10 的二进制包解压到 /opt/kylin然后修改 /etc/profile加入export KYLIN_HOME/opt/kylin export HADOOP_HOME/opt/hadoop export HBASE_HOME/opt/hbase export HIVE_HOME/opt/hive export PATH$PATH:$KYLIN_HOME/bin:$HADOOP_HOME/bin:$HBASE_HOME/bin:$HIVE_HOME/binKylin 的 check-env.sh 脚本会读取 HADOOP_HOME、HBASE_HOME、HIVE_HOME 这些变量如果缺失会直接告诉你环境不完整。 执行$KYLIN_HOME/bin/check-env.sh正常情况会输出 Hadoop 和 HBase 客户端版本信息。 在我这套环境里check-env.sh 能过但后面启动 Kylin 时依然会报错问题出在 Jar 包版本冲突。3.2 替换 Kylin 的 Hadoop 和 HBase 相关 Jar这是整套搭建里最关键的一步。 Kylin 3.10 默认带的是 Hadoop 2.x 和 HBase 1.x 的客户端依赖直接对接 Hadoop 3.0 和 HBase 2.0会出现多个不兼容类。 我遇到过的典型报错有java.lang.NoSuchMethodError: org.apache.hadoop.fs.FileSystem.createjava.lang.NoClassDefFoundError: org/apache/hadoop/hbase/HTableDescriptorjava.lang.NoSuchMethodError: org.apache.hadoop.hbase.client.ConnectionFactory.createConnection这些本质都是因为 Kylin 内嵌的依赖版本太旧。 解决思路很简单把 Kylin 自带的旧版本 Jar 替换成当前环境 Hadoop/HBase 对应的 Jar。具体操作如下。Hadoop 方面cd /opt/kylin/tomcat/lib # 将原先 hadoop-*.jar 移到一个 backup 目录 mkdir -p /opt/backup/kylin-hadoop-jars mv /opt/kylin/tomcat/lib/hadoop-*.jar /opt/backup/kylin-hadoop-jars/ # 把 Hadoop 客户端相关 jar 软链进来 ln -s /opt/hadoop/share/hadoop/common/*.jar /opt/kylin/tomcat/lib/ ln -s /opt/hadoop/share/hadoop/hdfs/*.jar /opt/kylin/tomcat/lib/ ln -s /opt/hadoop/share/hadoop/client/*.jar /opt/kylin/tomcat/lib/ ln -s /opt/hadoop/share/hadoop/mapreduce/*.jar /opt/kylin/tomcat/lib/ ln -s /opt/hadoop/share/hadoop/yarn/*.jar /opt/kylin/tomcat/lib/HBase 方面# 同理先备份旧 jar mv /opt/kylin/tomcat/lib/hbase-*.jar /opt/backup/kylin-hbase-jars/ # 引入 HBase 2.0 的 client 和 server jar ln -s /opt/hbase/lib/hbase-client-2.0.2.jar /opt/kylin/tomcat/lib/ ln -s /opt/hbase/lib/hbase-common-2.0.2.jar /opt/kylin/tomcat/lib/ ln -s /opt/hbase/lib/hbase-server-2.0.2.jar /opt/kylin/tomcat/lib/ ln -s /opt/hbase/lib/hbase-protocol-2.0.2.jar /opt/kylin/tomcat/lib/ ln -s /opt/hbase/lib/hbase-hadoop-compat-2.0.2.jar /opt/kylin/tomcat/lib/这里有个细节HBase 2.0 的 client 会依赖一些 Netty 和 Trace 相关类如果发现运行时还是抱 ClassNotFound把 HBase lib 目录下对应的 netty-*.jar 也一并软链过去。 我没做这一步之前Kylin 启动时卡在 HBase 连接初始化上改了之后才正常。另外Zookeeper jar 也要注意。 HBase 2.0 自带 ZK 3.4.13 的 client而 Kylin 自带可能是 ZK 3.4.5 或者其他版本。 建议把 Kylin 的 zookeeper-.jar 也清理掉软链到 /opt/hbase/lib/zookeeper-.jar避免 Session 莫名其妙断开。3.3 修改 Kylin 核心配置Kylin 的配置文件是 $KYLIN_HOME/conf/kylin.properties。 我这次改动过的关键项如下kylin.server.modeall kylin.metadata.urlkylin_metadatahbase kylin.storage.hbase.region-cut-gb5 kylin.engine.mr.lib-dir/opt/kylin/lib kylin.job.concurrency8 kylin.hbase.region.count.min8 kylin.source.hive.enabletrue解释几个关键参数。kylin.server.modeall本机既要跑查询也要跑 Job。 如果拆成多节点可以把 query 和 job 分开。kylin.metadata.urlKylin 的元数据默认存放在 HBase 里这个配置会给 Kylin 自动创建一个名为 kylin_metadata 的 namespace/表。 第一次启动时会自动建表不需要手动处理。kylin.storage.hbase.region-cut-gb单个 Region 超过 5GB 就触发切割这会影响 Cube 构建时的 HBase 写入和查询性能。 除非数据量很小否则不建议设太低Region 切分频繁会导致构建任务变慢。kylin.hbase.region.count.min预分区数量下限。 如果维度组合比较多建议把这个值调大减少单 Region 热点问题。3.4 启动 Kylin 并初始化元数据所有基础服务就绪后在 kylin-master 上执行$KYLIN_HOME/bin/start.sh启动时需要等待几十秒日志在 $KYLIN_HOME/logs/kylin.log。 第一次启动会初始化 HBase 元数据如果看到New metadata store created: kylin_metadatahbase说明元数据库初始化成功。访问 http://kylin-master:7070/kylin默认账号 ADMIN / KYLIN。 登录后进入 “System” 页面可以看到 Hadoop 3.0.3、HBase 2.0.2 这些版本信息。 如果这里显示的不是 2.0.2 而是 1.x说明 Jar 没有替换干净回 3.2 节继续处理。启动 Kylin 前最好先确认 Hive Metastore 也在运行。 很多同学会漏掉这一步导致 Kylin 界面的 “Data Source” 里加载不到表。4. 实操演示第一个 Cube 构建与查询4.1 准备 Hive 测试数据先建一个简单的销售事实表模拟线上的订单记录。CREATE DATABASE test_db; CREATE TABLE test_db.fact_sales ( order_id string, product_id string, category string, amount double, order_date string ) ROW FORMAT DELIMITED FIELDS TERMINATED BY ,; LOAD DATA LOCAL INPATH /data/sales.csv INTO TABLE test_db.fact_sales;sales.csv 内容类似1001,P001,手机,2999.0,2024-01-01 1002,P002,电脑,5999.0,2024-01-02 1003,P001,手机,2999.0,2024-01-03 1004,P003,耳机,399.0,2024-01-03数据量很小但流程和真实场景一致。 后面构建 Cube 时Kylin 会跑到 YARN 上执行 MapReduce这需要 Hadoop 集群本身正常。4.2 创建 Model 和 Cube进入 Kylin Web UI先建 Project名称随便比如 sale_analysis。 然后在 Data Source 里加载 Hive 表选择 test_db.fact_sales 即可。Model 创建时我需要指定事实表fact_sales。维度字段category、product_id、order_date。度量字段amount聚合方式为 SUM。Cube 创建时我重点讲几个容易被忽略的配置。Rowkeys 的选择顺序直接影响 HBase 的查询效率。 建议把高基数的维度放前面比如 product_id 放第一order_date 第二category 放最后。 如果维度基数相差很大还可以开启 Mandatory Dimension 和 Hierarchy Dimension 来剪枝减少 Cube 膨胀。聚合组也很关键。 比如 order_date 按天、按月、按年分别聚合可以配置成 Hierarchy 关系否则 Kylin 会生成大量多余的 Cuboid造成 Cube 体积爆炸。 我之前在另一个项目里没做裁剪几千万行的数据直接生成几百万个 Cuboid构建时间从半小时变成十几小时非常痛苦。度量可以选 SUM(amount)也可以加一个 COUNT_DISTINCT(order_id) 来算订单数。 需要注意 COUNT_DISTINCT 会占用更多存储而且构建比 SUM 慢不是必需就不用。4.3 构建 Cube在 Cube 页面点击 “Action - Build”选择全量构建。 我这次数据量小选择 “Refresh” 和 “Build” 都可以。 点击后Kylin 会提交一个 MR Job 到 YARN 上日志里会显示 job ID。Build 过程一般包括从 Hive 抽取原始数据。基于维度组合做 Cube 预计算。将结果写入 HBase。在 HBase 中生成 HTable 并注册 Coprocessor。如果前面 Jar 替换有问题这一步最容易暴露比如 hbase coprocessor 相关类错误。 我在 HBase 2.0 上遇到过一个典型问题Coprocessor 加载失败导致 RegionServer 直接卡死。 后来发现是 Kylin 的 hbase-server jar 版本太老替换成 HBase 2.0.2 的 jar 后才能正常构建。构建完成的状态是 GREEN。 如果失败点进去看 MapReduce 日志基本都能定位到具体异常。4.4 SQL 查询构建完成后在 Kylin Web UI 的 “Insight” 页面写 SQLSELECT category, SUM(amount), COUNT(DISTINCT order_id) FROM test_db.fact_sales GROUP BY category;Kylin 会把这条 SQL 重新路由到已经构建好的 Cube 上而不是去扫 Hive 表。 我第一次跑这条查询时因为数据量很小几乎 1 秒内就返回了。 如果直接跑 Hive需要提交一个 MR 任务快则几秒慢则几十秒。 这就是 Kylin 的核心价值复杂维度聚合提前算好查询时只做 HBase 扫描。5. 常见问题速查与实战避坑5.1 启动与依赖问题Kylin 启动时报 Hadoop/HBase 类无法加载基本都是因为 Kylin 自带的 Jar 与环境版本不一致。 按 3.2 节的替换方法处理。 替换后最好重启 Kylin而不是热加载。check-env.sh 提示 HADOOP_HOME 未设置确认 /etc/profile 已配置并且当前 shell 执行过 source /etc/profile。 Kylin 脚本不会主动读取 /etc/profile需要你在启动前手动 export或者放到启动脚本里。HBase RegionServer 崩溃日志出现 coprocessor 相关异常把 Kylin tomcat lib 下的 hbase-server-*.jar 换成 HBase 2.0.2 的版本同时检查 Kylin 的 coprocessor 注册是否在构建后生效。5.2 构建 Cube 的问题构建任务卡住不动先看 YARN ResourceManager 是否有任务再查看 Kylin 日志看是否卡在 Hive 抽取阶段。 多数是 Hive Metastore 没启动或者 Hive 连接超时。维度组合过多导致 Cube 膨胀构建后的 HDFS 存储可能比原表大几十倍。 合理设计聚合组、启用 Mandatory 和 Hierarchy 维度、必要时用聚合组里的“联合维度”。 这是一开始就要想清楚的而不是等构建完了再改。构建后查询结果不对检查 Model 的时间维度。 如果你用了增量构建时间字段格式必须和 Hive 表一致否则会丢数据。5.3 查询慢的问题查询响应突然变慢先看 HBase 是否有 Region 热点。 如果单个 Region 太大会降低并行扫描能力。 调大 kylin.storage.hbase.region-cut-gb 不合理应该把预分区数量增加或者优化 Rowkey 顺序。SQL 没有命中 CubeKylin 不是所有 SQL 都能跑。 如果你的查询维度组合不在 Cube 的 Cuboid 列表里Kylin 会扫描进度增大的 Cuboid速度变慢。 打开 SQL 的 “Query Result” 能看到命中的 Cuboid 信息拿这个作为优化依据。5.4 问题速查表现象可能原因处理方式登录 Kylin 后加载数据源为空Hive Metastore 未启动启动 Hive metastore启动 Kylin 报 NoClassDefFoundErrorJar 版本冲突替换 Kylin tomcat/lib 下的 Hadoop/HBase jar构建 Cube 时 MR Job 失败HBase 客户端依赖缺失软链 HBase 2.0 全部依赖 jar 到 Kylin libRegionServer 崩溃HBase Coprocessor 类加载失败替换 hbase-server jar 并重启组件查询结果不准确增量构建时间配置错误检查 Model 的时间范围和 Hive 时间格式Cube 构建后体积过大Cuboid 裁剪不到位启用聚合组、强制维度、层次维度最后聊点体会这套环境组合Hadoop 3.0 HBase 2.0 Kylin 3.10不是装完就能用的核心工作量大多花在依赖兼容上。 我个人的建议是不要一上来就做 Cube 调优先把 Kylin 元数据初始化、Web UI 登录、数据源加载、Cube 构建这条链路跑通再去考虑维度裁剪和查询性能。 版本兼容问题优先通过替换 Jar 解决而不是改代码。另外HBase 2.0 的稳定性和 Hadoop 3.0 的 ResourceManager 都还有不少内存问题建议严格控制 YARN 容器内存大小并给 Kylin 单独预留 JVM 堆。 我们团队后来为 Kylin 加了独立节点和 HBase 的 RegionServer 分开部署内存压力就缓解了很多。如果你也是要在新版本 Hadoop/HBase 上跑 Kylin最好先把 Kylin 官方包里自带的依赖清单导出来再和当前环境做 diff。 这个步骤看起来麻烦却能省下后面排查问题的大量时间。