写点什么

Kylin 在贝壳的性能挑战和 HBase 优化实践

  • 2021-01-10
  • 本文字数:4993 字

    阅读完需:约 16 分钟

Kylin 在贝壳的性能挑战和 HBase 优化实践

Kylin 在贝壳的使用情况介绍



Kylin 从 2017 年开始作为贝壳公司级 OLAP 引擎对外提供服务, 目前有 100 多台 Kylin 实例;有 800 多个 Cube;有 300 多 T 的单副本存储;在贝壳 Kylin 有两套 HBase 集群,30 多个节点,Kylin 每天的查询量最高 2000+万


我们负责 Kylin 同事张如松在 2018 年 Kylin Meetup 上分享过Kylin在贝壳的实践,当时每天最高请求量是 100 多万,两年的时间里请求量增加了 19 倍;我们对用户的查询响应时间承诺是 3 秒内的查询占比要达到 99.7%,我们最高是达到了 99.8%。在每天 2000+W 查询量的情况下,Kylin 遇到很多的挑战,接下来我将为大家介绍一下我们遇到的一些问题,希望能给社区的朋友提供一些参考。


Kylin HBase 优化


表/Region 不可访问


1)现象



凌晨构建 Cube 期间,会出现重要表的某个 region 不可访问导致构建失败的情况,右上角的图是 HBase 的 meta 表不可访问的日志;白天查询时也有部分查询因为数据表某个 Region 不可访问导致查询超时的情况,右下角的图是查询数据表 Region 超时的日志;另外一个现象是老的 Kylin 集群 Region 数量达到 16W+,平均每台机器上 1W+个 Region,这导致 Kylin HBase 集群建表和删表都非常慢,凌晨构建会出现建表卡住的现象,同时清理程序删除一张表需要三四分钟的时间,面对这样的情况,我们做了一些改进。


2)解决方案



删除无用表减少 Region。 通过刚才的介绍 HBase 集群平均每台机器上 1W+个 Region,这对于 HBase 来说是不太合理的,另外由于删除一张表需要三四分钟的时间,清理程序也执行的异常缓慢,最后我们不得不使用了一些非常规手段删除了 10W+个 Region。


缩短清理周期, 从之前的一周清理一次 HBase 表到每天清理一次,除此之外 Kylin 会每周合并一次 Cube 来减少 HBase 表数量从而减少 Region 数量,最终 16W+的 Region 删到了不到 6 万,至此我们解决了一部分问题,还会存在构建时重点表的 Region 不可访问的情况。


将 HBase 从 1.2.6 升到 1.4.9, 主要是想要利用 RSGroup 的能力来做重点表和数据表的计算隔离;


关闭 HBase 自动 Balance 的功能, 仅在夜间业务低峰期开启几个小时;


使用 HBase 自带的 Canary 定期的检测 Region 的可能性, 如果发现某些 Region 不可用马上发送告警


使用 RSGroup 单独隔离重点表来屏蔽了计算带来干扰, 这些重点表包括 HBase Meta 表、Acl 表、Namespace 表、Kylin_metadata 表。


经过了这一系列的改进之后表/Region 不可访问的问题基本上解决了,现在基本上没有再出现 Region 不可访问的情况。解决这个问题我们花费了很长时间,经历了升级重启和删了大量的表后,我们遇到了另外一个问题。


RS 数据本地性提升


1)现象



Kylin HBase 集群的 RegionServer 数据本地性非常低,只有 20%不能很好的利用 HDFS 短路读,这样对查询响应时间产生了一定影响 ,我们三秒内的查询占比出现了下降。了解 HBase 的朋友都知道如果 RS 的数据本地性较低,有一种解决方案就是做 Compact 把数据拉到 RegionServer 对应的 Datanode 上,考虑到大规模的做 Compact 会对查询造成很大影响,我们没有这么做,跟 Kylin 的同学沟通后发现绝大多数的 Cube 每天会使用最新构建的表,查旧表的可能系不是特别大,所以提升每天新建表的数据本地性就可以了, 具体我们是这样做的。


2)解决方案



我们发现 Kylin 用到的是 HFileOutputFormat3 跟 HBase 的 HFileOutputFormat2 是有一些差别的,我们在 HFileOutputFormat3 里面加入了 HBASE—12596 的特性,这个特性主要是生成 HFile 的时候会写一份数据的副本到 Region 所在的 RegionServer 对应的 Datanode 上。下面是一些代码细节,程序会先取到这个 Region 所在的机器,然后再获取 Writer 时,把这台节点的信息传递过去,最后写数据的时候会写一个副本到这个 Region 对应的 Datanode 上, 这样逐渐我们的数据稳定性就提上来了,现在看了一下基本上在 80%多左右。


RegionServer IO 瓶颈


1)现象


我们发现在构建早高峰时,HBase 响应时间的 P99 会随之升高的,通过监控发现是由于 RegionServer 机器的 IO Wait 偏高导致的。


还有一种场景是用户构建时间范围选择过大,导致网卡被打满,之前有个用户构建了一年的数据,还有构建三四个月数据,这两种情况都会造成 RegionServer 机器 IO 出现瓶颈导致 Kylin 查询超时。



上图是 Cube 数据构建流程,首先 HBase 集群和公司大的 Hadoop 集群是独立的两套 HDFS 集群,每天构建是从大集群的 HDFS 去读取 Hive 的数据,构建任务直接输出 HFile 到 HBase 的 HDFS 集群,最后执行 Bulkload 操作。由于 HBase HDFS 集群机器较少,构建任务写数据过快导致 DataNode/RegionServer 机器 IO Wait 升高,怎么解决这个问题呢?


2)解决方案



我们想用 HBase 比较常用的方式就是 DistCp 来解决这个问题,左下角这张图是我们的改进方案,就是我们设置构建任务的输出路径到 Hadoop 的大集群,而不是到 HBase 的 HDFSB 及群,再通过 DistCp 限流的拷贝 HFile 到 HBase 的 HDFS 集群,最后做 Bulkload 操作。之前提到我们有 800 多个 Cube,并不是所有的 Cube 都需要走这套流程, 因为限流拷贝的话肯定会影响数据的产出时间,我们设计了针对 Project 或者是 Cube 设置开启这个功能, 我们通常会对数据量比较大的 Cube 开启 DistCp 限流拷贝,其他 Cube 还是使用之前的数据流程。


中间这个图是一个构建任务的截图,第一步是生成 HFile,第二步是 DistCp,最后再 Bulkload,这个功能我们新增了一些配置项,比如说第一个是否开启 DictCp,第二个是每个 Map 带宽是多少,再有就是最大有多少 Map。通过这个功能我们基本上解决了构建高峰 IOWait 会变高的情况。


慢查询治理–超时定位链路优化


1)现象



慢查询治理遇到的第一个问题就是超时定位链路特别长。我们收到 Kylin 报警时首先会想知道:


  • 是哪个 Cube 超时了?

  • Cube 对应的 HBase 表是哪个?

  • 是 Region 不可用还是查询方式变了?


之前提到有一段时间经常出现 Region 不可用的情况,一旦出现超时我们查询链路是什么样的呢? 可能我们先去看 HBase 日志里看有没有 Deadline has passed 的警告日志,有这种报警的话我们会拿到它的 QueryID,然后去 ES 或者是 Mysql 里面去查询这个 QureyID 对应的 Cube 信息和 SQL,知道这些信息之后,还需要去到超时的 Kylin 节点上去查询日志,从日志里面才能找到是查询哪个 HBase 表的哪个 Region 超时,然后再去判断是不是 Region 不可用了,或者是查询方式改变。 这个链路非常长,每次都需要 HBase 和 Kylin 的同学一块儿来查。


2)解决方案



针对这个痛点给我们做了如下改进:我们直接把 Cube 信息和 Region 的信息打在 HBase 的日志里。 中间这个黑色的部分就是 HBase 的日志,我们可以看到这个查询已经终止了,Cube 的名字是什么,Region 的名字是什么,下面的白色部分是通过天眼系统配置的报警信息,这个报警是直接报到企业微信的,我们能马上知道这个 Deadline 涉及的 Cube 和 Region,能马上做一个检测是这个表不可用了还是查询方式改变了,大大节省了定位问题的时间。



这个是为了解决超时链路过长我们对 Kylin 做的一些代码改动,首先我们在 Protobuf 文件中加了一个 segmentName 字段,然后在协处理器类中获取了 Region 名字,在协处理器调用 checkDeadLine 方法检查时传入 segmentName 和 regionName,最后日志会打印出来 segment 名称和 Region 的信息。 这个功能已经反馈给社区了,见:https://issues.apache.org/jira/browse/KYLIN-4788


慢查询治理-队列堆积定位


1)现象



有一天我们发现 Kylin HBase RegionServer 队列堆积非常严重,RegionServer 的 P99 的响应时间已经达到了 10 多分钟的级别,大家看右上角是 HBase 关于队列的监控情况,一些机器的堆积已将近 3W。我们当时非常疑惑,因为 Kylin 和 HBase 之间 RPC 的超时时间是 10 秒,在 10 秒之后 Kylin 和 HBase 的连接都已经断开了,HBase 到底处理什么查询,右下角是 HBase RegionServer UI 页面的截图,在这个截图里我们发现一些查询其实已经执行了快半个小时了,这半个小时是在执行什么呢?


2)解决方案



我们当时的解决方案是去任务堆积的有队列推积的 RegionServer 上去看日志,通过查询开始时间结束时间做差值,找出查询时间最长的 Top10 的查询,通过 QureyID 匹配出 Cube 和具体的 SQL,最终我们发现一般这种查询时间特别长都是因为查询方式的变化与原来 Cube 设置的 Rowkey 不相符导致了全表扫描。最终的方案其实查出来之后 Kylin 的同学会去调整 Cube 的 Rowkey 设置,然后重新构建。


这种离线的定位的方式其实不是特别好,一开始我们想基于日志做实时报警,这样能帮助我们更快的发现和定位问题,但是后来想想这也是比较被动的一种方式,这只是发现问题,不能彻底解决这个问题。


我们后来想的一个方案是 SQL 作执行之前可以为 SQL 打分,评分过低的就拒绝执行,这个功能还没有实现。有这个想法是因为当我们找到 SQL 信息后, Kylin 的同学是可以看出来查询是不是不合理,是不是跟 Rowkey 设置不符,我们想以后做这样一个功能,把人为判断的经验程序化,在 SQL 没有执行之前就把潜在的风险化解掉。


慢查询治理 – 主动防御



慢查询治理还有一个举措是 Kylin 的主动防御。我们发现有大量的耗时较长的查询会占据请求队列,影响其他查询的响应时间。


解决方案是通过 Kafka 收集 Kylin 的日志,经过天眼系统实时清洗后写入 Druid,通过 Druid 做统计分析,如果某个业务方/Cube 在一定时间内超过 3 秒的查询到达一定的阀值,主动防御系统会把这个业务方/Cube 的查询超时时间设置为 1s,让较慢的查询尽快超时,避免对正常查询的干扰。右边就是我们整个流程的一个架构图,主动防御对慢查询治理有一定的作用,但全表扫描的情况还是没有办法完全避免。


重点指标查询性能保障


1)现象



另外一个举措是对重点指标的查询性能保障。早期 HBase 集群只有 HDD 一种存储介质,重点指标和普通指标都存储在 HDD 上,非常容易受到其他查询和 HDD 性能的影响,重点指标响应时间无法保障。


2)解决方案


我们的解决方案是利用了 HDFS 的异构存储,给一部分 DataNode 插上 SSD,将重点 Cube 的数据存储在 SSD 上,提升吞吐的同时与普通指标数据做存储隔离,这样就既避免了受到其他查询的影响,也可以通过 SSD 的性能来提升吞吐。引入 SSD 只是做了存储的隔离,还可以通过 RSGroup 做计算隔离,但由于重点指标的请求量占到了集群总请求量的 90%以上,单独隔离出几台机器是不足以支撑这么大请求量的,所以最终我们并没有这么做。


最后是我们得出的一些经验, SSD 对十万以上扫描量查询性能提升 40%左右,对百万以上扫描量性能提升 20%左右。



这是我们用 SSD 做的一些改动,数据存储在 SSD 是可针对 Cube 设置的。我们可以指定哪些 Cube 存在 SSD 上,构建任务建表时会读取 Cube 的配置,按照 Cube 配置来设置 HBase 表的属性和该表的 HDFS 路径存储策略。在 DistCp 拷贝之前也要先读取 Cube 的配置,如果 Cube 的配置是 ALL_SSD,程序需要设置 DistCp 的目的路径存储策略为 ALL_SSD,设置完成后再进行数据拷贝。


这样做的目的是为了避免 Bulkload 后数据还需要从 HDD 移动到 SSD,移动数据会带来什么影响呢? 我们发现如果不先设置 DistCp 目的路径存储策略的话,数据会被先写到 HDD 上,Bulkload 后由于表的 HDFS 存储路径存储策略是 ALL_SSD,Hadoop 的 Mover 程序会把数据从 HDD 移动到 SSD,当一个数据块的三个副本都移动到 SSD 机器上后,RegionServer 不能从其缓存该数据块的三台 DataNode 上读取到数据,这时 RegionServer 会随机等待几秒钟后去向 NameNode 获取该数据块最新的 DataNode 信息,这会导致查询响应时间变长,所以需要在 DistCp 拷贝数据之前先设置目的路径的存储策略。


JVM GC 瓶颈


1)现象



我们遇到的下一个问题就是 RegionServer 的 JVM GC 瓶颈。在查询高峰期 Kylin HBase JVM Pause 报警特别频繁,从这张图里面可以看到有一天已经超过 1200 个。Kylin 对用户的承诺是三秒内查询占比在 99.7%,当时已经达到了 99.8%,于是我们就想还需要优化哪一块能让 3 秒内查询占比达到 99.9%,这个 JVM Pause 明显成为我们需要改进的一个点,大家做 JAVA 基本都知道 JVM 怎么去优化呢?


2)解决方案



首先可能会想到调整参数,其次就是换一种 GC 算法,我们采用了后者。 之前我们用的是 JDK1.8,GC 算法是 G1,后来我们了解到 JDK11 推出了一个新的算法叫 ZGC。最终,我们把 JDK 从 1.8 升级到 JDK13,采用 ZGC 替代了原有的 G1。右上角的图是 ZGC 上线后,这套集群 RegionServer 的 JVM Pause 的次数几乎为 0,右下角的 GC 时间也是相比之前降低特别多。ZGC 有一个设计目标是 Max JVM Pause 的时间在几毫秒,这个效果当时看着是比较明显的,左边的图是天眼系统的报警的趋势图,ZGC 上线后 JVM Pause 报警数量明显降低。关于 ZGC 我本月会发一篇文章介绍 ZGC 算法和我们做了哪些改动来适配 JDK13,这里就不详细介绍了。


作者介绍


冯亮,贝壳找房高级研发工程师。


本文转载自公众号 apachekylin(ID:ApacheKylin)。


原文链接


Kylin 在贝壳的性能挑战和 HBase 优化实践

2021-01-10 10:002057

评论 2 条评论

发布
用户头像
刚好逮住一个,你们不知道自己的app 卡的要死吗?一旦进入搜索框等待至少3秒以上,更傻的是会还不会去掉搜索框历史记录直接按历史搜
2021-01-10 15:04
回复
人家是后端大数据这块的,不是安卓/iOS 这块的,你在这说也没用啊。人家说不定是 fire-forget 发了文章就不管的呢。
2021-01-12 14:46
回复
没有更多了
发现更多内容

【技术分享】浅谈RTC及Agora RTC SDK集成介绍

Hanson

腾讯大牛整合Java+spring5系统学习架构,神乎其技

小Q

Java 学习 编程 面试 spring 5

给你一个亿的keys,Redis如何统计?

不才陈某

redis

我理解的信息化、数字化、数智化

boshi

数字化 数据智能 信息化

Spring 源码学习 05:BeanDefinition 概念及其实现

程序员小航

spring 源码 源码阅读 BeanDefinition

重点人员管控系统开发,可视化数据分析搭建

t13823115967

重点人员管控系统开发 智慧公安 可视化数据分析搭建

微软最强 Python 自动化工具开源了!不用写一行代码!

星安果

Python 微软 自动化 自动化测试 playwright

IntelliJ IDEA 2020.3正式发布,年度最后一个版本很讲武德

YourBatman

IDEA 新特性 2020.3

面试无忧:源码+实践,讲到MySQL调优的底层算法实现

996小迁

Java 架构 面试

ONES 收购 Tower,五源资本合伙人对话两位创始人

万事ONES

项目管理 团队协作 ONES Tower 收购

Spock单元测试框架实战指南一Spock是什么?它和JUnit有什么区别?

Java老k

Java 单元测试 JUnit Mock spock

《穿越数据的迷宫》笔记:第 3 章 DAMA的数据管理原则

方志

数据治理

架构设计之路-1

5加3彩票

架构师 代码规范

架构师训练营第 1 期 -week11

习习

《技术男征服美女HR》—Fiber、Coroutine和多线程那些事

太白上仙

Java 程序员 面试 后端 多线程

AOT慈善币系统软件开发|AOT慈善币APP开发

系统开发 现成系统

架构师训练营第 11 周课后练习

叶纪想

极客大学架构师训练营

英特尔发布第二代Horse Ridge低温量子控制芯片

E科讯

关于binlog,这个参数能不能用?

Simon

MySQL Binlog

跨架构编程不再难,英特尔机器编程工具迎来重磅更新

E科讯

英特尔神经拟态生态系统发展和研究的最新进展

E科讯

国产电子表格Luckysheet后台也开源了!支持在线协作,一键docker私有部署

奇异石榴果

Java Excel SpreadJS 表格控件

1分钟解密:博睿大数据核心引擎Bonree Zeus六大优势

博睿数据

英特尔推动集成光电的发展,用于数据中心

E科讯

智慧公安扫码一键定位报警系统搭建

t13823115967

智慧公安 智慧公安扫码 一键定位报警系统搭建

谁能阻止世纪互联星光?2020年第11期北京机房网络质量评测数据排行榜发布

博睿数据

加码线下,新荣耀“破题”场景经济

脑极体

javascript开发后端程序的神器nodejs

程序那些事

Java 后端 nodejs koa 程序那些事

Linux平台中调试C/C++内存泄漏方法 (腾讯和MTK面试的时候问到的)

linux大本营

c++ Linux 后台开发 架构师

极客大学 - 架构师训练营 第十一周总结

9527

甲方日常 62

句子

工作 随笔杂谈 日常

Kylin 在贝壳的性能挑战和 HBase 优化实践_架构_apachekylin_InfoQ精选文章