vlambda博客
学习文章列表

从HBase底层原理解析HBASE列族不能设计太多的原因?

在之前的文章中,笔者详细介绍了:

  1. HBase基础知识(包括简介、表结构)、系统架构、数据存储
  2. WAL log和HBase中LSM树的应用
  3. HBase寻址机制
  4. minor合并和major合并
  5. region管理以及region server上下线
  6. HMaster工作机制和HBase容错性
  7. HBASE数据迁移和备份
    1. distcp命令拷贝hdfs文件的方式
    2. copytable的方式实现表的迁移和备份
    3. replication的方式实现表的复制
    4. Export/Import的方式实现表的迁移和备份

并通过文章详细阐述了:

  1. 布隆过滤器在HBase中的应用

  2. 协处理器(observer和endpoint)

  3. row key设计要点

  4. HBase热点问题及处理

通过上述文章的介绍,我们了解到:
HBase底层存储依赖于HDFS,HBase中table在行的方向上分割为多个region,它是HBase负载均衡的最小单元,可以分布在不同的RegionServer上,但是一个region不能拆分到多个RegionServer上。

但是region不是HBase物理存储的最小单元,它由一个或者多个store组成,每个store保存一个column family即列族。每个store由一个memstore和多个storefile组成,storefile由hfile组成是对hfile的轻量级封装,存储在hdfs上。

所以,每个column family可以看作是HBase中一个集中的存储单元。在生产中,我们设计列族时会将具有相似属性的比如IO特性或者将经常一起查询的列放到一个列族中,可以减少文件的IO、寻址时间,从而提高性能。

刚才说到HBase中每个store由memstore和storefile组成,这里的memstore其实是Sorted Memory Buffer,在WAL机制开启的情况下,不考虑块缓存,数据日志会先写入HLog,然后进入Memstore,最后持久化到HFile中。

在这个过程中,如果某region下下的storeFile大小超过阀值就需要进行切分。每个列族在文件层面上是以单独的文件存储的。但是不同的列族,却可能会共享一个region。这就会导致一个问题:
HBase 表中列族A的数据有100万行,但是列族B可能才1000行。当进行region split时,会列族B也进行切分,从而导致这1000行数据也分布在多个不同region中,最终导致查询数据时,导致寻址时间等增加,影响性能。
此外,默认情况下,只有一个region,当满足一定条件,region会进行分裂。如果一个HBase表中设置过多的列族,则可能引起以下问题:
  1. 一个region中存有多个store,当region分裂时导致多个列族数据存在于多个region中,查询某一列族数据会涉及多个region导致查询效率低(这一点在多个列族存储的数据不均匀时尤为明显)

  2. 多个列族则对应有多个store,那么Memstore也会很多,因为Memstore存于内存,会导致内存的消耗过大

  3. HBase中的压缩和缓存flush是基于region的。当一个列族出现压缩或缓存刷新时,因为关联效应会引起临近的其他列族做同样的操作,在列族过多时会涉及大量的IO开销

所以,我们在设计HBase表的列族时,遵循以下几个主要原则,以减少文件的IO、寻址时间:

  1. 列族数量,要尽可能的少

  2. 列族名字可读性好,但不能过长。原因可类比于HBase row key设计原则

推荐文章:








关注大数据学习与分享,获取更多技术干货