HarmonyOS开发者限时福利来啦!最高10w+现金激励等你拿~ 了解详情
写点什么

百度智能监控场景下的 HBase 实践

  • 2019-05-07
  • 本文字数:4212 字

    阅读完需:约 14 分钟

百度智能监控场景下的HBase实践

通过百度大规模时序数据存储系列文章的介绍,想必读者对百度智能监控系统 Noah 的 TSDB 不再陌生,它主要用来存储 Noah 监控系统的时序指标数据,包括但不限于硬件和软件的可用性指标、资源使用率指标和性能指标等。如《百度大规模时序数据存储(二)|存储选型及数据模型设计》文章所述, Noah-TSDB 是基于 HBase 为底层存储的基础上自主研发的,其优秀的性能离不开 HBase 的贡献。今天主要聊聊在百度智能监控场景下的 HBase 相关实践经验,先简单介绍一下 HBase。

HBase 架构简介

HBase 是一个基于 Java、开源的、非关系型的、面向列存储的分布式可扩展的大数据存储数据库。HBase 的集群主要由 HMater 和 RegionServer 两种角色组成,底层以 HDFS 作为存储设施,集群由 Zookeeper 协助管理。其架构如下图所示:



图 1 HBase 架构图


简单介绍一下 HBase 中相关组件的作用:


  • HMaster


HMaster 是整个集群的大脑,负责数据表的操作、集群的负载均衡和故障恢复等集群管理工作。


  • RegionServer


HBase 将表以行为单位划分成许多片段,每个片段称为一个 Region。这些 Region 被分配到 RegionServer 进行管理。在读写流程中,定位到数据所在 RegionServer 后,Client 与 RegionServer 直接交互进行数据的读写。


  • Zookeeper


HBase 作为一个大规模的分布式系统,Zookeeper 的作用是至关重要的。首先 Zookeeper 作为 HMaster HA 解决方案,保证了至少有一个 HMaster 处于工作状态。其次 Zookeeper 通过心跳机制探活 RegionServer,当 RegionServer 故障时及时通知 HMaster 进行故障处理工作。最后 Zookeeper 保存了维护全局元信息的 META 表的路径,Client 第一次与 HBase 集群交互时,需要通过 META 表来获取目标数据所在的 RegionServer。


上面简单介绍了 HBase 的架构和各组件的基本信息,下面和大家分享一下在百度最大规模时序数据库的场景下使用 HBase 时遇到的几个典型问题和优化方案。

热点问题

大家都知道木桶效应,对于 TSDB 系统来说,热点 Region 所在的 RegionServer 就是影响整个”水桶”容量最短的那块木板。理想情况下 HBase 中所有的请求应该均匀的分布在所有 RgionServer 的所有 Region 上,当个别 Region 收到的读写请求数量大幅超过其它的 Region,它所在的 Region 就有可能成为热点。



图 2 RegionServer 信息(此图来源网络非百度实际数据)


Noah-TSDB 初期曾遇到监控元数据表设计不合理导致热点的问题。当时研发同学收到 Noah-TSDB 写入模块队列堵塞的业务报警,从 Noah 监控系统上看到同时间段访问 HBase 异常明显增长。HBase 中的个别 RegionServer 频繁进行 GC,网络 I/O 和磁盘 I/O 密集,操作队列中待执行的请求堆积严重,负载明显高于其它的 RegionServer。查看异常 RegionServer 的日志发现大量请求访问的是同一个 Region:”tsdb-meta,*** 1.”。初步定位是由于该 Region 负载过高,导致它所在的 RegionServer 成为热点,进而导致系统的吞吐量下降,上游写入模块请求堆积。


tsdb-meta 是用来存储监控指标的名称、周期等元信息的表,表中红色填充的行代表其拥有数据量超过正常水平的,表结构如下:


表 1 原始 tsdb-meta 表



分析上面的存储结构,我们可以知道:


  1. 同一个监控对象(namespace)的监控指标元信息将会存储在 HBase 表的同一行。

  2. 不同监控对象的指标数量不同,将导致行的大小不均匀。

  3. HBase 中数据分片是以行为单位,每行的数据存储在同一个 Region 中,当某一行存储的监控指标数量远大于正常水平时,该行就有可能成为热点。


综上所述,当个别监控对象拥有的监控指标个数过多时,tsdb-meta 可能会出现热点问题。同时经我们验证发现,成为热点的监控对象拥有的监控指标的数量大约是正常水平的 20 倍左右,进一步确认了故障原因。


定位到根因后,我们决定从两个方面来着手解决这个问题。一方面,定期统计监控对象拥有的指标个数,及时发现由于监控配置异常和不合理使用导致的个别监控对象拥有的监控指标过多的问题。第二方面,对 tsdb-meta 表结构改造,将原来按列分布的数据修改为按行展开平铺,充分打平数据,利用 HBase 按行自动分片的机制来达到负载均衡的状态。第一方面主要是从业务层面对不合理使用的情况进行人工干预。今天主要着重介绍第二方面。


  • tsdb-meta 表 Schema 改造


前文大体介绍了表结构改造的思路,避免单行数据过大导致热点问题。我们将监控对象和监控指标的名称信息一起作为行键,只保留一列用于存储指标的其余信息,避免了因单行数据过大导致的热点问题。


表 2 优化后的 tsdb-meta 表



  • 预分区


tsdb-meta 表优化后,我们发现生产环境存储数据的 tsdb-data 表也存在热点问题。tsdb-data 是用来存储监控指标数值的表,生产环境是按时间跨度进行分表,每两天的数据存储在一张表中。数据的行键由数据 hash 后的特征变量 ts_uid 和时间基准 timestamp_base 组成,利用 HBase 存储时按行键的字典顺序排序的特点,将不同的监控指标的数据散列到不同的 Region,相同监控对象的指标数据顺序排列,达到优化查询的效果。由于 tsdb-data 表的日常访问量基数较大,当某个监控对象拥有的指标数量高于平均水平,那么该监控对象的监控指标很大概率会被分配到相同的 Region,导致该 Region 过大,进成为热点,集群会分裂过大的 Region 来维持负载均衡的状态。频繁的分裂操作会占用大量资源,影响 RegionServer 的吞吐量。为解决因 Region 过大导致的热点,我们采用了对数据表进行预分区的方法。


在对 tsdb-data 表进行预分区时,我们发现只通过指定 Region 数量来实现预分区的效果并不理想,因为会出现实际写入量与槽位分配不均的问题。HBase 数据表是按照行键的字节空间均匀划分而不是按照实际存储的数据量进行划分。如下图所示,图中红色方块代表实际存储的数据,白色的方块代表无实际数据的行。



图 3 原始 Region 预分区


如上图,虽然数据表已经按照行键的字节空间划分成 3 个 Region 了,但是明显 Region 3 中实际存储的数据量远大于 Region 1 和 Region 2。这种情况下 Region 3 有成为热点的可能性。为了改善这种情况,Noah-TSDB 结合了生产环境中的 tsdb-data 表按等间隔时间跨度分表的特点,决定参照历史表的使用情况对新表进行预分区。根据生产环境实际产生的行键和预期的分区大小计算出 Region 分界值,然后根据分界值将表划分成实际水位相近的 Region,这样虽然每个 Region 的槽位大小不一样,但是每个 Region 实际存储的数量是相当的,进一步降低产生热点的风险。



图 4 优化后的 Region 预分区

如何合理的设置 Region 数量

在前文介绍的预分区策略中,除了需要参考生产环境的实际使用情况外还需要根据机器资源和分裂阈值等系统参数来预估合适的 Region 大小,Region 大小确定后,我们可以预估出整体的 Region 数量。那么如何判断当前集群是否能够承载调整后的 Region 数量呢?如果 Region 的数量不合理有哪些危害呢?在讨论 Region 数量对集群的影响之前,我们先了解一些基础知识:


  1. 在 HBase 的数据写入流程中,数据是先写到 Memstore(写缓存)排序,然后异步 Flush 追加到 HFile 中。一个 Region 中的多个列族对应多个 Memstore,Memstore Flush 的最小单位是 Region。

  2. 当一个 RegionServer 中所有 Memstore 的大小总和达到阈值 hbase.regionserver.global.memstore.upperLimit * hbase_heapsize 会触发 Memstore Flush。根据 Memstore 从大到小依次 Flush,直至 MemStore 内存使用量低于阈值 hbase_heapsize * hbase.regionserver.global.memstore.lowerLimit。

  3. HBase 会定期 Flush Memstore 来保障 Memstore 不会长时间没有持久化。为避免所有的 MemStore 在同一时间都进行 Flush 导致的问题,定期的 Flush 操作有随机延时。


综上可知,一方面由于同一个 RegionServer 共享 Memstore,Region 数量过多会导致 Memstore Flush 的频率变快,产生的 HFile 变多,HBase 持续的进行 Compaction,引发合并风暴。另一方面由于 HBase 定期 Flush Memstore,每次执行 Flush 需要将每个 Region 的每个列族对应的 Memstore 写入文件并存到 HDFS, Region 数量越多,每次需要一起处理的文件数量就越大,即使存在随机时延机制,短时间内文件的创建和数据的迁移较多也会加大集群负载,可能引起快照超时、客户端超时和批量加载超时,降低 TSDB 系统性能。因此 Region 数量过多会降低系统吞吐量。


Region 数量过少也会降低系统性能。当数据量不变的情况下,由于 Region 数量过少导致单个 Region 过大,每个 Region 处理的写入请求数偏高,当 Flush 的速度慢慢被写入速度追上并赶超时,就会堵塞写入,影响 RPC,进而影响 HBase 的整体写入和查询,降低系统的吞吐量。


Region 数量设置不合理,会降低 TSDB 系统整体性能与可靠性,一般推荐的单个 RegionServer 管理的 Region 数量计算方法如下:


#{Region} = (RS memory)*(total memstore fraction)/((memstore size)*(# {column families}))
复制代码


举个例子,如果 RegionServer 的参数如下:


  1. Java Heap Size of HBase RegionServer in Bytes 设置的是 20G

  2. hbase.regionserver.global.memstore.upperLimit 是 0.4

  3. hbase.hregion.memstore.flush.size 是 128M

  4. 多个表的列族个数共 2 个


那么 #{Region} = 20 * 1024 * 0.4/ (128 * 2) = 32。这个公式是在假设所有的 Region 都在以相同的速率写的前提下,如果实际只有部分 Region 在写入数据,结果可以根据比例、结合业务进行调整。例如 Noah-TSDB 的场景下,数据是按照时间分表,一般两天的数据存在一张数据表中,数据的写入都集中在最近的一张表,因此实际写入活跃的 Region 数量远小于 Region 的总数量,所以实际每个 RegionServer 管理的 Region 的数量大约是通过上述公式直接计算结果的 3 倍左右。


预估出整体的 Region 数量和单个 RegionServer 管理的 Region 数量后,就可以合理的进行容量规划,在集群调整的时候预估需要的机器资源。

总结

上面就是今天介绍的全部内容了,给大家简单分享了一些使用 HBase 的实践经验。其实在实际使用时我们也发现了 HBase 过重,运维成本较高等问题,也在持续的进行调研和架构升级,大家有什么好的建议欢迎不吝赐教。另外文中如果有理解不到位或者偏差的地方,欢迎大家指正。

作者简介

张洋洋,百度高级研发工程师。负责百度智能运维产品(Noah)的分布式时序数据库和通用配额管理平台的设计研发工作,在分布式存储和配额管理方向有广泛的实践经验。


本文转载自公众号 AIOps 智能运维(ID:AI_Ops)


原文链接:https://mp.weixin.qq.com/s/M_teW4hNNaLWbWghA02j9A


2019-05-07 08:005478

评论

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

数据库表数据量大读写缓慢如何优化(4)【分库分表】

我爱娃哈哈😍

数据库 架构

极客时间产品训练营第三周作业

云随心

产品 作业 产品训练营

厚积薄发!华为云7篇论文被AAAI收录,2021年AI行业技术风向标看这里!

华为云开发者联盟

人工智能 卷积网络 远程监督 域泛化 油气储集层收集

程序员成长第一篇:机会与趋势

石云升

28天写作 2月春节不断更 机会与趋势

说说常常被研发忽略的原型模式

后台技术汇

28天写作 2月春节不断更

产品经理训练营第0期-第三次作业

孙行者

第0期 产品经理训练营 问题

挖矿系统APP源码搭建

luluhulian

Idea工具的各种查找快捷键

小马哥

IntelliJ IDEA 七日更 2月春节不断更

华为18A架构师共享:Netty+Redis+zookeeper+高并发技术栈

996小迁

redis zookeeper 架构 Netty 高并发

SpringCloud 从入门到精通15---Sentinel搭建和服务监控

Felix

EXCEL数据如何去重? Python:这事我比你熟

智分析

Python

产品训练营 第三次作业

Wangyunnfei

使用pgBackRest并行归档解决wal堆积问题

PostgreSQLChina

数据库 postgresql 开源 开源社区

用RabbitMQ了好几年之后,我总结出来5点RabbitMQ的使用心得

四猿外

MQ RabbitMQ 消息队列

官宣了!Apache ECharts 毕业成为 Apache 软件基金会顶级项目!

百度Geek说

百度 基金会

即构自研海量有序数据网络MSDN,构建全球可靠的多云通讯链路

ZEGO即构

OpenAI将k8s扩展至7500个节点以支持机器学习;Graph Diffusion Network提升交通流量预测精度

京东科技开发者

区块链 开源

前端面试必备ES6全方位总结

我是哪吒

程序员 面试 大前端 ES6 2月春节不断更

玩转IDEA项目结构Project Structure,打Jar包、模块/依赖管理全搞定

YourBatman

Module IntelliJ IDEA Project Structure

Kafka基础简介

架构精进之路

kafka 七日更 28天写作 2月春节不断更

MySQL安装教程&问题解决

Mars

MySQL 运维

利用 Python 分析了某化妆品企业的销售情况,我得出的结论是?

JackTian

Python 数据分析 数据可视化 化妆品 2月春节不断更

即日起 Jira、Confluence 正式停售本地版,中国客户将无法购买

万事ONES

项目管理 开发者 研发管理 团队协作 CTO

Linux-Lab 入门:使用开发板

贾献华

嵌入式 Linux Kenel 开发板 arm boot

日记 2021年2月2日(周二)

Changing Lin

个人感悟 2月春节不断更

Elasticsearch 写一致性原理

escray

七日更 28天写作 死磕Elasticsearch 60天通过Elastic认证考试 2月春节不断更

《我想进大厂》之Zookeeper夺命连环9问

艾小仙

zookeeper

挖矿区块链_什么是挖矿 带你详细了解挖矿基础知识

v16629866266

托管节点池助力用户构建稳定自愈的 Kubernetes 集群

阿里巴巴云原生

Docker 容器 运维 云原生 k8s

华为云FusionInsight助力宇宙行打造金融数据湖新标杆

华为云开发者联盟

数据湖 云原生 存储 FusionInsight 华为云

ICE暴雪正悄悄崛起

DT极客

百度智能监控场景下的HBase实践_大数据_张洋洋_InfoQ精选文章