Habse中Rowkey的设计原则——通俗易懂篇

Hbase的Rowkey设计原则

一、 Hbase介绍

HBase -> Hadoop Database,HBase是Apache的Hadoop项目的子项目。HBase不同于一般的关系数据库,它是一个适合于非结构化数据存储的数据库。另一个不同的是HBase基于列的而不是基于行的模式,主要用来存储非结构化和半结构化的松散数据(列存NoSQL数据库)

二、 设计原则

    2.1 Rowkey长度原则

Rowkey是一个二进制码流,Rowkey的长度被很多开发者建议设计在10-100个字节,不过建议是越短越好,不要超过16个字节。

原因如下:

(1)数据的持久化文件HFile中是按照KeyValue存储的,如果Rowkey过长比如100个字节,1000万列数据光Rowkey就要占用100*1000万=10亿个字节,将近1G数据,这会极大影响Hfile的存储效率;

(2)MemStore将缓存部分数据到内存,如果Rowkey字段过长内存的有效利用率降低,系统将无法缓存更多的数据,这会降低检索效率,因此Rowkey的字节长度越短越好。

(3)目前操作系统一般都是64位系统,内存8字节对齐,空值在16个字节,8字节的整数倍利用操作系统的最佳特性。

2.2 Rowkey散列原则

如果Rowkey是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将Rowkey的高位作为散列字段,由程序循环生成,低位放时间字段,这样将提高数据均衡分布在每个Regionserver实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息将产生所有新数据都在一个 RegionServer上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别RegionServer,降低查询效率。

2.3 Rowkey唯一原则

必须在设计Rowkey上保证其唯一性。

2.4 访问hbase table中的行,只有三种方式:
    1 通过单个row key访问
    2 通过row key的range
    3 全表扫描

Hbase API文档:?overview-summary.html

 HBase的查询实现只提供两种方式:

    1、按指定RowKey获取唯一一条记录,get方法(org.apache.hadoop.hbase.client.Get)
    2、按指定的条件获取一批记录,scan方法(org.apache.hadoop.hbase.client.Scan)

实现条件查询功能使用的就是scan方式,scan在使用时有以下几点值得注意:

1、 scan可以通过setCaching与setBatch方法提高速度(以空间换时间);
2、 scan可以通过setStartRow与setEndRow来限定范围。范围越小,性能越高。
    通过巧妙的RowKey设计使我们批量获取记录集合中的元素挨在一起(应该在同一个    Region下),可以在遍历结果时获得很好的性能。
3、 scan可以通过setFilter方法添加过滤器,这也是分页、多条件查询的基础。

三、 应用场景

   3.1  针对事务数据Rowkey设计

事务数据是带时间属性的,建议将时间信息存入到Rowkey中,这有助于提示查询检索速度。对于事务数据建议缺省就按天为数据建表,这样设计的好处是多方面的。按天分表后,时间信息就可以去掉日期部分只保留小时分钟毫秒,这样4个字节即可搞定。加上散列字段2个字节一共6个字节即可组成唯一 Rowkey。如下图所示:

事务数据Rowkey设计

 

第0字节

 

第1字节

 

第2字节

 

第3字节

 

第4字节

 

第5字节

 

 

散列字段

 

时间字段(毫秒)

 

扩展字段

 

0~65535(0x0000~0xFFFF)

 

0~86399999(0x00000000~0x05265BFF)

 

 

 

 

这样的设计从操作系统内存管理层面无法节省开销,因为64位操作系统是必须8字节对齐。但是对于持久化存储中Rowkey部分可以节省25%的开销。也许有人要问为什么不将时间字段以主机字节序保存,这样它也可以作为散列字段了。这是因为时间范围内的数据还是尽量保证连续,相同时间范围内的数据查找的概率很大,对查询检索有好的效果,因此使用独立的散列字段效果更好,对于某些应用,我们可以考虑利用散列字段全部或者部分来存储某些数据的字段信息,只要保证相同散列值在同一时间(毫秒)唯一。

针对统计数据的Rowkey设计

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyzpwf.html