HBase 是一种开放源,分布式,版本化,非关系型数据库,关键元素有行键、列族、列限定符和时间戳。

  • Table:Hbase的table由多个行组成;
  • Row:一个行在Hbase中由一个或多个有值的列组成。Row按照字母进行排序,因此行健的设计非常重要。这种设计方式可以让有关系的行非常的近,通常行健的设计是网站的域名反转,比如(org.apache.www, org.apache.mail, org.apache.jira),这样的话所有的Apache的域名就很接近;
  • Column:列由列簇加上列的标识组成,一般是“列簇:列标识”,创建表的时候不用指定列标识;
  • Column Family:列簇在物理上包含了许多的列与列的值,每个列簇都有一些存储的属性可配置,例如是否使用缓存,压缩类型,存储版本数等。在表中,每一行都有相同的列簇,尽管有些列簇什么东西也没有存;
  • Column Qualifier:列簇的限定词,理解为列的唯一标识。但是列标识是可以改变的,因此每一行可能有不同的列标识;
  • Cell:由row,column family,column qualifier包含时间戳与值组成的,一般表达某个值的版本;
  • Timestamp:时间戳一般写在value的旁边,代表某个值的版本号,默认的时间戳是你写入数据的那一刻,但是你也可以在写入数据的时候指定不同的时间戳。

    逻辑视图

    列名由其列族前缀和限定符组成。例如,columns:html 列由列族 contents 和 html 限定符组成。冒号(:)将列族与列族限定符分隔开
Row Key Time Stamp ColumnFamily contents ColumnFamily anchor ColumnFamily people
“com.cnn.www” t9 anchor:cnnsi.com = “CNN”
“com.cnn.www” t8 anchor:my.look.ca = “CNN.com”
“com.cnn.www” t6 contents:html = “…”
“com.cnn.www” t5 contents:html = “…”
“com.cnn.www” t3 contents:html = “…”
“com.example.www” t5 contents:html = “…” people:author = “John Doe”

物理视图

尽管从概念上讲,表可以看作是行的稀疏集合,但它们实际上是按列族存储的。可以随时将新的列限定符(col­um­n_­fam­ily:col­um­n_qual­i­fier)添加到现有的列族。
ColumnFamily anchor

Row Key Time Stamp Column Family anchor
“com.cnn.www” t9 anchor:cnnsi.com = “CNN”
“com.cnn.www” t8 anchor:my.look.ca = “CNN.com”

ColumnFamily contents

Row Key Time Stamp ColumnFamily contents:
“com.cnn.www” t6 contents:html = “…”
“com.cnn.www” t5 contents:html = “…”
“com.cnn.www” t3 contents:html = “…”

逻辑视图中显示的空单元格根本不存储。因此,contents:html 在时间戳记上请求该列的值 t8 将不返回任何值。同样,anchor:my.look.ca 在时间戳上请求值 t9 将不返回任何值。但是,如果未提供时间戳,则将返回特定列的最新值。

架构

image.png
image-20200620183057498.png

  • Zookeeper:作为分布式的协调。RegionServer也会把自己的信息写到ZooKeeper中。
  • HDFS:Hbase运行的底层文件系统
  • RegionServer:理解为数据节点,存储数据的。
  • Master:RegionServer要实时的向Master报告信息。Master知道全局的RegionServer运行情况,可以控制RegionServer的故障转移和Region的切分。

    不适用场景

    Hbase 不适合解决所有的问题:

  • 首先数据库量要足够多,如果有十亿及百亿行数据,那么Hbase是一个很好的选项,如果只有几百万行甚至不到的数据量,RDBMS是一个很好的选择。因为数据量小的话,真正能工作的机器量少,剩余的机器都处于空闲的状态

  • 其次,如果你不需要辅助索引,静态类型的列,事务等特性,一个已经用RDBMS的系统想要切换到Hbase,则需要重新设计系统。
  • 最后,保证硬件资源足够,每个HDFS集群在少于5个节点的时候,都不能表现的很好。因为HDFS默认的复制数量是3。

    数据结构

    Hbase 采用的是 LSM 树的结构,这种结构的关键是,

  • 每一次的插入操作都会先进入MemStore(内存缓冲区)

  • 当 MemStore达到上限的时候,Hbase会将内存中的数据输出为有序的StoreFile文件数据(根据Rowkey、版本、列名排序,这里已经和列 簇无关了因为Store里都属于同一个列簇)。
  • 这样会在Store中形成很多个小的StoreFile,当这些小的File数量达到一个阀值的时 候,Hbase会用一个线程来把这些小File合并成一个大的File

这样,Hbase 就把效率低下的文件中的插入、移动操作转变成了单纯的文件输出、 合并操作。不过读取的时候稍微麻烦一些,读取时看这些数据在内存中,如果未能命中内存,则需要访问较多的磁盘文件。极端的说,基于 LSM 树实现的 hbase 写性能比 mysql 高了一个数量级,读性能却低了一个数量级。
由上可知,在 Hbase 底层的 Store 数据结构中,

  • 每个StoreFile内的数据是有序的;
  • 但是StoreFile之间不一定是有序的;
  • Store只 需要管理StoreFile的索引就可以了。

这里也可以看出为什么指定版本和 Rowkey 可以加强查询的效率,因为指定版本和 Rowkey 的查询可以利用 StoreFile 的索引跳过一些肯定不包含目标数据的数据