Hbase Schema 模型设计注意事项及示例

1、Hbase 数据模型概述

        HBase的数据模型也是由表组成,每一张表里也有数据行和列,可是在HBase数据库中的行和列又和关系型数据库的稍有不一样。数据库

        表(Table): HBase会将数据组织成一张表,表名必须是能用在文件路径里的合法名字,由于HBase的表是映射成hdfs上面的文件,Hbase的表及表中的数据都是以二进制字节进行存储;
        行(Row): 在表里面,每一行都是以一个行键(Row Key)来进行惟一标识的,行键并无什么特定的数据类型,以二进制的字节来存储。
        列族(Column Family): 列族是Hbase Schema定义的一部分,列不是,列族一旦肯定后,就不能轻易修改,由于它会影响到HBase真实的物理存储结构,可是列族中的列标识(Column Qualifier)以及其对应的值能够动态增删。表中的每一行都有相同的列族,可是不须要每一行的列族里都有一致的列标识(Column Qualifier)和值,因此说是一种稀疏的表结构,这样能够必定程度上避免数据的冗余;
        列标识(Column Qualifier): 列族中的数据经过列标识来进行映射,即为一个键值对,Column Qualifier就是Key,值是value;
        单元(Cell): 每个行键,列族和列标识共同组成一个单元,存储在单元里的数据称为单元数据;
        时间戳(Timestamp): 默认下每个单元中的数据插入时都会用时间戳来进行版本标识。读取单元数据时,若是时间戳没有被指定,则默认返回最新的数据,写入新的单元数据时,若是没有设置时间戳,默认使用当前时间。每个列族的单元数据的版本数量都被HBase单独维护,默认状况下HBase保留3个版本数据。数组

        

        Hbase必定程度上又能够当作一个多维度的Map模型去理解它的数据模型。即以行键(Row Key),列标识(column qualifier),时间戳(timestamp)标识的有序Map数据结构的数据库,具备稀疏,分布式,持久化,多维度等特色。正以下图,一个行键映射一个列族数组,列族数组中的每一个列族又映射一个列标识数组,列标识数组中的每个列标识(Column Qualifier)又映射到一个时间戳数组,里面是不一样时间戳映射下不一样版本的值,可是默认取最近时间的值,因此能够当作是列标识(Column Qualifier)和它所对应的值的映射。用户也能够经过HBase的API去同时获取到多个版本的单元数据的值。Row Key在HBase中也就至关于关系型数据库的主键,而且Row Key在建立表的时候就已经设置好,用户没法指定某个列做为Row Key。服务器

        

        HBase也能够当作是一个相似Redis那样的Key-Value数据库。以下图,当你要查询某一行的全部数据时,Row Key就至关于Key,而Value就是单元中的数据(列族,列族里的列和列中时间戳所对应的不一样版本的值);用户要查询指定行里某一条单元数据时,HBase会去读取一个数据块,里面除了有要查询的单元数据,可能同时也会获取到其它单元数据,由于这个数据块还包含着这个Row Key所对应的其它列族或其它的列信息,这些信息实际也表明着另外一个单元数据,这也是HBase的API内部实际的工做原理。数据结构

        

        HBase提供了丰富的API接口让用户去操做这些数据。主要的API接口有3个,Put,Get,Scan。Put和Get是操做指定行的数据的,因此须要提供行键来进行操做。Scan是操做必定范围内的数据,经过指定开始行键和结束行键来获取范围,若是没有指定开始行键和结束行键,则默认获取全部行数据。分布式

        在HBase表设计中最重要的就是定义Row-Key的结构,要定义Row-Key的结构时要紧密结合实际业务应用场景,对这张表出现什么样的读写场景。除此以外,在设计表的时候咱们也应该要考虑HBase数据库的一些特性。
        1. HBase中表的索引是经过Key来实现的
        2. 在表中是经过Row Key的字典序来对一行行的数据来进行排序的,表中每一块区域的划分都是经过开始Row Key和结束Row Key来决定的。
        3. 全部存储在HBase表中的数据都是二进制的字节,并无数据类型。
        4. 原子性只在行内保证,HBase表中并无多行事务。
        5. 列族(Column Family)在表建立以前就要定义好
        6. 列族中的列标识(Column Qualifier)能够在表建立完之后动态插入数据时添加。性能

2、Hbase 表设计示例优化

业务场景描述

        设计一张表,用来保存微博上用户互粉的信息。加密

读场景业务要求
        1. 每一个用户都关注了谁
        2. 用户A有没有关注用户B
        3. 谁关注了用户Aspa

写场景业务要求
        1. 用户关注了另外一个用户
        2. 用户取消关注某个用户.net

初始表结构设计方案

        每一行表明着某个用户和全部他所关注的其它用户。这个用户ID做为Row Key,一个列族follows,而每个列标识(Column Qualifier)就是这个用户所关注的其余用户在列族里的序号,单元数据就是这个用户所关注的其余用户的用户ID。在这种表结构的设计下,“每一个用户都关注了谁”这个问题很好解决,但对于“用户A有没有关注用户B”这个问题在列不少的时候,须要遍历A用户所在Row的全部单元数据去找到用户B,这样的开销会十分大。而且当添加新的被关注用户时,由于不知道给这个新用户分配什么样的列族序号,须要遍历整个列族中的全部列找出最后一个列,并将最后一个列的序号+1给新的被关注用户做为列族内的序号,这样的开销也十分大。

       

改进列族序号方案

        在初始方案的基础上,添加一个counter记录列族中全部列的总数量,当添加新的被关注用户时,这个新用户的序号就是counter+1。可是当要取消关注某个用户时,同样得遍历全部的列数据,并且最大的问题是在于HBase不支持事务处理,这种经过counter来添加被关注用户的操做逻辑得写在客户端中。

        

        

改进列表识方案

        列标识(Column Qualifier)存储的时候是二进制的字节,能够存储任何数据,并且列标识仍是动态增添的,基于这个特性咱们再改进表的设计,以下图。此次以被关注的用户ID作为列标识(Column Qualifier),而后单元数据能够是任意数字,好比所有统一成1。在这种表结构的设计下,添加新的被关注者,以及取消关注都会变得很简单。可是对于读场景中,谁关注了用户A这个问题,由于HBase数据库的索引只创建在Row Key上,这里不得不扫描全表去统计全部关注了用户A的用户数量。

        

综合优化方案

        将Row Key设计成“followerID+followedID”的形式,好比:“Jame+Emma”,这里的Row Key值就表明着Jame关注了Emma(其实这里应该是“Jame的ID+Emma的ID”,只是为了解释方便而直接用名字),同时包含了关注者和被关注者两个信息;还须要注意的一点就是列族的名字被设计成只有一个字母f,这样设计的好处就是减小了HBase对数据的I/O操做压力,同时减小了返回到客户端的数据字节,提升响应速度,由于每个返回给客户端的KeyValue对象都会包含列族名字。同时将被关注人的用户名称也保存在了表中做为Column Qualifier,这样作的好处就是节省了去用户表查找用户名的资源。在这种表结构设计下,“用户A取消关注某个用户B”,“用户A有没有关注用户B?”的业务处理就会变得简单高效。

        

        

RowKey加密处理

        在实际的生产环境中,还须要将Row Key使用MD5加密,一方面是使Row Key的长度都一致,能提升数据的存取性能。

        

设计要点总结

  • Row Key是HBase表结构设计中很重要的一环,它设计的好坏直接影响程序和HBase交互的效率和数据存储的性能。
  • Base的表结构比传统关系型数据库更灵活,你能存储任何二进制数据在表中,并且无关数据类型。
  • 在相同的列族中全部数据都具备相同的操做模式
  • 主要是经过Row Key来创建索引
  • 以纵向扩张为主设计的表结构能快速简单的获取数据,但牺牲了必定的原子性,就好比上文中最后一种表结构;而以横向扩张为主设计的表结构,也就是列族中有不少列,好比上文中第一种表结构,能在行里面保持必定的原子性。
  • HBase并不支持事务,全部尽可能在一次API请求操做中获取到结果
  • 对Row Key的Hash优化能得到固定长度的Row Key并使数据分布更加均匀一些,而不是集中在一台服务器上,可是也牺牲了必定的数据排序和读取性能。
  • 能够利用列标识(Column Qualifier)来存储数据。
  • 列标识(Column Qualifier)名字的长度和列族名字的长度都会影响I/O的读写性能和发送给客户端的数据量,因此它们的命名应该简洁。

参考资料

http://0b4af6cdc2f0c5998459-c0245c5c937c5dedcca3f1764ecc9b2f.r43.cf2.rackcdn.com/9353-login1210_khurana.pdf

https://blog.csdn.net/ymh198816/article/details/51244911

相关文章
相关标签/搜索