HBase是Hadoop的生态系统,是建立在Hadoop文件系统(HDFS)之上的分布式、面向列的数据库,通过利用Hadoop的文件系统提供容错能力。如果你需要进行实时读写或者随机访问大规模的数据集的时候,请考虑使用HBase!
HBase作为Google Bigtable的开源实现,Google Bigtable利用GFS作为其文件存储系统类似,则HBase利用Hadoop HDFS作为其文件存储系统;Google通过运行MapReduce来处理Bigtable中的海量数据,同样,HBase利用Hadoop MapReduce来处理HBase中的海量数据;Google Bigtable利用Chubby作为协同服务,HBase利用Zookeeper作为对应。
HBase 是一个高可靠、高性能、面向列、可伸缩的分布式数据库,主要用来存储非结构化和半结构化的松散数据,设计它的目的就是用于处理非常庞大的表——通过水平扩展的方式,用计算机集群就可以处理由超过 10 亿行数据和数百万列元素所组成的数据表。
Hbase中的每张表都按照一定的范围被分割成多个子表(HRegion),默认一个HRegion超过 256M 就要被分割成两个,由 HRegionServer管理,管理哪些HRegion由HMaster分配。
提供了访问HBase的一系列API接口,如Java Native API、Rest风格http API、Thrift API、scala等,并维护cache来加快对HBase的访问。
HBase 通过 Zookeeper 来做 Master 的高可用,保证任何时候集群中只有一个Master 、实时监控RegionServer的上线和下线信息,并实时通知Master、元数据的入口以及集群配置的维护等工作。
Zookeeper的作用如下:
HBase表在行的方向上分隔为多个Region。Region是HBase中分布式存储和负载均衡的最小单元,即不同的region可以分别在不同的Region Server上,但同一个Region是不会拆分到多个server上。Region按大小分隔,每个表一般是只有一个region,当region的某个列族达到一个阈值(默认256M)时就会分成两个新的region。
(1)RegionServer维护Region,处理对这些Region的IO请求,向HDFS文件系统中读写数据。
一个RegionServer由多个Region组成,一个Region由多个Store组成,一个Store对应一个CF(列族),而一个store包括位于内存中的Mem Store和位于磁盘的StoreFile,每个StoreFile以HFile格式保存在HDFS上。写操作先写入Mem Store,当Mem Store中的数据达到某个阈值时,RegionServer会启动flashcache进程写入StoreFile,每次写入形成单独的一个StoreFile。
(2)RegionServer负责切分在运行过程中变得过大的Region。
每个表一开始只有一个Region,随着表数据不断插入,数据越来越多,StoreFile也越来越大,当StoreFile文件的数量增长到一定阈值后,系统会进行合并(minor、major compaction),minor主要是合并一些小的文件,不做删除,清理操作,而majar在合并过程中会进行版本合并和删除工作,形成更大的StoreFile。
当一个Region所有StoreFile的大小和数量超过一定阈值后,会把当前的Region分割为两个新的Region(裂变),每个Region保存一段连续的数据片段,如此往复,就会有越来越多的region,并由Master分配到相应的RegionServer服务器,这样一张完整的表被保存在多个RegionServer 上,实现负载均衡。
(3)对于数据的操作:(DML)get, put, delete;
每一个Region由一个或多个Store组成,至少是一个Store,HBase会把一起访问的数据放在一个Store里面,即为每个ColumnFamily建一个Store,如果有几个ColumnFamily,也就有几个Store。一个Store由一个memStore和0或者多个StoreFile组成。Store的大小被HBase用来判断是否需要切分Region。
memStore内存中的数据写到文件后就是StoreFile,StoreFile底层是以HFile的格式保存。这是在磁盘上保存原始数据的实际的物理文件,是实际的存储文件。StoreFile是以HFile的形式存储在HDFS的。每个 Store 会有一个或多个 StoreFile,数据在每个 StoreFile 中都是有序的(按照RowKey的字典顺序排序)。
HLog记录数据的所有变更,可以用来恢复文件,一旦region server 宕机,就可以从log中进行恢复。HBase的修改记录,当对HBase读写数据的时候,数据不是直接写进磁盘,它会在内存中保留一段时间(时间以及数据量阈值可以设定)。由于数据要经 Mem Store 排序后才能刷写到 StoreFile,但把数据保存在内存中可能有更高的概率引起数据丢失,为了解决这个问题,数据会先写在一个叫做Write-Ahead logFile的文件中,然后再写入内存中。所以在系统出现故障的时候,可以通过这个日志文件来恢复数据。
一个LogFlusher的类是用来调用HLog.optionalSync()的。
HDFS 为 HBase 提供底层数据存储服务,同时为 HBase提供高可用的支持, HBase 将 HLog 存储在 HDFS 上,当服务器发生异常宕机时,可以重放 HLog 来恢复数据。
命名空间,类似于关系型数据库的 DatabBase 概念,每个命名空间下有多个表。HBase有两个自带的命名空间,分别是“hbase” 和 “default”,“hbase” 中存放的是 HBase 内置的表,“default”表是用户默认使用的命名空间。
类似于关系型数据库的表的概念(实际上Region在HBase数据库中是表的切片)。建表时不同的是,HBase定义表时只需要声明列簇即可,不需要声明具体的列。这意味着,往HBase中写入数据时,字段可以动态、按需指定。因此,和关系型数据库相比,HBase能够轻松应对字段变更的场景。
HBase 表中的每行数据都由一个 RowKey 和多个 Column(列)组成,数据是按照 RowKey的字典顺序存储的,并且查询数据时只能根据 RowKey 进行检索,所以 RowKey 的设计十分重要。
HBase 中的每个列都是由Column Family(列簇)和 Column Qualifier(列限定符)运行限定,例如:info: name,info: age 。建表时,只需声明列簇,而列限定符无需预先定义。
用于标识数据的不同版本(version),每条数据写入时,如果不指定时间戳,系统会自动为其加上该字段,其值为写入 HBase 的时间。
由{RowKey, Column Family:Column Qualifier, Time Stamp} 唯一确定的单元。cell 中的数据是没有类型的,全部是字节码形式存储(byte[]数组)。
(1)在传统的关系数据库中,如果数据结构发生了变化,就需要停机维护,而且需要修改表结构,而在 HBase 中数据表内的列可以做到动态增加,并且列为空的时候不存储数据,从而节省存储空间。
(2)HBase 适合存储 PB 数量级的海量数据,PB 级的数据在只采用廉价 PC 来存储的情况下,也可以在几十到一百毫秒内返回数据。这与 HBase 的极易扩展息息相关,正因如此,HBase 为海量数据的存储提供了便利。
(3)传统的通用关系数据库无法应对在数据规模剧增时导致的系统扩展性问题和性能问题。HBase 可以做到自动切分数据,并且会随着数据的增长自动地拆分和重新分布。
(4)HBase 可以提供高并发的读写操作,而且可以利用廉价的计算机来处理超过 10 亿行的表数据。
(5)HBase 具有可伸缩性,如果当前集群的处理能力明显下降,可以增加集群的服务器数量来维持甚至提高处理能力。
(1)不能支持条件查询,只支持按照 RowKey(行键)来查询,也就是只能按照主键来查询。这样在设计 RowKey 时,就需要完美的方案以设计出符合业务的查询。
(2)HBase 不能支持 Master(主)服务器的故障切换,当 Master 宕机后,整个存储系统就会挂掉,不能提供正常的服务。
(3)查询 HBase 时不支持通过 SQL 语句进行查询。
HBase 作为一个开源的分布式 Key-Value 数据库,其主要作用是面向 PB 级别数据的实时入库和快速随机访问。这主要源于上述易扩展的特点,使得 HBase 通过扩展来存储海量的数据。
Hbase 是根据列族来存储数据的。列族下面可以有非常多的列。列式存储的最大好处就是,其数据在表中是按照某列存储的,这样在查询只需要少数几个字段时,能大大减少读取的数据量。
HBase 中的表通过 Region 分布在集群上,而且 Region 会随着数据的增长自动拆分和重新分布。
HBase 支持通过 MapReduce 进行大规模并行处理,将 HBase 用作源和接收器。
WAL 机制保证了数据写入时不会因集群异常而导致写入数据丢失,Replication 机制保证了在集群出现严重的问题时,数据不会发生丢失或损坏。而且 Hbase 底层使用 HDFS,HDFS 本身也有备份。
HBase 支持使用 Java 的 API 来编程进行数据的存取,还支持使用 Thrift 语言和 REST 语言的 API 来编程进行数据的存取。
一般而言,如果单表的数据量只有百万的数量级或者更少,则不建议使用 HBase,而应该考虑关系数据库是否能够满足应用的需求。
HBase 是一个 Key-Value 数据库,默认对 RowKey 做了索引优化,所以即使数据量非常庞大,根据 RowKey 查询的效率也会很高。但是,如果还需要根据其他条件进行查询,则不建议使用 HBase。
HBase 是 NoSQL 产品中的一种,它也具有 NoSQL 的缺点,就是不能进行连表查询等操作,也就是说,如果业务场景是需要事务支持、复杂的关联查询,则不建议使用 HBase。
虽然说 HBase 是一个面向列的数据库,但是它与真正的列式存储系统(比如 Parquet、Kudu等)又有所区别,再加上自身存储架构的设计,使得 HBase 并不擅长做数据分析。所以如果业务需求是为了做数据分析,比如做报表,那么不建议使用 HBase。