HBase-宽表和高表的对比
一、宽表和高表定义
HBase 中的表可以设计为高表(tall-narrow table) 和 宽表(flat-wide table):
(1) 宽表是指很多列较少行,即列多行少的表,一行中的数据量较大,行数少;
(2) 高表是指很多行较少列,即行多列少,一行中的数据量较少,行数大。
二、宽表和高表的优劣
HBase的键分为两种:
(1) 列键:包括了列族名和限定符,定位到列的索引
(2) 行健:相当于关系型数据库中的主键,通过行健得到逻辑布局中一行的所有列
由于列键是由列族名和限定符组成的,属于定位具体 StoreFile 的,所以应该将需要查询的维度或者信息存储在 row key 中,因为用它来筛选数据效率最高!
Hbase 的 row key 是分布式的索引,也是分片的依据。Hbase 的 row key + column family + column qualifier + timestamp + value 是 HFile 中数据排列依据。
据此,在HBase中使用宽表、高表的优劣总结如下:
(1) 查询性能:高表查询更好,因为查询条件都在 row key 中,是全局分布式索引的一部分。高表一行中的数据较少。所以查询缓存 BlockCache 能缓存更多的行,以行数为单位的吞吐量会更高。
(2) 分片能力:高表分片粒度更细,各个分片的大小更均衡。HBase按行来分片,高表一行的数据较少,宽表一行的数据较多。
(3) 元数据开销:高表元数据开销更大。高表行多,row key 多,可能造成region 数量也多,- root -、 .meta 表数据量更大。过大的元数据开销,可能引起 HBase 集群的不稳定、master 更大的负担。
(4) 事务能力:宽表事务性更好。HBase对一行的写入(Put)是有事务原子性的,一行的所有列要么全部写入成功,要么全部没有写入。但是多行的更新之间没有事务性保证。
(5) 数据压缩比:如果我们对一行内的数据进行压缩,宽表能获得更高的压缩比。因为宽表中,一行的数据量较大,往往存在更多相似的二进制字节,有利于提高压缩比。通过压缩,缓解了宽表一行数据量太大,并导致分片大小不均匀的问题。查询时,根据 row key 找到压缩后的数据,进行解压缩。而且解压缩可以通过协处理器(coproesssor)在 HBase 服务器上做,而不是在业务应用的服务器上做,以充分应用 HBase 集群的CPU能力。
三、宽表和高表的应用场景
3.1、高表的应用
在一个电子邮箱系统中,将行健设置为用户的唯一ID,其余属性作为列族或者列族中的列,如此一来,同一个用户的所有邮件信息都会被存储在同一行中(因为他们的行健相同),这在大部分情况下是通用的,但是有些用户的邮件数量非常非常大,大到一行数据就超出了HFile 的最大限度,这样一来,宽表设计方式就出现了致命的缺陷:表数据无法拆分,更无法进行 HBase 的负载均衡等特性。
PS:也许会有疑问,HFile 和 Region 达到一定大小的时候不是会自动切分的吗? 这是因为HBase 只能按行切分,当行数量达到阈值的时候会根据行健进行切分。
解决这个问题更好的办法是代替宽表,设计一个高表: 可以将行健设置为用户Id + 邮件Id,这样一来,每封邮件都是单独的一行,将宽表中的行数据释放出来。
这样做的好处是:
(1) 行数量可以更容易的被拆分;
(2) 行健中包含关键的筛选信息(邮件 Id 被移到了 row key),用户可以直接根据行健定位到唯一的一封邮件;
(3) 拥有很好的扩展性,高表也是推荐的用法。
但是要使用高表还是宽表还要根据具体的业务场景来确定,因为在以上高表的设计中,同一用户的数据分布在多行中,用户不可能在一个简单的操作中修改一个收件箱的全局属性,因为这涉及到了原子性的操作,如果用户没有一次修改整个收件箱的需求时,这种设计是非常合适的,但是如果用户真的有这种需求,而且需求很大,那么宽表反而更加合适,因为 HBase 能够保证行级别的原子性。
3.2、宽表的应用
Hbase 宽表可以应用在社区系统中,比如 BBS:可以用帖子的 Url 地址作为row key 保存,而后面的每一个回复,作为列族中单独的列。回复越多,列族中单独的列就越多,表就变宽了。
设计表时,可以不绝对追求高表、宽表,而是在两者之间做好平衡。根据查询模式,需要分布式索引、分片、有很高选择度(即能据此查询条件迅速锁定很小范围的一些行)的查询用字段,应该放入row key;能够均匀地划分数据字节数的字段,也应该放入 row key,作为分片的依据。选择度较低,并且不需要作为分片依据的查询用字段,放入 column family 和 column qualifier,不放入row key。
HBase-宽表和高表的对比的更多相关文章
- Hadoop HBase概念学习系列之HBase里的高表设计概念(表设计)(二十八)
在下面这篇博文里,我给各位博客们,分享了创建HBase表,但这远不止打好基础. HBase编程 API入门系列之create(管理端而言)(8) 在关系型数据库里,表的高表和宽表是不存在的.在如HBa ...
- SQL Server 堆表与栈表的对比(大表)
环境准备 使用1个表,生成1000万行来进行性能对比(勉强也算比较大了),对比性能差别. 为了简化过程,不提供生成随机数据的过程.该表初始为非聚集索引(堆表),测试过程中会改为聚集索引(栈表). CR ...
- hbase操作(shell 命令,如建表,清空表,增删改查)以及 hbase表存储结构和原理
两篇讲的不错文章 http://www.cnblogs.com/nexiyi/p/hbase_shell.html http://blog.csdn.net/u010967382/article/de ...
- hive-内部表和外部表 对比
建表时,需要考虑究竟建内部表还是外部表,内部表和外部表都有哪些不同? 内部表: 1. 数据存储位置:数据最终会被移动到 hive.metastore.warehouse.dir指定的路径下,以表名创建 ...
- Hadoop HBase概念学习系列之META表和ROOT表(六)
在 HBase里的HRegion 里,谈过,HRegion是按照表名+开始/结束主键,即表名+主键范围来区分的.由于主键范围是连续的,所以一般用开始主键就可以表示相应的HRegion了. 不过,因为我 ...
- ORACLE创建表之前判断表是否存在与SQL Server 对比使用
在SQL Server 数据库中,我们在创建表之前删除表,有if exit()这样的语句,但是在oracle中却没有.如果直接使用drop table那么如果表不存在会报错,导致后续语句无法运行.因此 ...
- Oracle和MySQL的高可用方案对比【转】
关于Oracle和MySQL的高可用方案,其实一直想要总结了,就会分为几个系列来简单说说.通过这样的对比,会对两种数据库架构设计上的细节差异有一个基本的认识.Oracle有一套很成熟的解决方案.用我在 ...
- Mysql优化原则_小表驱动大表IN和EXISTS的合理利用
//假设一个for循环 ; $i < ; $i++) { ; $i < ; $j++) { } } ; $i < ; $i++) { ; $i < ; $j++) { } } ...
- Hive 文件格式 & Hive操作(外部表、内部表、区、桶、视图、索引、join用法、内置操作符与函数、复合类型、用户自定义函数UDF、查询优化和权限控制)
本博文的主要内容如下: Hive文件存储格式 Hive 操作之表操作:创建外.内部表 Hive操作之表操作:表查询 Hive操作之表操作:数据加载 Hive操作之表操作:插入单表.插入多表 Hive语 ...
- MySQL表结构,表空间,段,区,页,MVCC
索引组织表(IOT表):为什么引入索引组织表,好处在那里,组织结构特点是什么,如何创建,创建IOT的限制LIMIT. IOT是以索引的方式存储的表,表的记录存储在索引中,索引即是数据,索引的KEY为P ...
随机推荐
- Vue tinymce富文本编辑器整合
最近再弄一个后台管理系统,挑选了不少的编辑器,最终选择了tinymce,UI精美,功能模块多,可按需加载配置 vue cli 3 + tinymce5.0版本整合参考:https://liubing. ...
- ava进阶(39)--守护线程与定时器
文档目录: 一.守护线程 二.定时器 ---------------------------------------分割线:正文------------------------------------ ...
- python常见面试题讲解(三)明明的随机数
题目描述 明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了N个1到1000之间的随机整数(N≤1000),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对 ...
- C++ std::initializer_list 实现原理勘误
今天正在看侯捷<C++ 新标准 C++11-14>的视频,里面讲到 std::initializer_list 的实现原理,并且把源码贴出来. /// initializer_list t ...
- Java求一个集合的所有子集
转载请注明出处: 求一个集合的所有子集表示从一个集合当中,任取任意项或不取,所能得到的所有结果,比如有一个集合{a,b,c,d},那么{a,b}, {b, d}等都是它的子集,空集也是它的子集, 一个 ...
- Linux中使用Docker容器安装mysql,无法直接使用mysql命令?
1.问题 如果你在 Docker 容器中运行 MySQL,你不能在宿主主机上使用 mysql --version 命令来检查 MySQL 版本,因为 MySQL 客户端工具在宿主主机上未安装. 2.解 ...
- DDP运行报错(单卡无错):ERROR:torch.distributed.elastic.multiprocessing.api:failed (exitcode: 1)
使用DDP时出现错误,但是单卡跑无错误. 错误记录如下: RuntimeError: Expected to have finished reduction in the prior iteratio ...
- [转帖]kubernetes(k8s):容器资源限制(内存限制、cpu限制、namespace限制)
文章目录 1. k8s容器资源限制 2. 内存资源限制实例 3. cpu资源限制 4. namespace设置资源限制 5. namespace中pod的配额 6. namespace的创建.使用和删 ...
- 人大金仓学习之二_ksh和kddm的学习
人大金仓学习之二_ksh和kddm的学习 摘要 承接上一篇文章 主要是这里总结一下ksh相关的文档. 这里学习了很多文档: https://help.kingbase.com.cn/v8/perfor ...
- [转帖]Python基础之函数(四)
https://www.jianshu.com/p/168e341fb81c 一.函数定义 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段:比如常用的print(),就是内建函数:通 ...