目次
1.4.1 模式创建
1.4.2 Rowkey设计
1.4.3 列族定义
1.4.3.1 可设置的数据块大小
1.4.3.2 数据块缓存
1.4.3.3 布隆过滤器
1.4.3.4 数据压缩
1.4.3.5 单元时间版本
1.4.3.6 生存时间
1.4.4 模式设计实例
1.4.4.1 实例1:动物分类
1.4.4.2 实例2:店铺与商品
1.4.4.3 实例3:网上商城用户消费记录
1.4.4.4 实例4:微博用户与粉丝
1.4.4.5 小结
本文参考于学校《HBase应用于开发》课本
前言
本节将介绍怎样设计HBase的模式(Schema),将对比HBase与RDBMS的模式设计的异同,重点介绍模式设计中的两个要点——Rowkey和Column Family,并联合4个实例介绍怎样进行HBase的模式设计。
数据库的模式设计并不是一个新概念,在关系型数据库之前,模式设计的范式已经存在。实在,只要是可以称为“数据库”的系统,都存在模式设计的问题。作为一种典型的列式存储数据库,HBase的模式设计同样非常重要。HBase的模式设计和传统数据库的模式设计存在什么样的差异,更需要关注的是哪些关键属性,怎样设计这些属性,怎样通过更直观、清楚地认识模式设计,这些都是本节解说的要点。
1.4.1 模式创建
要知道HBase的表怎样创建,起首需要相识HBase的模式布局,包罗表、Rowkey、列族、Timestamp(时间版本)。实在模式是一个三维有序布局,前面三个维度确定一行数据。
HBase的模式差别于关系型数据库(RDBMS),HBase与RDBMS的区别在于:HBase的单元格(cell)所在的行是有序的,其列(Qualifier)在所属列族(Column Famliy)存在的环境下,可以通过客户端自由添加,如表 1.4.1所示。
表 1.4.1 HBase表设计模式与RDBMS对比
属性
| HBase
| RDBMS
| 数据类型
| 只有字符串
| 丰富的数据类型
| 数据操作
| 简朴的增编削查,不支持Join
| 各种各样的函数与表连接
| 存储模式
| 基于列式存储
| 基于表格布局和列式存储
| 数据掩护
| 更新后仍然保留旧版本
| 替换
| 可伸缩性
| 轻易地增加节点,兼容性高
| 需要中心层,捐躯功能
| 通过HBase的模式与传统数据库系统对比,我们可以更清楚地相识HBase的布局:实在HBase和关系型数据库是差别的两种系统,它们拥有差别的设计特性。
在HBase模式设计过程中需要思量不少因素,这些因素的列表如下:
1)这个表应该有多少个列族。
2)列族利用什么数据。
3)每个列族应该有多少列。
4)列名是什么,尽管列名不必在建表的时候定义,但是读写数据是需要知道的。
5)单元应该存放什么数据。
6)每个单元存储多少个时间版本。
7)行健(Rowkey)布局是什么,应该包含什么信息。
HBase模式的设计更需要注意两个关键点:
(1) Join
HBase中没有Join的概念,以是不支持Join操作,而在不少业务需求中,需要利用Join操作而大表布局可以解决这一问题,只需要一条行记录加上一个特定的行关键字,就可以实现把全部关于Join的数据合并在一起。
(2) Rowkey
Rowkey非常重要,在设计时需要慎重思量。以存储用户观影记录数据为例,复合的Rowkey由用户ID作为前缀(方便把某用户的观影记录聚合在一起),倒置的时间串作为Rowkey的后缀可以使观影记录数据从新到旧排列。如果Rowkey是整型的,用二进制的方式应该比用string来存储一个数据更节约空间。
带着上面提到的若干问题,下面介绍怎样设计HBase表布局。
1.4.2 Rowkey设计
Rowkey是不可分割的字节数,按字典排序由低到高存储在表中。一个空的数组用来标识表空间的起始或结尾。
在设计HBase表时,Rowkey设计是最重要的变乱,应该基于预期的访问模式来为Rowkey建模。Rowkey决定了访问HBase表时可以得到的性能,原因有两个:Region基于Rowkey为一个区间的行提供服务,而且负责区间的每一行;HFile在硬盘上存储有序的行。这两个因素是相互关联的。当Region将内存中数据刷写为HFile时,这些行已经排过序,也会有序地写到硬盘上。Rowkey的有序特性和底层存储格式可以包管HBase表在设计Rowkey之后的良好性能。
关系型数据库可以在多列上创建索引,但是HBase只能在Rowkey上创建索引。访问数据库的最主要方法就是利用Rowkey。非Rowkey访问,即在不清楚Rowkey前提下访问表,可以利用扫描全表。设计Rowkey有各种本领,而且可以针对差别访问模式进行优化,我们接下来就研究一下。
Rowkey是HBase的KeyValue存储中的Key,通常将用户要查询的字段作为Rowkey,查询效果作为Value下面介绍Rowkey设计需要的注意要点。在进行Rowkey设计时用户需要根据差别的需求有针对性地选择或优化这几点。
1. Rowkey是以字典次序从大到小排序
原生HBase只支持从小到大的排序,但是现在有个需求想展现影片热度排行榜,这就要求实现从大到小排列,针对这种环境可以采用Rowkey=Integer.MAX_VALUE-Rowkey的方式将Rowkey进行转换,最大的变最小,最小的变最大,在应用层再转返来即可完成排序需求。
2. RowKey尽量包管散列设计
包管散列设计可以确保全部的数据都不是在一个Region上,从而避免读写的时候负载会集中在个别Region上。
假设我们需要存储一个视频网站用户的全部观影记录(暂时不需要思量时间倒排),这时候的Rowkey可设计为userid_videoid的拼接字符串,但是这样设计的话,userid的分布就很可能不均匀,因为Rowkey是按字符串排序的(默认字典次序排序)。有三种办法来解决这个问题,详细如下:
- Ø 反转userid,将userid字符串反转后存储;
- Ø 散列userid,即对userid进行散列;
- Ø userid取模后进行MD5加密,取前6位作为前缀加入到userid前面。
假设某视频网站的用户正在观看视顿,但此时,要开辟一个新栏目,全部的用户观影记录都按照时间倒排序展示在这个栏目中。这个时候,就需要为原来的userid_videoid创建一张索引表,而且这个表的Rowkey要和时间相关。
Rowkey设计可以利用当前时间(观影时间)的Long值作为Rowkey的前缀、别的发起Rowkey最好都是String:一是方便线上利用shell查数据、排查错误;二是更容易让数据均匀分布;三是不必思量存储成本。
3. RowKey的长度尽量短
如果Rowkey太长,第一存储开销会增加,影响存储效率;第二内存中Rowkey字段过长,会导致内存的利用率降低.进而降低索引命中率:
一样平常的做法是:
- Ø 时间利用Long来表示。
- Ø 尽量利用编码压缩。
1.4.3 列族定义
列族(column Family)是一些列的聚集。一个列族的全部列成员有着雷同的前缀。比如,列courses:history和courses:math都是列族courses的成员:冒号(:)是列族的分隔符,来区分前缀和列名。列族前缀必须是可输出的字符,剩下的部分称为列(Qualifier),可以由任意字节数组组成一列族必须在表创建的时候声明:列则不需要特殊声明,用户随时可以创建新列。
在物理上,一个列族的成员在文件系统上都存储在一起,因为存储优化都是针对列族级别的,这就意味着,访问一个列族的全部成员的方式都是雷同的。
现在HBase并不能很好地处理两个或者三个以上的列族,以是应尽量减少列族数量。目前,flush和compaction操作是针对一个Region的,以是当一个列族操作大量数据的时候会引发一个flush那些不相关的列族也要进行nush操作,尽管它们没有操作多少数据。compaction操作现在是根据一个列族下全部文件的数量触发的,而不是根据文件大小触发的。当很多的列族在进行flush和compaction时,会造成很多没用的I/O负载,要解决这个问题,需要将flush和compaction操作只针对一个列族进行。
尽量在应用中利用一个列族。如果全部查询操作只访问一个列族,可以引入第二个和第三个列族。基于flush性能的思量,列族数量越少越好。
如果一个表存在多个列族,当基数差距很大时,例如,A族有100万行,B族有10亿行,A族可能会被分散到很多Region,导致扫描A的效率降低多个列族在实行flush和compaction时,会造成很多I/O负载。
下面是列族相关的设置属性,这此属性都有默认值,如果在创建表的时候不显式指定,则利用默认值。
1.4.3.1 可设置的数据块大小
HFile数据块大小可以在列族条理设置。这个数据块差别于之前谈到的HDFS数据块,其默认位是65536字节,或64KB。数据块是索引存储的,每个HFile数据块的起始键数据块大小的设置影响数据块索引的大小。数据块越小,索引越大,从而占用更大内存空间。同时载进内存的数据块越小,随机查找性能更好。但是,如果需要更好的序列扫描性能,那么一次可以或许加载更多HFile数据进入内存更为公道,这意味着应该将数据块设置为更大的值。相应地,索引变小,将在随机读性能上付出更多的代价。
可以在表实例化时设置数据块大小,代码如下:
Hbase(main):002> create ‘mytable’
{NAME => ‘colfam1’, BLOCKSIZE => ‘65536’}
1.4.3.2 数据块缓存
把数据放进读缓存,并不是肯定可以或许提拔性能。如果一个表或表的列族只被次序化扫描访问或很少被访问,则Get或Scan操作花费时间长一点是可以接受的。在这种环境下,可以选择关闭列族的缓存。如果只是实行很多次序化扫描,会多次利用缓存,而且可能会滥用缓存,从而把应该放进缓存获得性能提拔的数据给排挤出去。如果关闭缓存,不仅可以避免上述环境发生,而且可以让出更多缓存给其他表和同一表的其他列族利用。
数据块缓存默认是打开的。可以在新建表或更改表时关闭数据块缓存属性:
Hbase(main):002:0>create ‘mytable’, { NAME => ‘colfam1’, BLOCKCACHE => ‘false’ }
IN_MEMORY参数的默认值是false,该值表示HBase除了在数据块缓存中保存这个列族,相比其他列族更激进之外,并不提供其他额外的包管。该参数在实际应用中设置为true。此时访问性能不会变化太大。下面代码展示怎样设置lN_MEMORY属性:
Hbase(main):002:0>create ‘mytable’, { NAME => ‘colfam1’, IN_MEMORY => ‘true’ }
1.4.3.3 布隆过滤器
数据块索引提供了一个有效的方法getDataBlocklndexReader(),在访问某个特定的行时用来查找应该读取的HFile的数据块。但是该方法的作用有限。HFile数据块的默认大小是64KB,一样平常环境下不能调整太多。
如果要查找一个很短的行,只在整个数据块的起始行键上创建索引是无法给出更细粒度的索引信息的。例如,某行占用100字节存储空间,一个64KB的数据块包含(64*1024)/100=655.53,约700行,只能把起始行放在索引位上。要查找的行可能落在特定命据块上的行区问,但也不能肯定存放在那个数据块上,这就导致多种可能性:该行在表中不存在,或者存放在另一个HFile中,乃至在MemStore中。这些环境下,从硬盘读取数据块会带来I/O开销,也会滥用数据块缓存,这会影响性能,尤其是劈面对一个巨大的数据集且有很多并发读用户时。
布隆过滤器(Bloom Filter)答应对存储在每个数据块的数据做一个反向测验。当查询某行时,先查抄布隆过滤器,看看该行是否存在这个数据块。布隆过滤器要么确定答复该行不在,要么答复不知道,因此称之为反向测验。布降过滤器也可以应用到行内的单元格上,当访问某列标识符时先利用同样的反向测验。
利用布降过滤器也不是没有代价,相反,存储这个额外的索引条理占用额外的空间。布隆过滤器的占用空间大小随着它们的索引对象数据增长而增长,以是行级布隆过滤器比列标识符级布隆过滤器占用空间要少。当空间不是问题时,它们可以压榨整个系统的性能潜力。
可以在列族上打开布隆过滤器,代码如下:
HBase(main):007:0>create ‘mytable’, { NAME => ‘colfam1’, BLOOMFILTER => ‘ROWCOL’ }
注意,数据只在硬盘上是压缩的,在内存中(MemStore或BlockCache)或在网络传输时是没有压缩的,不能经常改变数据的压缩编码,但是如果的确需要改变某个列族的压缩编码,也可以直接更改表定义,设定新的压缩编码。此后Region合并时,天生的HFile全部会采用新编码压缩。这个过程不需要创建新表和复制数据。
1.4.3.4 数据压缩
HFile可以被压缩并存放在HDFS上,这有助于节流硬盘I/O,但是读写数据时压缩息争压缩会提高CPU利用率。压缩是表定义的一部分,可以在建表或模式改变时设定。除非确定压缩不会提拔系统的性能,否则推荐打开表的压缩。只有在数据不能被压缩,或者因为某些原因服务器的CPU利用率有限制要求的环境下,有可能需要关闭压缩特性。
HBase可以利用多种压缩编码,包罗LZO、SNAPPY和GZIP,LZO和SNAPPY是此中最盛行的两种。SNAPPY由Google在2011年发布,发布不久Hadoop和HBase项目开始对其提供支持。在此之前,选择的是LZO编码。Hadoop利用的LZO原生库受GPLv2版权控制,不能放在Hadoop和HBase的任何发行版中,必须在它们中单独安装;别的,SNAPPY拥有BSD许可(BSD-licensed),以是它更容易和Hadoop及Haase发行版捆绑在一起。LZO和SNAPPY的压缩比例和压缩/解压缩速度差不多。
当建表时可以在列族上打开压缩,代码如下:
Hbase(main):002:0> create ‘mytable',{ NAME => ‘colfaml1’, COMPRESSION =>'SNAPPY’ }
注意,数据只在硬盘上是压缩的,在内存中(MemStore或BlockCache)或在网络传输时是没有压缩的。
不能经常改变数据的压缩编码,但是如果的确需要改变某个列族的压缩编码,也可以直接更改表定义,设定新的压缩编码。此后Region合并时,天生的HFile全部会采用新编码压缩。这个过程不需要创建新表和复制数据。
1.4.3.5 单元时间版本
在默认环境下,HBase的每个单元格只维护三个时间版本。该属性也是可以设置的。如果只需要一个版本,在创建表时可以直接将VERSIONS参数设置为1,这样系统就不会保留更新单元的多个时间版本。时间版本也是在列族级设置的,代码如下:
Hbase(main):002:0> create ‘mytable’, { NAME => ‘colfam1’, VERSIONS => 1 }
可以在同一个建表语句里为列族指定多个属性,代码如下:
Hbase(main):002:0> create ‘mytable’, { NAME => ‘colfam1’, VERSIONS => 1, TTL => ‘18000’ }
也可以指定列族存储的最少时间版本数,代码如下:
Hbase(main):002:0> create ‘mytable’, { NAME => ‘colfam1’, VERSIONS => 5, MIN_VERSIONS => ‘1’ }
在列族上同时设定TTL也黑白常有效的。如果当前存储的全部时间版本都早于TTL,至少MIN_VERSION个最新版本会保留下来,这样可以确保在杳询以及数据早于TTL时有效果返回。
1.4.3.6 生存时间
生存时间(Time To Live,TTL),用于设置单元格的生存周期。如果单元格过期,则会将其删除。应用系统经常需要从数据库中删除旧数据,因为数据库很难超过某种规模。传统数据库中内置了很多灵活的处理方法。例如,在一个视频网站用户的观影系统中,不想删除用户全部观影记录。这些都是用户天生的数据,将来某一天实行一些深度挖掘分析时可能有效,但是不需要保持全部观影记录都能实时访问,以是可以将早于某个时间的观影记录归档存放到平面文件中。
早于指定TTL值的数据在下一次大合并时会被删除。如果在同一单元格中有多个时间版本,早于设定TTL值的版本会被删除。可以禁用TTL,或者通过设置其位为INT.MAX_VALUE(2147483647)让它永久启用,这也是默认值,单位是秒。可以在建表时设置TTL,代码如下:
Hbase(main):002:0> create ‘thetable’, {NAME => ‘cf1’, TTL => ‘18000’ }
该下令在列族cf1上设置TTL为18000s,即5小时。cf1中超过5小时的数据会在下一次大合并时被删除。
1.4.4 模式设计实例
在设计教据库表的时候,思量设计要满足功能需求是最基本的工作。下面将通过4个实例解说怎样进行HBase表布局设计。主要通过数据和功能需求两方面来对比传统关系型教据库与HBase表布局设计的异同。
1.4.4.1 实例1:动物分类
1. 数据需求
如果一位生物科学家要存储一些动物相关信息,此中要包罗动物的大类,以从一些大类动物下包罗的小类,这样可以方便今后查询某种详细动物属于哪一种别,以及动物名字详细是什么。下面简朴列举一些动物分类如下:
- Ø Animal
- Ø Pig
- Ø Cat
- Ø Monkey
- Ø Dog: Red dog和Black dog
- Ø Tiger: Tiger of northeast
此中,Animal是顶级分类,Pig、Cat、Monkey、Dog和Tiger属于一级分类,而Dog中的Red dog和Black dog,以及Tiger中的Tiger of northesst属于二级分类。
2. RDBMS表布局设计
动物分类在关系型数据库的设计中只需要思量主键的映射关系即可,需要一个分类表布局。每种动物都有几个关键字段:id、name、parent_id和child_id,如表 1.4.2所示。
表 1.4.2 RDBMS中的动物分类表布局
id PK
| name
| parent_id
| child_id
| 1
| animal
|
| 2,3,4,5
| 2
| pig
| 1
|
| 3
| cat
| 1
|
| 4
| monkey
| 1
|
| 5
| dog
| 1
| 7,8
| 6
| red-dog
| 1.5
|
| 7
| black-dog
| 1.5
|
| 8
| tiger
| 1
| 9
| 9
| tiger-of-northeast
| 1.8
|
| 对于动物分类的HBase表布局设计,Rowkey对应RDBMS中的id,共有三个列族:name、parent、和child,详细设计如表 1.4.3所示。
表 1.4.3 HBase中的动物分类表布局
Rowkey
| Column Famlily
| <id>
| name
| parent
| child
|
|
| parent:<id>
| child:<id>
| 1
| animal
|
| child:2=cat
child:3=monkey
child:4=dog
child:5=tiger
child:6=pig
|
|
|
|
| 4
| dog
| parent:1=animal
| child:7=reddog
child:8=blackdog
| 7
| reddog
| perent:1=animal
parent:4=dog
|
| 通过这个简朴的例子可以行出,这两种表布局设计有本质的区别,一个是行式存储,一个是列式存储,以是刚刚接触HBase的读者需要转换思维设计表布局,这样才可以或许更好地把握HBase的表模式设计。
1.4.4.2 实例2:店铺与商品
电商行业中店铺和商品都是最基本的概念,本实例将描述这两者之间的关系。本实例是涉及多表关联关系的设计。
1. 数据需求
某电商网站要存储在本网站的店铺属性信息,同时要知道这典店铺都卖了哪些商品,以及这些商品的详细信息。下面是店铺和商品之间关系的描述。
店铺表: Shop: Item=1:N
商品表: Item: Shop=1:N
此中,Shop是店铺,Item是商品。1:N表示一对多。
2. RDBMS表布局设计
关系型数据库中店铺表共包含三个字段:name、address和regdate,分别表示铺名称、所在地和注册日期,详细描述如表 1.4.4所示。
表 1.4.4 RDBMS中的店铺表布局
列名
| 列含义
| id PK
| 主键
| name
| 店铺名称
| address
| 所在地
| regdata
| 注册日期
| 商品表共包含四个字段:name、price、details和title,分别表示商品名称、价格、商品详情和展示名称,详细描述如表 1.4.5所示。
表 1.4.5 RDBMS中的商品表布局
列名
| 列含义
| id PK
| 主键
| name
| 商品名称
| price
| 价格
| details
| 商品详情
| title
| 展示名称
| 店铺商品对应关系表是表示店铺和商品的映射关系表,共三个字段:shop_id、item_id和type,详细解释如表 1.4.6所示。
表 1.4.6 RDBMS中的店铺与商品对应关系表布局
列名
| 列含义
| shop_id
| 店铺主键
| item_id
| 商品主键
| type
| 关联类型
| 3. HBase表布局设计
店铺表主键是RDBMS中的店铺表的id,共有两个列族:info和item,info表示店铺的静态属性,item表示店铺与商品的关联关系,如表 1.4.7所示。
表 1.4.7 HBase中的店铺表布局
Rowkey
| Column Famlily
| <shop_id>
| info
| item
| info:name
info:address
info:regdate
| item:<item_id>=type
| 商品表主键是RDBMS中的商品表的id。共有两个列族:info和shop。info表示商品的静态属性,shop表示商品与店铺的关联关系,如表 1.4.8所示:
表 1.4.8 HBase中的商品表布局
Rowkey
| Column Famlily
| <shop_id>
| info
| shop
| info:name
info:price
info:details
info:title
| shop:<shop_id>=type
| 通过对比我们可以看出,RDBMS表布局设计是通过三个表来实现的:一个表存储商品的详细信息,一个表存储店铺的详细信息,还有一个是店铺与商品的对应关系表。而HBase表布局设计是通过两个表实现的,每个表中都存储了店铺与商品的关联关系,并分别存储了商品与店铺的详细信息。如果想查询某个店铺所卖的商品的详细信息,RDBMS表要通过对商品详细信息和商品与店铺对应关系表进行Join来实现,而HBase表只需找到存储了商品的详细信息的表来查询即可。
1.4.4.3 实例3:网上商城用户消费记录
现在网购已经成为潮水,用户在网上商城购买商品产生购买行为,网站肯定会记录下用户的消费记录,本案例就是对网上商城的用户消费记录进行分析,提炼数据模子,并对比关系型数据库和HBase数据库的表布局设计的异同。
1. 数据需求
某电商要存储用户购买商品的信息,而且想知道该用户近来一段时间都购买了哪些商品,从而分析该用户近期的消费状态,详细的查询需求如下:
用户购买的商品
查询用户近来购买的商品
2. RDBMS表设计
为了加速查询,需要对usr_id创建索引,但是创建索引的代价是索引的重建导致插入速度减慢。我们关系型数据库中用户消费记录表Sale,详细表述如表 1.4.9所示。
表 1.4.9 RDBMS中的Sale表布局
列名
| 列含义
| Id PK
| 主键
| user_id IDX
| 用户ID,创建索引
| product
| 商品
| time
| 购买时间
| 3. HBase表布局设计
在HBase中设计用户消费表Sale时,Rowkey的设计非常重要。本例利用<usr_id><Long.MAX_VALUE-System.currentTimeMillis()><product_id>作为Rowkey,该Rowkey共由三个部分组成:user_id,Long.MAX_VALUE-System.currentTimeMillis()和product_id,此中,Long.MAX_VALUE-System.currentTimeMillis()是为了使得用户的近来消费记录可以或许按照时间次序排列。详细设计如表 1.4.10所示。
表 1.4.10 HBase中的Sale表布局
Rowkey
| Column Family
| <user_id> <Long.MAX_VALUE-System.currentTimeMillis()>
<product_id>
| name
| name:product
name:time
| 1.4.4.4 实例4:微博用户与粉丝
很多人都在玩微博,信赖各人都知道微博上用户和粉丝都黑白常精密的关系。本例将尝试提炼用户与粉丝关系的数据模子,并对比RDBMS和HBase设计表布局的异同。
1. 数据描述
微博网站既要存储用户的详细信息,也要存储该用户全部的粉丝对应关系。用户粉丝的对应关系是一对多,即user:fans=1:N,user是用户,fans是粉丝,1:N表示一对多。基于这些数据关系,数据处理是可以查询用户的全部粉丝。
2. RDBMS表布局设计
RDBMS中的用户表共有5个字段:id、nickname、gender、dob和address,详细的字段分析如表 1.4.11所示。
表 1.4.11 RDBMS中的用户布局
列名
| 列含义
| id
| 主键
| nickname
| 用户昵称
| gender
| 性别
| dob
| 出生日期
| address
| 所在地
| 用户对应表共有三个字段;user_id和fans_id和type,详细字段解释如表 1.4.12所示。
表 1.4.12 RDBMS中的用户粉丝对应表布局
列名
| 列含义
| user_id
| 用户主键
| fans_id
| 粉丝用户主键
| type
| 互粉类型
| 3. HBase表布局设计
表 1.4.13是用户与粉丝关系表的HBase布局。此中,主键是RDBMS中的用户主键。列族有两个:info和fans。info表示用户的静态属性信息,fans表示该用户的粉丝关系的。因为粉丝也是微博用户,以是粉丝的id也是user_id,在fans列族中的粉丝id也利用user_id。
表 1.4.13 HBase中的用户与粉丝表布局
Rowkey
| Column Family
| <user_id>
| info
| fans
| info:nickname
info:gender
info:dob
info:address
| fans:<user_id>=type
| 通过对比可以看出,RDBMS是利用两个表来设计实现的,一个表存储用户的详细信息,一个表存储用户与粉丝的对应关系。而HBase通过一个表存储用户的详细信息和粉丝对应关系。
1.4.4.5 小结
我们带着一些问题开始了本章的学习,现在我们知道,HBase表怎样设计是与需求直接相关的,如果想设计优秀的表布局,关键是先清理业务场景需求。当然HBase表布局设计有一些硬性指标,遵照这些指标对HBase性能的的提拔有很大帮助。例如,Rowkey本身是按字典升序排列,每个表最好不超过三个列族等。
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |