HBase 2.0 在时序数据存储方向的应用

阅读数:136 2019 年 9 月 25 日 23:48

HBase 2.0在时序数据存储方向的应用

1HBase 生态介绍

HBase 是基于 HDFS 存储的分布式 Nosql 数据库,具有易于线性拓展和高并发随机实时读写能力,目前已成为大部分公司基础存储架构中不可缺少的组成部分。经过多年发展,HBase 生态也日益丰富,目前 HBase 主要生态包括以下几个方向:

1.1 时序数据:

OpenTSDB 是基于 HBase 的时序数据库,具有海量数据实时读写能力和聚合计算能力。多被应用在实时监控领域和对业务趋势的实时分析;

1.2 Cube 分析:

Kylin 是 HBase 生态中 Cube 分析的项目,将数据进行预计算后存储在 HBase 中,对用户提供 SQL 接口,可为用户提供亚秒级多维度分析;

1.3 SQL On HBase:

Phoenix 是 HBase 上的 SQL 组件,支持标准 SQL 和 JDBC API,用户可像使用关系型数据库的操作方式操作 HBase 数据。同时支持二级索引功能,大大提升查询速度;

1.4 时空数据:

GeoMesa 是基于 HBase 的时空数据组件,可提供大规模分布式地理空间数据查询和分析。

2 贝壳 HBase 的生态介绍

在贝壳已经有基于 Kylin 的实时分析引擎;基于 OpenTSDB 的集群监控信息存储;基于 Phoenix 的 SQL 组件,支持标准 SQL 语法,可通过 JDBC 方式连接进行操作,可建立索引对查询加速。

1)基于 Kylin 的实时分析服务(已建立完成)
2)基于 Opentsdb 的集群监控信息存储(已建立完成)
3)基于 Phoenix 的 SQL 组件(已建立完成)
4)基于 GeoMesa 的时空数据(暂未建设,需求收集中)

3HBase 时序数据存储目前情况

从 2018 年 8 月份开始我们开始使用 OpenTSDB 来存储集群监控数据,目前已存储 Hadoop 和 HBase 集群 Metrics 数据以及集群各个节点基础信息数据。这套时序存储由 5 个节点的 HBase 集群和 3 个节点的 OpenTSDB 搭建而成,HBase 平均每秒处理 3W 请求,最大每秒处理 10W+ 请求。

4HBase 2.0 新特性介绍

2018 年 8 月份我们开始对 HBase2.0 版本进行调研,希望能够使用更少的资源,获得更高的性能,通过一系列尝试最终仅使用原来一半的内存达到了预期效果。那么为什么 HBase2.0 能够使用更少资源获得更高的性能呢?这得益于 2.0 版本的一些新特性,现在我来为大家介绍一下:

4.1 AssignmentManager V2(AM V2)

AM 负责维护 Region 分配过程中的状态,AM V2 基于 Procedure V2 存储状态,去除了对 Region 分配过程对 zookeeper 的依赖,Region 状态直接通过心跳汇报给 Master,降低了 RIT 的出现概率。改特性默认开启;

4.2 Offheapping of Read/Write Path

将数据缓存和 memstore 放到堆外,堆内只存储一级缓存中的索引和 bloom filter 数据;减少了 GC 次数提升了稳定降低延迟;

4.3 In-Memory Compaction

在 HBase1.x 版本中,memstore 达到 flush 阀值时,直接进行 flush 将数据写到磁盘;引入该功能后,memstore 中数据会在内存中进行多次 compaction 后再 flush,减少了写磁盘次数并能减少写放大问题;

4.4 NettyRpcServer

使用 Netty 的高并发能力,大大提升了 HBaseRPC 的吞吐能力,降低了延迟。该特性默认开启;

4.5 Async Client

Async Client 利用异步 RPC 机制,大大高 Client 端请求并发量,扩大吞吐;

4.6 RS Group

通过给 RegionServer 分组,很好地实现了资源隔离,也可以按需分配不同性能机器进行数据存储,例如冷数据存在 HDD 磁盘 RS 上,温数据存在 SDD 和 HDD 混布 RS 上,热数据存在全 SSD RS 上;

4.7 Support for MOB

MOB 特性使得 HBase 支持存储小于 10MB 的中等媒体对象数据,相比原有直接存储大对象,其读写效率更高。

5OpenTSDB 介绍

OpenTSDB 是一个基于 HBase 的可拓展时序数据读写服务,可通过 HTTP API 的方式对数据进行读写。我们使用的 OpenTSDB 版本是最新的 2.3.1,为了达到更好的读写性能,我们采用了读写分离的部署方案。接下来我给大家介绍一下值得注意的点和配置:

1)初始化表时,要对表进行预切分

默认初始化的表都只有一个分区,造成大量请求压到一个节点上造成宕机;

2)开启 uid 随机映射到 metrics,使得数据均匀分布到各 region 上:

复制代码
1tsd.core.uid.random_metrics=true

3)开启 mate 数据实时创建追踪,以便使用 tag_values 函数获取 metric 指定 tag 值集合:

复制代码
1tsd.core.meta.enable_realtime_uid=true
2tsd.core.meta.enable_tsuid_tracking=true
3tsd.core.meta.enable_realtime_ts=true

注意:开启该功能后,对 HBase 的访问量会激增。

4)设置 tag 允许字符,解决非字符问题:

复制代码
1tsd.core.tag.allow_specialchars = ", ;[]:/@"

6 关键配置

6.1 HBase 相关配置

前面介绍了很多特性,有些是默认开启的,有些需要额外配置。我们主要使用了 Offheapping of Read/Write Path 和 In-Memory Compaction 两个特性,下面是相关的配置:

1)hbase-env.sh 文件内配置:

设置对外内存大小

复制代码
1export HBASE_OFFHEAPSIZE=30G

regionserver JVM 参数设置,建议使用 G1 垃圾回收,可控制最长暂停时间

复制代码
1export HBASE_REGIONSERVER_OPTS="$HBASE_REGIONSERVER_OPTS -XX:+UseG1GC -Xms30g -Xmx30g -XX:+UnlockExperimentalVMOptions -XX:MaxGCPauseMillis=100 -XX:-ResizePLAB -XX:+ParallelRefProcEnabled -XX:+AlwaysPreTouch -XX:G1HeapWastePercent=3 -XX:InitiatingHeapOccupancyPercent=35 -XX:G1MixedGCLiveThresholdPercent=85 -XX:G1NewSizePercent=4 -XX:G1MaxNewSizePercent=10"

2)hbase-site.xml 文件配置

复制代码
1<!-- Offheap Read Path Setting -->
2<property>
3 <name>hbase.bucketcache.ioengine</name>
4 <value>offheap</value>
5</property>
6
7<property>
8 <name>hbase.bucketcache.size</name>
9 <value>17408</value>
10 <description> 堆外缓存 (L2 Cache) 大小,单位 MB</description>
11</property>
12
13<property>
14 <name>hfile.block.cache.size</name>
15 <value>0.2</value>
16 <description> 堆上缓存 (L1 Cache) 大小,占堆大小的 20%</description>
17</property>
18
19<!-- Offheap Write Path Setting -->
20<property>
21 <name>hbase.regionserver.offheap.global.memstore.size</name>
22 <value>10240</value>
23 <description> 堆外 memstore 大小,单位 MB</description>
24</property>

3)In-Memory Compaction 配置

有两种设置方式:

全局开启

在 hbase-site.xml 添加如下配置:

复制代码
1<property>
2 <name>hbase.hregion.compacting.memstore.type</name>
3 <value>NONE|BASIC|EAGER|ADAPTIVE</value>
4 <description></description>
5</property>

注意:使用这种配置,会导致原有其他表的 region 无法使用,建议采用第二种配置

针对表开启

复制代码
1create '<tablename>',
2{NAME => '<cfname>’, IN_MEMORY_COMPACTION =>'<NONE|BASIC|EAGER|ADAPTIVE>'}

6.2 In-Memory Compaction 策略介绍

1)BASIC 策略
一个低开销方案,它将 pipline 中的所有 segment 索引合并到一个平坦索引中。他不会清理冗余,以避免 cell 数据拷贝
2)EAGER 策略
一个高成本 / 高回报方案,即可以平衡索引也可以消除冗余,并清理多余版本,需要拷贝数据会有额外开销,适用于写入较多场景
3)ADAPTIVE 策略
首先对待合并 segment 进行评估,方法是在已经统计过不重复 key 个数的 segment 中,找出 cell 个数最多的一个,然后用这个 segment 的 numUniqueKeys/getCellsCount 得到一个比例,如果比例小于设定的阀值则使用 EAGER 策略,否则使用 BASIC 策略

7OpenTSDB 相关配置

在 opentsdb.conf 文件中配置

复制代码
1 tsd.core.tag.allow_specialchars = ", ;[]:/@"
2 tsd.core.uid.random_metrics=true
3 tsd.core.meta.enable_realtime_uid=true
4 tsd.core.meta.enable_tsuid_tracking=true
5 tsd.core.meta.enable_realtime_ts=true

8 经验总结

经过一段时间的使用我们遇到过一些问题,在这里和大家分享下:

1)HBase 2.0 默认使用 NettyRpcServer,会由于客户端(OpenTSDB)处理结果速度慢造成 Netty buffer 堆积 ,导致 RegionServer 频繁 FullGC,然后宕机;
解决方案:引入社区 Patch,对缓冲区大小进行限制,缓冲区默认大小 2GB,我们最终设置 6GB

2)Hbase 2.0 中 hbck 只能进行检查不能进行修复,一旦出现 RIT 问题不易解决;
解决方案:出现 RIT 问题可通过以下两种方式进行解决:

  • 在 hbase shell 中使用 assign 命令重新分配指定 region,如果无效采用第二种方式;
  • 使用 hbck2 进行修复,有些修复后仍未解决时重启 Master,问题得到解决。

3)当 RegionServer 重启后,集群不会自动 balance,手动调用 balancer 命令也无效,即使其他节点每秒请求几万的情况下也不会进行 balance,且日志无异常。
解决方案:切换 HMaster 节点,再手动调用 balancer 命令。

作者介绍:
牛魔(企业代号名),贝壳找房 HBase 负责人。

本文转载自公众号贝壳产品技术(ID:gh_9afeb423f390)。

原文链接:

https://mp.weixin.qq.com/s/jNqT2rwd6yFl9A4yLACcZQ

评论

发布