hbase原理学习总结

转自:https://blog.csdn.net/embracejava/article/details/72589045
译自:《Architecting HBase Applications-A GUIDE FOR SUCCESSFUL DEVELOPMENT AND DESIGN》,作者:Jean-Marc Spaggiari & Kevin O’Dell,如果对原书内容感兴趣,建议阅读原版图书。

以下为我个人的理解,如有不对之处,烦请指出,多多益善。

定义

apache hbase :1.非关系型、2.基于列的、3.分布式存储、4.以google的Big Table为原型,5.基于HDFS构建、6.java语言开发、7.开源、

基于列:稀疏存储,如果某个rowkey的某列没有值,那么这个列就不会被存储,可以认为没有这个列;
基于行:一次存储完整的一行,如果行中某列没有值,列仍会被存储,值为空或者给定的默认值。

不支持:非关系(不能join)、不支持事务、不支持SQL

Hbase两种类型的表:
系统表:存储用户表的元信息,包括访问控制信息、表/分区/命名空间等。
用户表:用户自己定义的表

存储模型

hbase原理学习总结
1个Table被预为多个Region,一个Region可以有多个Column Family,一个CF拥有一个Store,一个Store拥有一个memStore 和 多个HFiles。

  • 对于一个Table,会根据rowkey被分为多个Regions:用 start key 和end key,定义每个Region的边界,来预分区,这些信息会被存储到系统表中。
    当有数据写入时,会根据其rowkey及预分区规则,将其存储到相应的Region上去。每隔一个固定的时间(用户配置的),Hbase会对这些Regions进行负载均衡,对Region进行必要的迁移。如果一个Region太大,还可以进行Split,反之则可以对Region进行合并。因此Region是管理的基本单元。
  • 一个Region可以有多个Column Family,但按照实际使用经验来说,最好只有一个。如果一张表有多个列族,而它们之间并没有一致性约束,那么最好拆分成多张表。
    列族的划分规则:具有同样访问模式的和同样格式的数据划分到同一个列族。
    访问模式举例:频繁读取但很少写入,经常写入但很少读取这两类访问模式的数据划分到不同的列族中。
    数据格式举例:应该讲文本信息和图片信息两种数据格式的数据划分到不同的列族中。文本信息应该是压缩存储,图片信息不应压缩存储
    为什么一个Region中最好只有一个CF:在一个Region中,写缓冲区被所有cf共享,多个cf情况下,会产生许多小文件,则会带来很多压缩操作,最终影响系统性能。
  • 一个cf对应一个Store,一个Store有一个memstore和多个HFiles。当数据写入时,首先写入memstore,当memstore写满时,数据会被flush出一个HFile来,多个HFiles最终会被压缩到一起形成一个大文件,然后存储到HDFS上。
  • HFiles由blocks组成(此blocks与HDFS的blocks没有关系,一个HDFS的block可能会包含多个HFile)。HFile的blocks的大小一般在8K~1M,默认是64K。
    然而压缩后的block的大小会基于数据和压缩格式进行变化。大的block会产生比较少的索引值,有利于对表数据的连续访问。而小得block会产生更多的索引值,有利于对表数据的随机访问。但对于block大小的设定,建议采用默认值。
    HFile里可能会包括以下几种block:
    • Data block:(可以被压缩),包括delete标记和puts标记
    • Index blocks : 用来进行随机读取的定位。当查找某一个特定行的数据时,通过index blocks来快速跳到HFile的特定位置上。
    • Bloom filter blocks:用来存储跟bloom filter index相关的信息。
      在HBase中,每一行都以一种特定格式来存储,下
  • cell: Hbase是基于列的数据库,因此每个cell都是单独存储的,同一行的不同cell可能会存储到不同的HDFS文件中。
    keytype字段代表了可能的HBase操作:
    Put/Delete/DeleteFamilyVersoin/DeleteColumn/DeleteFamily
    hbase原理学习总结

HBase内部管理和优化

  1. compaction(压缩)
    当前Region会产生多个HFiles,这些HFiles是以小文件的形式存储到本地HDFS上的,compaction就是对这些小文件进行管理和优化。
    compaction会将多个HFile压缩成一个大文件,并对已删除的cell进行清理。
    清理:当用户删除一个cell时,hbase会存储一个删除标记到此cell。compaction 会对有删除标记的cell及与其同key同CQ但是时间戳在其之前的所有进行清理。
    根据清理的完整度,将压缩分为两种:minor compaction (初级压缩)和 Major compaction(高级压缩)。
    minor compaction只选中当前Region中的部分HFiles进行compaction,因此清理时出现以下两种情况,导致清理也是不完全的:1.minor compaction选中的HFile中,有些cell有删除标记,但是时间戳在它之前的同key且同CQ的cell存在于其它未被选中的HFile中;2.未被选中的HFile中有些cell被有删除标记,但是时间戳在它之前的cell,存在于被选中HFile中。第1中情况中,必须保留删除,以确保其它未被选中的HFile中的应该被删除的还有被清理的机会。
    major compaction则能确保清理是完全的。并且可以将删除标记也清理掉。
    hbase默认当当前Region中hfiles数量为超过3时,触发compaction操作。hbase会根据一定策略选中要compaction的HFiles,如果只是选中了部分HFiles,那么进行minor compaction,如果选中了全部的HFiles,那么进行major compaction。
    hbase默认每周自动进行major compaction,经验建议关闭自动进行的主压缩,该为定时任务手工进行。
    major compaction可以由用户选择压缩级别:所有表(不建议)、单个表、单个Region、单个CF。
    经验建议:将所有表的主压缩分散到一周中去。如果表多,且每个表的Region都很多,强烈建议你自己实现如下方式的压缩自动任务:检查每个分区HFiles的数量和最旧版本的时间,如果HFiles的数量超出了你的预期或者最近版本比配置的周期要长(一开始最好配置成一个星期),就触发一次Region级别的major compaction。这样做可以保证region的数据本地性,降低你集群的IO。
  2. split
    Region中的HFiles经过不断的压缩,形成了越来越大的文件,当文件大小超过10G,hbase会对其进行Split,选择一个合适的rowkey作为分割点,生成两个Region,每个Region会被balance到不同的server上去。
    split不会将相同key的cell分割到不同的Region上去。因此如果列族非常多,或者每个列族中的列非常多,导致一个rowkey的数据就超过了10G,但是无法进行split,这样会导致整个server仅为这一个rowkey服务,应该避免。
    如果一个表有多个CF,但是不同CF的数据量差距非常大,这会导致split后数据量小的CF只有几个HFiles,这也应该避免。
    split后的Region会被balance到不同server上去,这会使得其失去本地化这个特性,直到下一次压缩操作(压缩为什么会形成本地化?不理解)。
  3. balance
    当split出两个Region后,或者有server撤出,或者有新的server加入时,会出现负载不均衡的情况。
    hbase默认每5分钟一次进行balance,以保证所有server服务的Region的数量大致相等。
    hbase默认的balance算法是StochasticLoadBalancer,经验建议默认此配置即可。
    balance时,会有几毫秒的服务不可用。之后,Region会失去数据本地化,知道下一次major compaction。

hbase 集群角色