我们知道,一张 HBase 表包含一个或多个列族。
HBase 的官方文档中关于 HBase 表的列族的个数有两处描述:

A typical schema has between 1 and 3 column families per table. HBase tables should not be designed to mimic RDBMS tables. 以及 HBase currently does not do well with anything above two or three column families so keep the number of column families in your schema low.

上面两句话其实都是说一件事,HBase 中每张表的列族个数建议设在1~3之间。
其实,HBase 支持的列族个数并没有限制,但为什么文档建议在1~3之间呢?
我将从几个方面来阐述这么做的原因。

列族数对 Flush 的影响

在 HBase 中,调用 API 往对应的表插入数据是会写到 MemStore 的,而 MemStore 是一种内存结构,每个列族对应一个 MemStore(和零个或多个 HFile)。如果我们的表有两个列族,那么相应的 Region 中存在两个 MemStore,如下图:

从上图可以看出,越多的列族,将会导致内存中存在越多的 MemStore;
而储存在 MemStore 中的数据在满足一定条件的时候将会进行 Flush 操作;
每次 Flush 的时候,每个 MemStore 将在磁盘生产一个 HFile 文件,如下:

这样会导致越多的列族最终持久化到磁盘的 HFile 越多。更要命的是,当前 Flush 操作是 Region 级别的(当然,从HBase 1.1,HBase 2.0 开始 Flush 已经可以设置成列族级别的了),也就是说, Region 中某个 MemStore 被 Flush,同一个 Region 的其他 MemStore 也会进行 Flush 操作。当表有很多列族,而且列族之间数据不均匀,比如一个列族有100W行,一个列族只有10行,这样会导致持久化到磁盘的文件数很多,同时有很多小文件,而且每次 Flush 操作也涉及到一定的 IO 操作。

为了解决每次 Flush 都对整个 Region 中 MemStore 进行的,HBASE-10201/HBASE-3149引入了对 Flush 策略进行选择的功能(hbase.regionserver.flush.policy),可以仅对超过阈值(hbase.hregion.percolumnfamilyflush.size.lower.bound.min)的 MemStore 进行 Flush 操作。但是如果没有 MemStore 大于这个阈值,还是会对所有的 MemStore 进行 Flush 操作。

此外,如果我们的列族数过多,这可能会导致触发 RegionServer 级别的 Flush 操作;这将会导致落在该 RegionServer上的更新操作被阻塞,而且阻塞时间可能会达到分钟级别。

列族数对 Split 的影响

我们知道,当 HBase 表中某个 Region 过大(比如大于 hbase.hregion.max.filesize 配置的大小。当然,Region 分裂并不是说整个 Region 大小加起来大于 hbase.hregion.max.filesize 就拆分,而是说 Region 中某个最大的 Store/HFile/storeFile 大于 hbase.hregion.max.filesize 才会触发 Region 拆分的),会被拆分成两个。如果我们有很多个列族,而这些列族之间的数据量相差悬殊,比如有些列族有 100W 行,而有些列族只有10行,这样在 Region Split 的时候会导致原本数据量很小的 HFile 文件进一步被拆分,从而产生更多的小文件。注意,Region Split 是针对所有的列族进行的,这样做的目的是同一行的数据即使在 Split 后也是存在同一个 Region 的。

列族数对 Compaction 的影响

与 Flush 操作一样,目前 HBase 的 Compaction 操作也是 Region 级别的,过多的列族也会产生不必要的 IO。

列族数对 HDFS 的影响

我们知道,HDFS 其实对一个目录下的文件数有限制的(dfs.namenode.fs-limits.max-directory-items)。如果我们有 N 个列族,M 个 Region,那么我们持久化到 HDFS 至少会产生 N*M 个文件;而每个列族对应底层的 HFile 文件往往不止一个,我们假设为 K 个,那么最终表在 HDFS 目录下的文件数将是 N*M*K,这可能会操作 HDFS 的限制。

列族数对 RegionServer 内存的影响

前面说了,一个列族在 RegionServer 中对应于一个 MemStore。而 HBase 从 0.90.1 版本开始引入了 MSLAB(Memstore-Local Allocation Buffers,参考HBASE-3455),这个功能默认是开启的(通过hbase.hregion.memstore.mslab.enabled),这使得每个 MemStore 在内存占用了 2MB (通过hbase.hregion.memstore.mslab.chunksize 配置)的 buffer。如果我们有很多的列族,而且一般一个 RegionServer 上会存在很多个 Region,这么算起来光 MemStore 的缓存就会占用很多的内存。要注意的是,如果没有往 MemStore 里面写数据,那么 MemStore 的 MSLAB 是不占用空间的。

关于列族数设置的建议

在设置列族之前,我们最好想想,有没有必要将不同的列放到不同的列族里面。如果没有必要最好放一个列族。如果真要设置多个列族,但是其中一些列族相对于其他列族数据量相差非常悬殊,比如1000W相比100行,是不是考虑用另外一张表来存储相对小的列族。

为什么不建议在 HBase 中使用过多的列族的更多相关文章

  1. 为什么不建议在hbase中使用过多的列簇

    我们知道,hbase表可以设置一个至多个列簇(column families),但是为什么说越少的列簇越好呢? 官网原文: HBase currently does not do well with ...

  2. HBase中Memstore存在的意义以及多列族引起的问题和设计

    Memstore存在的意义 HBase在WAL机制开启的情况下,不考虑块缓存,数据日志会先写入HLog,然后进入Memstore,最后持久化到HFile中.HFile是存储在hdfs上的,WAL预写日 ...

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

    在之前的文章<深入探讨HBASE>中,笔者详细介绍了: HBase基础知识(包括简介.表结构).系统架构.数据存储 WAL log和HBase中LSM树的应用 HBase寻址机制 mino ...

  4. Hbase篇--HBase中一对多和多对多的表设计

    一.前述 今天分享一篇关于HBase的一对多和多对多的案例的分析. 二.具体案例 案例一.多对多    人员-角色   人员有多个角色  角色优先级   角色有多个人员   人员 删除添加角色   角 ...

  5. HBase中的压缩算法比较 GZIP、LZO、Zippy、Snappy [转]

    网址: http://www.cnblogs.com/panfeng412/archive/2012/12/24/applications-scenario-summary-of-compressio ...

  6. Flink 使用(一)——从kafka中读取数据写入到HBASE中

    1.前言 本文是在<如何计算实时热门商品>[1]一文上做的扩展,仅在功能上验证了利用Flink消费Kafka数据,把处理后的数据写入到HBase的流程,其具体性能未做调优.此外,文中并未就 ...

  7. HBase中的备份和故障恢复方法

    本文将对Apache HBase可用的数据备份机制和大量数据的故障恢复/容灾机制做简要介绍. 随着HBase在重要的商业系统中应用的大量添加,很多企业须要通过对它们的HBase集群建立健壮的备份和故障 ...

  8. 关于hbase中的hbase-site.xml 配置详解

    该文档是用Hbase默认配置文件生成的,文件源是 hbase-default.xml hbase.rootdir 这个目录是region server的共享目录,用来持久化HBase.URL需要是'完 ...

  9. Hbase中HMaster作用

    HMaster在功能上主要负责Table表和HRegion的管理工作,具体包括: 1.管理用户对Table表的增.删.改.查操作: 2.管理HRegion服务器的负载均衡,调整HRegion分布: 3 ...

随机推荐

  1. 从锅炉工到AI专家(10)

    RNN循环神经网络(Recurrent Neural Network) 如同word2vec中提到的,很多数据的原型,前后之间是存在关联性的.关联性的打破必然造成关键指征的丢失,从而在后续的训练和预测 ...

  2. Winform 程序打包及安装

    前言 近期被公司外派到驻空调厂的项目组,支援一个TCP相关的程序对接.主要是做智能门禁系统,然后主要是统计出实时的进出人数. 我这边能作为服务端,门禁设备作为客户端,整个流程并不算复杂,根据协议来写, ...

  3. centos 7 linux系统安装 mysql5.7.17(glibc版)

    前言:经过一天半的折腾,终于把 mysql 5.7.17 版本安装上了 centos 7 系统上,把能参考的博客几乎都看了一遍,终于发现这些细节问题,然而翻了无数的文章,基本上都没有提到这些,所以小生 ...

  4. PC逆向之代码还原技术,第一讲基本数据类型在内存中的表现形式.浮点,指针寻址公式

    目录 代码还原技术 一丶简介代码还原 二丶代码还原中的数据类型表现形式 1.整数类型 2.无符号整数 3.有符号整数 4.浮点数数据类型 5.浮点编码 4.Double类型解析. 三丶浮点汇编 1.浮 ...

  5. linux rsync 实际应用

    linux rsync 实际应用 一.rsync的概述 rsync是类unix系统下的数据镜像备份工具,从软件的命名上就可以看出来了——remote sync.rsync是Linux系统下的文件同步和 ...

  6. Docker跨主机通信(九)--技术流ken

    容器网络 在前面的博客中已经详细讲解了几种网络方案: none, host, bridge,user-defined.但是他们只是解决了单个主机间的容器的通信问题,并不能实现多个主机容器之间的通信.本 ...

  7. grafana使用详解--技术流ken

    grafana简介 Grafana是一个跨平台的开源的度量分析和可视化工具,可以通过将采集的数据查询然后可视化的展示,并及时通知.它主要有以下六大特点: 1.展示方式:快速灵活的客户端图表,面板插件有 ...

  8. Python并发编程之谈谈线程中的“锁机制”(三)

    大家好,并发编程 进入第三篇. 今天我们来讲讲,线程里的锁机制. 本文目录 何为Lock( 锁 )?如何使用Lock( 锁 )?为何要使用锁?可重入锁(RLock)防止死锁的加锁机制饱受争议的GIL( ...

  9. linux-2.6.18源码分析笔记---进程

    一.进程重要字段描述 在目录include\linux\sched.h下定义了进程描述符task_struct,关注如下字段: 进程状态 volatile long state:表示进程状态,在该文件 ...

  10. 学JAVA第四天,JAVA获取年月日

    先添加引用import java.util.Calendar; 然后编写代码: Calendar calendar = null;//声明 calendar= Calendar.getInstance ...