hbase简单案例 基于hbase简单实际应用案例_hbase简单案例


    大数据、NoSql听着挺高大上的,主要是传统的数据库已经无法满足业务数据的增长,于是有了分布式存储,以此来满足数据的存储与查询性能。

关于HBase的使用经验主要是我在参与京东的统一监控平台而来的,下面从几个方面来介绍一下:

一、使用背景:

当时我们决定在监控平台中增加JVM的监控,每隔10秒采集一次JVM实例的运行时信息,比如CPU的占用率,堆内存大小,新生代GC次数,老年代GC次数,GC占用时间,活动线程数,守护线程数等jvm运行时信息。线上当时接入JVM监控实例有3000多个,每天产生的数据差不多1亿条,jvm监控数据的用法主要有两个方面,一是用于分析报警,二是用于前端展示用于观察线上应用实例的运行状况,数据有效期只存储最近三个月的,以下是在使用过程中的一些经验总结。

经验总结、

1、首先是rowkey的设计,这一点是很容易让人理解的,因为对于分布式key/value存储来说,往往是通过key来判断存储位置位置的,所以最好的结果就是让rowkey均匀存储在不同的node上,这样存储与查询的性能就会好很多,避免产生热点故障。

2、ETL很重要,规划数据的有效存储时间是很重要的,特别是对于监控数据来说,因为是基于时间序列的来存储的,所以只存储了最近三个月的数据,数据的过期时间就设置为3个月,因为3个月对于监控数据来说足够了,操作方式如下:

创建表的时候,可以通过HColumnDescriptor.setTimeToLive(int timeToLive)设置表中数据的存储生命期,过期数据将自动被删除,例如如果只需要存储最近90天的数据,那么可以设置setTimeToLive(90 * 24 * 60 * 60).

3、预分区(预先创建一些空的regions,这样当数据写入HBase时,会按照region分区情况,在集群内做数据的负载均衡)可以有效提高系统的运行稳定性,由于过期时间设置为3个月,每天的数据量可以评估一个大概,所以3个月的数据大概需要多少存储空间也是可以做一个粗略的计算的,根据计算结果来进行预分区,可以避免数据在存储过程中进行自动扩容,自动扩容容易造成当前数据的存储与查询请求暂停,导致hbase运行不稳定,也容易导致接入hbase的应用运行不稳定。

4、数据版本(Timestamp 是区分不同版本 Cell 的索引,64 位整型。不同版本的数据按照时间戳倒序排列,最新的数据版本排在最前面),由于hbase没有所谓的数据更新,采用的数据版本的存储机制,所以所谓同一行的数据可以有多个版本,当然对于我们当前监控的业务来说,取最新版本即可,所以我们可以将数据的版本数量设置为1个,对于数据的更新不太关注,如果日志信息的存储一样,这种业务数据往往只会写入一次,而不会有更新,设置数据存储的版本数量可以提高数据的查询效率并且可以节约存储空间,设置版本的数量如下:

创建表的时候,可以通过HColumnDescriptor.setMaxVersions(int maxVersions)设置表中数据的最大版本,如果只需要保存最新版本的数据,那么可以设置setMaxVersions(1)。

5、对于key(row key和column key)的设计来说,可以把业务key转换成等长的数字来存储,这样可以有效节约存储空间,对于数据存储空间的计算也要容易得多,我们都知道数字的存储空间占用的字节数量是固定的,而字符串占用的存储空间是不定的,当然这种转换后的代价就是在存储与查询时的代码实现要多一层的转换,但相对换来的优点,这点代价是很小的。当前业务对应的key的设计模型如下

row key=监控点key + ip +实例编号+ 时间(时间为年月日小时分秒),其中监控点key是由用户自己定义的,所以长短不一,最长不超过50个字符,所以在实际业务中的这个监控点key采用转换后的等长数字进行存储,于是就有了下面的row key设计:

row key=监控点key编码(数字) + ip +实例编号+ 时间。

由于在实际业务场景中,用户总是查询最新的监控数据,所以rowkey中的时间部分=Long.MAX_VALUE - timestamp,因为hbase的row key是按照字典序存储,这样最新的数据总是排在最前面了,有利于提高查询速度。

在查询一个jvm的实例在一定时间范围内的监控结果即可以通过指定

startRowKey(监控点key编码(数字) + ip +实例编号+ 开始时间)和endRowKey(监控点key编码(数字) + ip +实例编号+ 结束时间),在这个范围内进行扫描。

由于

column key就是性能指标了,性能指标也是采用的转换后的对应的数字编码进行存储的。

6、只用一个列簇(Column Family),一般情况下都使用一个列簇,目前Hbase并不能很好的处理超过2~3个column family的表。因为某个column family在flush的时候,它邻近的column family也会因关联效应被触发flush,最终导致系统产生更多的I/O。

7、在提交数据时,采用批量提交,可以有效提高存储速度。