列镞: 列族是多个列的集合。其实列式数据库只需要列就可以了,为什么还需要有列族呢?因为HBase会尽量把同一个列族的列放到同一个服务器上,这样可以提高存取性能,并且可以批量管理有关联的一堆列。所有的数据属性都是定义在列族上。

命名空间可以填补HBase无法在一个实例上分库的缺憾。通过命名空间我们可以像关系型数据库一样将表分组,对于不同的组进行不同的环境设定,比如配额管理、安全管理等。

HBase中有两个保留表空间是预先定义好的: HBase 、default


单元格: 一个列中可以存储多个版本的数据。而每个版本就称为一个单元格(Cell),所以在HBase中的单元格跟传统关系型数据库的单元格概念不一样。

Timestamp(时间戳/版本号):你既可以把它称为是时间戳,也可以称为是版本号,因为它是用来标定同一个列中多个单元格的版本号的。


HBase是怎么存储数据的

image.png
Master:负责启动的时候分配Region到具体的RegionServer,执行各种管理操作,比如Region的分割和合并。

RegionServer:RegionServer上有一个或者多个Region。

Region:表的一部分数据。HBase是一个会自动分片的数据库。一个Region就相当于关系型数据库中分区表的一个分区,或者MongoDB的一个分片。

ZooKeeper:ZooKeeper虽然是自成一家的第三方组件,不属于HBase体系。但是ZooKeeper在HBase中的重要性甚至超过了Master。


这个RegionServer的内部架构图,如图54所示:

image.png

一个WAL:预写日志,WAL是WriteAheadLog的缩写。当操作到达Region的时候,HBase先不管三七二十一把操作写到WAL里面去。HBase会先把数据放到基于内存实现的Memstore里,等数据达到一定的数量时才刷写(flush)到最终存储的HFile内。WAL是一个保险机制,数据在写到Memstore之前,先被写到WAL了。这样当故障恢复的时候可以从WAL中恢复数据。

多个Region:Region相当于一个数据分片。每一个Region都有起始rowkey和结束rowkey,代表了它所存储的row范围。



单个Region内部的结构,如图55所示。
image.png
多个Store:每一个Region内都包含有多个Store实例。一个Store对应一个列族的数据,如果一个表有两个列族,那么在一个Region里面就有两个Store。在最右边的单个Store的解剖图上,我们可以看到Store内部有MemStore和HFile这两个组成部分。



单个Store内部的结构可以表示成如图56所示:
image.png

MemStore:每个Store中有一个MemStore实例。数据写入WAL之后就会被放入MemStore。MemStore是内存的存储对象,只有当MemStore满了的时候才会将数据刷写(flush)到HFile中。

HFile:在Store中有多个HFile。当MemStore满了之后HBase就会在HDFS上生成一个新的HFile,然后把MemStore中的内容写到这个HFile中。HFile直接跟HDFS打交道,它是数据的存储实体。


数据在进入HFile之前已经被存储到HDFS一次了,为什么还需要被放入Memstore?

这是因为HDFS上的文件只能创建、追加、删除,但是不能修改。对于一个数据库来说,按顺序地存放数据是非常重要的,这是性能的保障,所以我们不能按照数据到来的顺序来写入硬盘。虽然很困难,但是办法还是有的。那就是使用内存先把数据整理成顺序存放,然后再一起写入硬盘。这就是Memstore存在的意义。虽然Memstore是存储在内存中的,HFile和WAL是存储在HDFS上的。但由于数据在写入Memstore之前,要先被写入WAL,所以增加Memstore的大小并不能加速写入速度。Memstore存在的意义是维持数据按照rowkey顺序排列,而不是做一个缓存。
**


设计MemStore的原因有以下几点:

(1)由于HDFS上的文件不可修改,为了让数据顺序存储从而提高读取效率,HBase使用了LSM树结构来存储数据。数据会先在Memstore中整理成LSM树,最后再刷写到HFile上。

(2)优化数据的存储。比如一个数据添加后就马上删除了,这样在刷写的时候就可以直接不把这个数据写到HDFS上。


增删查改的真正面目

  • 当你新增一个单元格的时候,HBase在HDFS上新增一条数据。

  • 当你修改一个单元格的时候,HBase在HDFS又新增一条数据,只是版本号比之前那个大(或者你自己定义)。

  • 当你删除一个单元格的时候,HBase还是新增一条数据!只是这条数据没有value,类型为DELETE,这条数据叫墓碑标记(Tombstone)。


  • 在HBase进行majorcompaction的时候,它会把多个HFile合并成1个HFile,在这个过程中,一旦检测到有被打上墓碑标记的记录,在合并的过程中就忽略这条记录。这样在新产生的HFile中,就没有这条记录了,自然也就相当于被真正地删除了。