简介
本文将介绍HBase的基本概念,各个组件的组成元素以及客户端与HBase服务端交互的过程
HBase的组成元素
HBase的特点是依靠HDFS文件系统,做到能够存储巨大容量的数据库。因为依赖HDFS,因此HBase有高可用的机制,即使其中一台服务器数据发生的损坏,也能通过冗余备份进行恢复。HBase还能够提供大吞吐量和低延时的查询,那么他的具体组成元素是怎么样的呢?
(1) Region
HBase的逻辑结构是一张表,但是表的大小巨大,因此HBase会对表进行切分,每一份都会存储在多台服务器上,而“这一份”数据的单位就叫做Region。
(2) RegionServer
RegionServer用于托管多个Region,本质上他是一个HDFS客户端,通常与HDFS的DataNode部署在一起,考虑到网络IO的优化,一般而言RegionServer主要负责与他部署在一块的DataNode的读写操作。
(3)HFile
HFile里面存储的是一个KeyValue对,存储数据的文件
(4)Memstore
写缓存。因为HBase的存储是按照RowKey排序的,同时在高并发写的时候如果每一次写都持久化到硬盘中,那么多次的IO操作会拖慢写性能。因此写操作会在Memstore中缓存并进行排序,然后触发flush条件后将这些数据写入到HFile中,从而提到写的效率。
(5)Write Ahead Log
在写操作之前,会将命令提前写入Log中,当服务端奔溃的时候,可以根据重做日志来恢复数据。
如何查询数据
既然一张表会被分成多个Region,那么HBase是如何定位到某一行的数据的呢?
HBase使用类似与树状结构的方法去存储元数据。
HBase的元数据存储在两个特殊的表,分别是-ROOT-表和.META.表。其中-ROOT-表只包含在1个region中。
HBase查询数据的时候,首先会从Zookeeper中查询-ROOT-所在的ReegionServer,-ROOT-会指向对应的.META.的regionServer以及region地址,最后客户端到对应的region中查询对应行的数据。
RowKey
RowKey是HBase中唯一的索引,HBase根据Rowkey排序的顺序进行存储,因此我们在设计rowKey的时候,相似的数据的RowKey尽量的紧凑和连续,以便扫描数据。如果是不变的元素,例如是用户ID,那么因为使用Hash算法去进行编码,以保证用户的分布是均衡的。
HBase表示的数据结构
HBase表示的数据结构是一个稀疏矩阵。HBase的存储是面向列存储的。
对于每一行数据而言,他都包含一个行键以及多个列族,一个列族包含多个列,同一个列族的数据是存储在一块的。
HBase与CAP
HBase不是一个ACID系统但是他提供一下保证:
(1)提供行级的写原子性保证
(2) 如果某行数据在扫描后被修改了,那么返回的数据是修改后的数据,而不是某个时间点的快照。
HBase是建立在分布式系统中的,因此我们考虑一下CAP问题
CAP产生的背景是,当有一部分机器与另外一部分机器产生分区(Partitions)的时候,这时候两个分区的数据是有可能不一致(Consistency)的。
如果不能系统不能忍受这种不一致性,那么在发生Partitions的时候是不会向外提供服务,直至恢复。
如果希望系统是可用的(Availability),那么需要忍受这暂时的不一致性,但是要保证最终的一致性,即恢复分区后最终的数据是一致的。
CAP不是在这三个元素中任选两个,而是在P的情况下选择A还是选择P
对于HBase而言,他需要保证数据的一致性,因此他选择了一致性。
参考原文
The short summary of the article is that CAP isn’t “C, A, or P, choose
two,” but rather “When P happens, choose A or C.”
Partitions, like death and taxes, are unavoidable – think of machine
death as just a partition of that machine out into the networking
equivalent of the afterlife. So it’s up to the system designer to
decide if, when that happens, we give up availability or give up
consistency.
In HBase’s case we choose consistency, so we have to give up some availability.