我们知道,一张 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. 浅谈新的布局方式-flex

    引言: 网页布局在flex出来之前,是由盒模型为底子,float,position,table,百分比来进行布局的,重绘的比较多,影响性能,复杂又不好维护.flex布局,可以简便.完整.响应式地实现各 ...

  2. NIO 简介

    上文我们描述了五中IO类型.第一种同步阻塞模型我们我们称之为BIO(Blocking IO), 第三种IO复用模型我们称之为NIO(Nonblocking IO). 上图我们可以很容易的发现 BIO会 ...

  3. Flow 常用知识点整理

    Flow入门初识 Flow是facebook出品的JavaScript静态类型检查工具. 由于JavaScript是动态类型语言,它的灵活性也会造成一些代码隐患,使用Flow可以在编译期尽早发现由类型 ...

  4. 使用 Jaeger 完成服务间的链路追踪

    世上本没有路,走的人多了,便变成了路 -- 鲁迅     本次讨论的话题就是需要在各个服务之间踏出条"路",让问题有"路"可循. 至于为什么用 jaeger.. ...

  5. Chapter 5 Blood Type——6

    "Yes — giving up trying to be good. I'm just going to do what I want now, and let the chips fal ...

  6. vue-eleme 学习笔记

     # watch 用法 (1).普通的watch <div style="margin-top: 60px;"> {{common}} <button @clic ...

  7. 监控mysql

    Mysql服务器监控 管理MySql服务器属于应用程序监控范畴.这是因为绝大多数性能参数是有MySql软件产生的,而不属于主操作系统的一部分. 如当前所提到的,应该总是先监控基础操作系统,然后监控My ...

  8. [十五]javaIO之SequenceInputStream

    功能简介   SequenceInputStream  合并流 顾名思义,就是可以吧两个流合并起来   他并没有很复杂,单纯的很,仅仅实现了InputStream 他拥有两个构造方法把两个InputS ...

  9. gulp基本设置

    var gulp = require('gulp'); var clean = require('gulp-clean'); var concat = require('gulp-concat'); ...

  10. cocos creator主程入门教程(二)—— 弹窗管理

    五邑隐侠,本名关健昌,10年游戏生涯,现隐居五邑.本系列文章以TypeScript为介绍语言. 我们已经知道怎样制作.加载.显示界面.但cocos没有提供一个弹窗管理模块,对于一个多人合作的项目,没有 ...