为什么不建议在 HBase 中使用过多的列族

我们知道,一张 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行,是不是考虑用另外一张表来存储相对小的列族。

原文地址:https://www.cnblogs.com/felixzh/p/10260682.html

时间: 2024-10-11 05:55:19

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

Hbase 中 hbase-site.xml 参数含义

hbase.client.scanner.caching 定义在扫描器中调用next方法时取回的行数.数值越大,在扫描时客户端需要对RegionServer发出的远程调用次数越少.数值越大,客户端消耗内存越大. hbase.balancer.period region均衡器在HBase Master中周期性运行.该属性定义了均衡器运行的时间间隔,默认5分钟,单位毫秒. hbase.client.write.buffer 客户端HTable实例写缓存,单位Byte.越大RPC调用越少,同时占用更多

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

网址: http://www.cnblogs.com/panfeng412/archive/2012/12/24/applications-scenario-summary-of-compression-algorithms.html GZIP.LZO.Zippy/Snappy是常用的几种压缩算法,各自有其特点,因此适用的应用场景也不尽相同.这里结合相关工程实践的情况,做一次小结. 压缩算法的比较 以下是Google几年前发布的一组测试数据(数据有些老了,有人近期做过测试的话希望能共享出来):

淘宝在hbase中的应用和优化

本文来自于NoSQLFan联合作者@koven2049,他在淘宝从事Hadoop及HBase相关的应用和优化.对Hadoop.HBase都有深入的了解,本文就是其在工作中对HBase的应用优化小结,分享给大家. 目 录 [ - ] 前言 原因 应用情况 部署.运维和监控 测试与发布 改进和优化 将来计划 前言 hbase是从 hadoop中分离出来的apache顶级开源项目.由于它很好地用java实现了google的bigtable系统大部分特性,因此在数据量猛增的今天非常受到欢迎.对于淘宝而言

ZooKeeper原理及其在Hadoop和HBase中的应用

简介 ZooKeeper是一个开源的分布式协调服务,由雅虎创建,是Google Chubby的开源实现.分布式应用程序可以基于ZooKeeper实现诸如数据发布/订阅.负载均衡.命名服务.分布式协调/通知.集群管理.Master选举.分布式锁和分布式队列等功能. 基本概念 本节将介绍ZooKeeper的几个核心概念.这些概念贯穿于之后对ZooKeeper更深入的讲解,因此有必要预先了解这些概念. 集群角色 在ZooKeeper中,有三种角色: Leader Follower Observer 一

Hbase学习(八)Hbase中的Coprocessor

1.起因(Why HBase  Coprocessor) HBase作为列族数据库最经常被人诟病的特性包括:无法轻易建立"二级索引",难以执行求和.计数.排序等操作.比如,在旧版本的(<0.92)Hbase中,统计数据表的总行数,需要使用Counter方法,执行一次MapReduce Job才能得到.虽然HBase在数据存储层中集成了MapReduce,能够有效用于数据表的分布式计算.然而在很多情况下,做一些简单的相加或者聚合计算的时候,如果直接将计算过程放置在server端,能

HBase 中的 JVM 与 GC

HBase中JVM基本配置 在JVM中,默认情况下会设置minimum heap size 为 1/64 可用物理内存,并为maximum heap size设置 1/4 的物理可用内存(不过在Java8 之前,默认最大是1g).当然,我们可以通过手动指定 JVM 参数,配置JVM的内存,例如: -Xms10g -Xmx10g 在HBase 中,也可以在 hbase-env.sh 中显示指定堆内存大小,例如: # The maximum amount of heap to use. Defaul

Hbase中rowkey设计原则

Hbase中rowkey设计原则 1.热点问题 在某一时间段,有大量的数据同时对一个region进行操作 2.原因 对rowkey的设计不合理 对rowkey的划分不合理 3.解决方式 rowkey是hbase的读写唯一标识 最大长度是64KB. 4.核心原则 设计必须按照业务需求进行设计 5.长度原则 经验:10~100字节可以 官方:16字节,因为操作系统时8字节进行存储 6.散列原则 划分region是按照rowkey的头部进行划分. 有几种方式: )组合字段 id+timestamp )

kettle连接Hbase中数据导出(7)

http://wiki.pentaho.com/display/BAD/Extracting+Data+from+HBase+to+Load+an+RDBMS 1)新建转换——Big Data——Hbase Input双击打开 2)在hbase中创建表 3)点击Get table names 4)创建Mapping 在下图中单击Get table names按钮,从下拉列表中选择需要创建MAPPING的表名,在Mapping name中输入Mapping名称,然后再设置key字段,如下图 4)创

kettle连接Hbase中数据导入(8)

http://wiki.pentaho.com/display/BAD/Loading+Data+into+HBase 1)下载样本文件 到官网去下载 2)Hbase中建表 3)创建转换 3)配置Text file Input 5)配置content和Fields 6)添加HBase Output 7)配置HBase Output 8)配置Mapping 9)完成配置连接 10)保存运行 11)检查Hbase中数据