写点什么

Apache Kylin 实践:链家数据分析引擎的演变史

2018 年 4 月 19 日

作者介绍:

链家网工程师,大数据架构团队成员,目前主要负责 OLAP 平台建设及大数据应用拓展。

前言

伴随链家业务线的拓宽和发展,以及数据生态的建设,数据规模快速增长。从 2015 年大数据部门成立至今,集群数据存储量为 9PB,服务器规模为 200 台 +。与此同时,数据需求也随着业务的发展落地不断增长,如统计分析、指标 API、运营报表等,不同业务需求差异较大,维度越来越多,需要定制化开发。面对数十亿行级别的数据,低延迟响应的特性,保障服务稳定、数据准确,链家的数据分析引擎经历了如下的发展历程。

早期的 ROLAP 架构

起初,数据规模不大,增长不是很快。而且,数据需求比较零散,处于摸索阶段。采用如下 ROLAP 引擎,支撑数据分析:

具体处理流程:数据源接入 HDFS,加载进 HIVE。数据开发工程师根据业务需求,开发 ETL 脚本,配置 OOZIE 任务调度执行,根据数据仓库分层模型,逐层生成数据,最终推送到 mySQL,根据维度筛选、聚合展示。

随着数据规模的增长和需求的增多,瓶颈逐渐显现。每个需求都要开发数据脚本,维度增加,开发周期拉长,同时需要耗费更多的人力,无法快速产出数据和响应需求变化。

链家 OLAP 平台及 Kylin 使用

如上,为链家 OLAP 平台结构,于 16 年底搭建。Kylin 采用集群部署模式,共部署 6 台机器,3 台用于分布式构建 Cube,3 台用于负载均衡查询,query 单台可用内存限制在 80G。同时,计算集群一旦运行大任务,内存压力大的时候,Hbase 就会性能非常差,为避免和计算集群互相影响,Kylin 集群依赖独立的 Hbase 集群。同时,对 Hbase 集群做了相应的优化,包括:读写分离、SSD_FIRST 优先读取远程 SSD、并对依赖的 HDFS 做了相应优化。

由于 Kylin 只专注预计算,不保存明细数据,对于即席查询和明细查询,通过自研 QE 引擎实现,底层依赖 Spark、Presto、HIVE,通过特定规则,路由到相应查询引擎执行查询。多维分析查询,由 Kylin 集群提供查询服务,可实现简单的实时聚合计算。

当前 Kylin 主要查询方为指标 API 平台,能根据查询 SQL 特征,做相应缓存。指标 API 作为数据统一出口,衍生出其他一些业务产品。使用统计,如下:Cube 数量 350+,覆盖公司 12 个业务线。Cube 存储总量 200+TB,数据行万亿级,单 Cube 最大 40+ 亿行。日查询量 27 万 +,缓存不命中情况下,时延<500ms(70%), <1s(90%),少量复杂 SQL 查询耗时 10s 左右。

Kylin 应用场景及使用规范

适用场景:数据规模大,非实时,目前能支持小时级别;维度组合和查询条件组合在可预见的范围内;查询条件扫描范围不会太大;不适合需要大范围模糊搜索排序的场景(类似 Search)。 如何能规范的使用 Kylin 很重要,在 Kylin 建设初期,踩过很多坑。并不是程序的错误,而是未能详细了解 Kylin 使用流程及规范,逐渐摸清积累了一些经验,沉淀到公司 wiki,供相关人员参考。大致如下:

一、维度优化,预计算的结果需要存储到 Hbase,且支持实时查询,因此,在配置维度时,要考虑到存储和查询的优化。包括:维度的编码,根据维度的值类型,选择合适的存储类型,可节省空间,加快 Hbase scan 效率;可根据业务需要,对维度进行分片存储,增加查询的并发度,缩短查询时间;基数允许范围内的维度,尽量采用字典编码;对于分区字段,一般格式为 yy-MM-dd hh:mm:ss,若只需要细化到天级别,可保存为数字类型 yyMMdd,极大降低维度基数。

二、根据 Hbase 的查询特性,rowkeys 是由维度组合拼接而成,因此要考虑到以后查询场景:对于查询频繁的维度,在设置 rowkeys 时,优先放在前面。

三、维度组合优化,由于维度的组合影响最终的数据量,因此如何能减少维度的组合,是 Cube 配置时所要考虑的。根据业务需要,及 Kylin 支持的特性,可进行的维度组合优化有:使用衍生维度,只物化维度表的主键,牺牲部分运行时性能进行实时 join 聚合;使用聚合组,将相关维度内聚成一组,并在聚合组内,根据维度的特征,配置强制维度、层级维度、联合维度。聚合组的设计可以非常灵活,例如,高基数的维度,可以单独一个 group。

四、及时清理失效数据。由于构建过程出错或者集群故障,会导致一些垃圾文件,随着时间积累的一些无用 segment,不但占用存储空间,增加 namenode 内存压力,以及占用 Hbase、HIVE 及 Kylin 元数据空间,因此需要定期清理掉,保持存储环境干净。

应该实时监控集群状态,重点关注 Cube 构建和查询的低延迟,不断优化数据模型及 Cube 的设计和存储,根据用户真正的需求,在存储、构建及查询性能间找到最佳的平衡点。

链家 Kylin 能力扩展

当前,Kylin 在用版本为 1.6,最新版本为 2.3。自 2.0 版本之后,又新增了一些新的特性,配置文件和属性也做了一些调整。由于,Cube 数据量大,涉及业务方多,在当前无明显瓶颈的情况下,没有实时更新新版本。但是,引入了 2.0+ 新增的一些重要特性,如分布式构建和分布式锁。

我们维护了自己的一套 Kylin 代码,使用过程中,针对特定场景的进行一些优化开发,包括:

一、支持分布式构建。原生 Kylin 是只能有一台机器进行构建。的当 Kylin 上的 Cube 越来越多,单台机器显然不能满足任务需求,除了任务数据有限制,任务多时也会互相影响数据构建的效率。通过修改 Kylin 的任务调度策略,支持了多台机器同时构建数据。使 Kylin 的构建能力可以横向扩展,来保证数据构建;

二、优化构建时字典下载策略。原生 Kylin 在 build cubiod data 时用的字典,会将该字段的全部字典下载到节点上,当字段的字典数量很多或者字典文件很大时,会在文件传输上消耗很多不必要的时间。通过修改代码,使任务只下载需要的字典文件,从而减少文件传输时间消耗,加快构建;

三、全局字典锁,在同一 Cube 所任务构建时,由于共享全局字典锁,当某执行任务异常时,会导致其他任务获取不到锁,此 bug 已修复并提交官方( https://issues.apache.org/jira/browse/KYLIN-3087 );

四、当有多台 query 情况下,元数据同步时,RestClient 采用的 BasicClientConnManager 会遇到并发瓶颈,抛出异常,解决方案为替换成 PoolingClientConnectionManager,并提交官方( https://issues.apache.org/jira/browse/KYLIN-2862 );

五、同一 Cube 构建多个 segment 时,假如第一次构建的 segment 时间段晚于第二个 segment,会取第一次的 last_build_time 作为最后一次构建时间,取值错误,已修复提交官方( https://issues.apache.org/jira/browse/KYLIN-2789 );

六、支持设置 Cube 强制关联维表,过滤事实表中无效的维度数据。Kylin 创建的临时表作为数据源。当使用 OLAP 表和维表关联字段作为维度时,会默认不关联维表,直接使用 OLAP 中的字段做维度。而在 Build Cube 这一步又会使用维表的字典来转换维度的值。如果 OLAP 中的值维表中没有就会产生问题。我们通过增加配置项,可以使 Kylin 强制关联维表,来过滤掉 OLAP 表中的脏数据;

七、Kylin query 机器,查询或者聚合,会加载大量的数据到内存,内存占用大,甚至存在频繁 Full GC 的情况。这种情况下,CMS 垃圾回收表现不是很好,因此更换为 G1 收集器,尽量做到 STW 时间可控,并及时调优。除了上述对 Kylin 本身的修改外,我们开发了 Kylin 中间件实现了任务调度、状态监控、权限管理等功能。

Kylin 中间件

中间件承接 Cube 管理及任务的调度,对外屏蔽了 Kylin 集群,架构图如下

可实现如下功能增强:

  1. 理论上,可实现无限容量队列,现实中不会有这么大任务量,也不会一直堆积;
  2. 同时,针对特定的 Cube,实现优先调度,保障重要数据的及时产出;
  3. 元数据管理平台,可通过中间件执行 SQL 查询,而指标 API 平台,需要预先在元数据管理平台配置 API 查询接口,配置时可看到自身权限对应的数据,由此实现权限的管控;
  4. 当任务执行失败,可进行有限次数重试,重试不成功会报警;
  5. 同时,可实现并发控制,由于 Kylin 集群的承载能力有限,过多的任务同时执行,会造成大量任务失败,目前设置最多提交 50 个构建任务同时运行。

总结

Kylin 引擎核心组件可扩展,支持超大规模数据,ANSI SQL 易用性高,作为链家 OLAP 平台的关键组件,基本承载了全部的多维分析需求,提升了数据产出效率和查询性能。相比 rOLAP 架构,现在只需关注基础数据建设和数据探索,节省了大量人力,并提高了整体可维护性。

在 OLAP 平台建设期间,Kyligence 给予我们很大帮助,并和其他公司保持技术交流。Kylin 社区很活跃,核心开发团队也非常热心、高效,作为国人主持开源的 apache 顶级项目,希望 Kylin 和社区有更好的发展。

未来,我们会持续跟踪业务需求,不断优化集群性能,提升集群稳定性和易用性。并重点关注大结果集查询性能、Spark 构建引擎、任务资源隔离等。

关于链家大数据架构团队

链家网大数据架构团队负责公司大数据存储平台、计算平台、实时数据流平台的架构、性能优化、研发等,提供高效的大数据 OLAP 引擎、以及大数据工具链组件研发,为公司提供稳定、高效、开放的大数据基础组件与基础平台。

2018 年 4 月 19 日 18:094019

评论

发布
暂无评论
发现更多内容

Clickhouse 性能测试

久吾尔岂

开始每周写作计划

M1racle

C++线程池的实现

程序喵大人

c++ C# 线程池

各大公司面试题分类整理

吕小毛

后端 面试题

centos7 maven私服自动启动

kcnf

内存对齐

程序喵大人

c c++ C#

JAVA小抄-000-初始

NoNoGirl

Java

婚姻就是合伙开公司,各自做好自己的工作很重要

鼎玉谷

管理 婚姻 公司 付出 人情

如何利用数据异构实现多级缓存或者数据迁移

松花皮蛋me

缓存 分布式 分库分表

金融「中台」十宗罪

fino星君

中台 企业中台 业务中台

对你来说,阅读是另一种生活的方式吗?

叶小鍵

读懂才会用 : Redis的多线程

小眼睛聊技术

Java redis 学习 程序员 编程语言 后端

关于GDB你需要知道的技巧

程序喵大人

c c++ C#

瞎琢磨先生の好物推荐(软件/网站)

瞎琢磨先生

Redis学习笔记(基础命令)

编程随想曲

redis

如何对Code Review的评论进行分级

宝玉

代码审查 Code Review

C++定时器的实现

程序喵大人

c c++ C#

浅谈SpringCloud之服务注册中心Eureka

北漂码农有话说

重新认识Go语言中的slice

麻瓜镇

golang

面试指南 | 终于要跟大家见面了,我有点紧张。

Apache Flink

大数据 flink 流计算 实时计算 大数据处理

翻译和产品本地化的区别是什么?

葛仲君

翻译 本地化 全球化 产品开发

当我们谈到ThreadLocal的时候,我们在谈什么?

Jason

Java 多线程 ThreadLocal

基于vue(element ui) + ssm + shiro 的权限框架

吴邪

DDD 实践手册(4. Aggregate — 聚合)

Joshua

设计模式 领域驱动设计 架构模式

笔记:《如何系统思考》之如何做到系统思考

wiflish

思维方式

瞎琢磨先生の常用的 linux 命令

瞎琢磨先生

Linux Shell

机会是留给不停寻找他们的人,而不是原地等待的人

非著名程序员

程序员 提升认知 机会 行动派

写作的意义到底是什么

七镜花园-董一凡

写作

准备重读测试驱动开发

escray

学习 CSD 认证实战营

习惯与惯性

伯薇

个人成长 习惯 习惯养成 提升能力

《TCP/IP详解》概述

网瘾少年SEC

TCP 网络协议 IP

InfoQ 极客传媒开发者生态共创计划线上发布会

InfoQ 极客传媒开发者生态共创计划线上发布会

Apache Kylin实践:链家数据分析引擎的演变史-InfoQ