前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Hbase应知应会【2023-08-16】

Hbase应知应会【2023-08-16】

作者头像
火之高兴
发布2024-07-25 15:39:52
470
发布2024-07-25 15:39:52
举报
文章被收录于专栏:大数据应用技术

1. HBase 架构名词解释

Hbase的存储结构

Hbase 中的每张表都通过行键(rowkey)按照一定的范围被分割成多个子表(HRegion),默认一个HRegion 超过256M 就要被分割成两个,由HRegionServer管理,管理哪些 HRegion 由 Hmaster 分配。HRegion 存取一个子表时,会创建一个 HRegion 对象,然后对表的每个列族(Column Family)创建一个 store 实例, 每个 store 都会有 0 个或多个 StoreFile 与之对应,每个 StoreFile 都会对应一个HFile,HFile 就是实际的存储文件,一个 HRegion 还拥有一个 MemStore实例。

Name Space

命名空间,类似于关系型数据库的 DatabBase 概念,每个命名空间下有多个表。HBase 有两个自带的命名空间,分别是 hbase 和 default,hbase 中存放的是 HBase 内置的表,default 表是用户默认使用的命名空间。

Zookeeper

HBase 通过 Zookeeper 来做 Master 的高可用、RegionServer 的监控、元数据的入口以 及集群配置的维护等工作。

Row

HBase 表中的每行数据都由一个 RowKey 和多个 Column(列)组成,数据是按照 RowKey 的字典顺序存储的,并且查询数据时只能根据 RowKey 进行检索,所以 RowKey 的设计十分重 要。

Column

HBase 中的每个列都由 Column Family(列族)和 Column Qualifier(列限定符)进行限 定,例如 info:name,info:age。建表时,只需指明列族,而列限定符无需预先定义。

Time Stamp

用于标识数据的不同版本(version),每条数据写入时,如果不指定时间戳,系统会 自动为其加上该字段,其值为写入 HBase 的时间。

Cell

由{rowkey, column Family:column Qualifier, time Stamp} 唯一确定的单元。cell 中的数据是没有类型的,全部是字节数组形式存贮。

HMaster

Master 是所有 Region Server 的管理者,其实现类为 HMaster,主要作用如下: 对于表的操作:create, delete, alter 对于 RegionServer的操作:分配 regions到每个RegionServer,接收心跳,监控每个 RegionServer的状态,负载均衡和故障转移。

HRegionServer

Region Server 为 Region 的管理者,其实现类为 HRegionServer,主要作用如下: 对于数据的操作:get, put, delete; 对于 Region 的操作:splitRegion、compactRegion。 向Master发送心跳。

Region

类似于关系型数据库的表概念。不同的是,HBase 定义表时只需要声明列族即可,不需 要声明具体的列。这意味着,往 HBase 写入数据时,字段可以动态、按需指定。因此,和关 系型数据库相比,HBase 能够轻松应对字段变更的场景。

Store

Regin 的纵向拆分,按照表中列族的数量,由于会按照列族拆分,所以一张表查询数据时,如果只有一个列族时,就限定查找范围;一张表中的列族不建议过多。

MemStore

提高数据的写入速度,MemStore是Regin中的内存区域。用于写缓存,由于 HFile 中的数据要求是有序的,所以数据是先存储在 MemStore 中,排好序后,等到达刷写时机才会刷写到 HFile,每次刷写都会形成一个新的 HFile。

WAL

预写日志,由于数据要经 MemStore 排序后才能刷写到 HFile,但把数据保存在内存中会有很高的概率导致数据丢失,为了解决这个问题,数据会先写在一个叫做 Write-Ahead logfile 的文件中,然后再写入 MemStore 中。所以在系统出现故障的时候,数据可以通过这个日志文件 重建。

StoreFile

保存实际数据的物理文件,StoreFile 以 HFile 的形式存储在 HDFS 上。每个 Store 会 有一个或多个 StoreFile(HFile),数据在每个 StoreFile 中都是有序的。

HFile

用于存储表数据的文件格式,它的特点包括排序存储、键值对结构、压缩、数据块和索引、布隆过滤器等,提供了高效的数据存储和访问方式。一个StoreFile对应着一个HFile。

HDFS

HDFS 为 HBase 提供最终的底层数据存储服务,同时为 HBase 提供高可用的支持。

2. HBASE的读写流程

HBase是一个在Hadoop上构建的分布式列存储系统,它提供了高可靠性、高性能和可伸缩性的数据存储和访问能力。下面是HBase的读写流程的详细解释:

写入数据的流程:

在这里插入图片描述
在这里插入图片描述
  1. Client 先访问 zookeeper,获取 hbase:meta 表位于哪个 Region Server。
  2. 访 问 对 应 的 Region Server , 获 取 hbase:meta 表 , 根 据 读 请 求 的 namespace:table/rowkey,查询出目标数据位于哪个 Region Server 中的哪个 Region 中。并将该table的region信息以及meta表的位置信息缓存在客户端的meta cache,方便下次访问。
  3. 与目标 Region Server 进行通讯;
  4. 将数据顺序写入(追加)到 WAL;
  5. 将数据写入对应的 MemStore,数据会在 MemStore 进行排序;
  6. 向客户端发送 ack;
  7. 等达到 MemStore 的刷写时机后,将数据刷写到 HFile。

读取数据的流程:

在这里插入图片描述
在这里插入图片描述
  1. Client 先访问 zookeeper,获取 hbase:meta 表位于哪个 Region Server。
  2. 访问对应的 Region Server ,获取 hbase:meta 表,根据读请求的 namespace:table/rowkey,查询出目标数据位于哪个 Region Server 中的哪个 Region中。并将该table的region信息以及meta表的位置信息缓存在客户端的meta cache,方便下次访问。
  3. 与目标 Region Server 进行通讯;
  4. 分别在 Block Cache(读缓存),MemStore 和 Store File(HFile)中查询目标数据,并将查到的所有数据进行合并。此处所有数据是指同一条数据的不同版本(time stamp)或者不同的类型(Put/Delete)。
  5. 将从文件中查询到的数据块(Block,HFile 数据存储单元,默认大小为 64KB)缓存到 Block Cache。
  6. 将合并后的最终结果返回给客户端。

需要注意的是,HBase的写入操作使用了写缓冲区(Write Buffer)来提高写入性能。数据首先被写入到内存中的写缓冲区,然后定期刷写到磁盘上的HFile中。读取操作首先检查内存中的读缓存(MemStore),如果数据在其中存在,则可以直接返回,避免了磁盘的访问。这种机制使得HBase能够提供高性能的写入和读取能力。

另外,HBase的数据存储是按照行键的字典序进行排序的,相邻的行键会存储在相邻的Region中,这样可以提高数据的局部性和访问效率。同时,HBase还支持数据的自动分片和负载均衡,可以根据数据的增长和负载情况自动进行Region的划分和迁移,保证系统的可伸缩性和负载均衡性。

3. rowkey的设计原则

在这里插入图片描述
在这里插入图片描述

在HBase中,Row Key(行键)的设计非常重要,它直接影响了数据的存储和访问性能。以下是一些设计Row Key的原则:

3.1 长度原则:

  1. 长度限制:100字节以内,8的倍数最好,可能的情况下越短越好。因为HFile是按照 keyvalue 存储的,过长的rowkey会影响存储效率;其次,过长的rowkey在memstore中较大,影响缓冲效果,降低检索效率。最后,操作系统大多为64位,8的倍数,充分利用操作系统的最佳性能。
  2. 存储效率:长的RowKey会显著影响HFile存储的效率。如果RowKey过长,在HFile中存储的索引数据会变大,导致存储空间的浪费。
  3. 内存使用:HBase的MemStore会将部分数据缓存在内存中,用于加速读写操作。如果RowKey过长,会影响MemStore的内存利用效率,从而降低系统的性能。
  4. 操作系统对齐:现代操作系统通常是64位的,内存会以8字节对齐。因此,控制RowKey的长度在16个字节以内是有益的,可以最大程度地利用操作系统的内存管理特性。
  5. 传输效率:在系统间传输数据时,RowKey、列名、时间戳等信息会一起传输。如果RowKey很大,会增加数据传输的开销。
  6. 索引内存占用:HBase的索引数据会占用大量的内存。如果RowKey过大,索引数据会变得更庞大,从而影响内存的使用效率。

3.2 散列性原则

HBase散列性设计原则是在设计HBase表结构时需要考虑的重要因素,它能避免热点问题,即总是往存储最大行健的Region里写入数据,关乎数据在Region中的分布均衡和查询性能。以下是HBase散列性设计的原则:

1. 均匀散列分布: HBase会将相邻的RowKey存储在不同的Region中,为了实现负载均衡和避免“热点”问题,需要将数据尽可能均匀地分散到不同的Region中。使用散列函数将RowKey映射为一个固定长度的值,然后根据这个值来选择对应的Region。常用的散列函数有MD5、SHA,或者反转rowkey(处理1开头电话号时)。需要注意的是,散列函数的选择要保证散列值的随机性,以避免数据倾斜。

2. 加盐: 加盐处理散列是一种常见的方法,用于在散列过程中增加随机性,从而避免特定模式的数据分布和哈希碰撞问题。在HBase中,加盐处理散列可以通过以下方式实现:

随机盐值:为每个rowkey生成一个随机的盐值,可以是随机数,然后将盐值和原始RowKey组合在一起进行散列。这样相同的数据在加盐后会具有不同的散列值,从而实现更均匀的数据分布。

固定盐值:使用一个固定的盐值作为数据行的前缀或后缀,然后将组合后的值进行散列。这种方式可以保证相同数据行在不同表中的哈希值不同,避免数据倾斜。

3.3 顺序性

在HBase中,相邻的行键会存储在相邻的Region中,因此,设计Row Key时应尽量考虑数据的访问模式,使得相关的数据能够存储在相邻的位置,以提高查询的效率。例如,可以使用时间戳或者具有时间戳的前缀作为Row Key,使得最新的数据能够存储在相邻的Region中。

3.4 可扩展性

Row Key的设计应该具有良好的可扩展性,能够应对数据的增长和负载的变化。避免使用过长的Row Key,以减少存储空间的占用和索引的开销。

3.5 查询需求

根据实际的查询需求来设计Row Key,使得常用的查询能够高效地定位到数据。例如,如果经常需要根据某个属性进行范围查询,可以将该属性作为Row Key的一部分。

HBase的列簇设计

• 原则:在合理范围内能尽量少的减少列簇就尽量减少列簇,因为列簇是共享region的,每个列簇数据相差太大导致查询效率低下。 • 最优:将所有相关性很强的 key-value 都放在同一个列簇下,这样既能做到查询效率最高,也能保持尽可能少的访问不同的磁盘文件。以用户信息为例,可以将必须的基本信息存放在一个列族,而一些附加的额外信息可以放在另一列族。

4. HBase 中 compact 用途是什么,什么时候触发,分为哪两种,有什么区别,有哪些相关配置参数?

在HBase中,compact是用于合并和优化HBase表的操作。它的主要作用是减少存储空间的占用、提高读写性能并优化数据布局。

compact操作会合并小的存储单元(HFile)为更大的块,从而减少存储文件的数量和大小。它可以通过合并删除标记(Cell Tombstone)并清理过时的数据来释放存储空间。此外,compact还可以减少读取时需要扫描的文件数量,从而提高查询性能。

在HBase中,有两种类型的compact操作:

  1. Minor Compact(小型紧缩):这是最常见的compact操作类型。它会合并相邻的HFile,并且只会触发那些小于预设阈值(一般为hbase.hstore.compaction.min.size参数配置)的HFile进行合并。Minor Compact通常是在后台自动触发的,目的是将小的文件按照一定规则合并成较大的文件。
  2. Major Compact(大型紧缩):这是一种全局的、重量级的compact操作。它会合并整个HBase表甚至整个region的所有HFile。Major Compact可以进一步优化存储空间和读写性能,但可能需要更多的时间和资源。 Major Compact通常需要手动触发。

主要区别:

  • Minor Compact主要针对小的HFile进行合并,而Major Compact则合并整个表或整个region的所有HFile。
  • Minor Compact自动触发,而Major Compact需要手动触发。
  • Minor Compact时间较短,对系统性能的影响较小,而Major Compact可能需要更长的时间,并且可能会对系统的读写性能产生较大的影响。

一些常见的与compact相关的配置参数包括:

  • hbase.hstore.compactionThreshold: 触发Minor Compact的最小HFile数量。
  • hbase.hstore.compaction.min.size: 触发Minor Compact的HFile大小下限。
  • hbase.hstore.compaction.max.size: 触发Major Compact的HFile大小上限。
  • hbase.hstore.compaction.minhbase.hstore.compaction.max: 用于设置不同级别的压缩策略,以控制Compaction的优先级。

这些参数可以根据具体的业务需求和系统性能进行调优。

5. 解释Hbase预分区以及作用

在HBase中,预分区(Pre-Splitting)是一种在创建HBase表时事先划分表的行键范围,将表的数据分布到多个Region(区域)中的操作。它的作用是提前将数据在多个Region之间均匀分布,以实现负载均衡和并行处理。

预分区的作用是为了解决当一个 region 的大小超过一定的阈值时就会发生 split 的操作,这个过程会消耗大量的磁盘及网络 I/O,因此我们虽然需要 split 带来的稳定的查询性能但是又不希望花费 split 带来的 I/O cost,预分区就可以很好的解决这个问题。

预分区可以通过 HBase shell 命令来创建,例如:

代码语言:javascript
复制
create 't1', 'f1', {SPLITS => ['10', '20', '30', '40', '50']}

这个命令将表 t1 分成了 6 个 region,其中前 5 个 region 的范围是 [0, 10), [10, 20), …, [40, 50),最后一个 region 的范围是 [50, +∞)。⁵

预分区的作用如下:

  1. 负载均衡:通过预先划分表的行键范围并创建多个Region,可以确保数据在不同Region之间均匀分布。这样可以使查询和写入操作在不同的Region上并行进行,从而提高系统的读写性能和吞吐量,并减少单个Region的负载压力。
  2. 并行处理:预分区可以让多个Region并行处理数据,从而提高系统的并发能力。每个Region都有自己的存储和计算资源,可以独立处理并响应客户端请求。通过并行处理,可以更快地执行大量的读取和写入操作。
  3. 预防热点问题:在没有预分区的情况下,如果数据按照默认设置插入到一个Region,可能会导致这个Region成为热点,造成性能瓶颈。通过预分区,可以将数据均匀地分布在不同的Region上,避免了单个Region的过载。
  4. 灵活扩展:通过预分区,可以在表创建时预置一定数量的Region。这样,在需要扩展HBase集群时,可以避免手动进行Region的分裂和迁移操作,而是通过动态分配新的Region来实现集群的扩展。

总之,HBase的预分区使得数据能够在不同的Region上进行并行处理,提高了系统的读写性能、负载均衡和扩展性。通过合理划分行键范围,可以确保数据在各个Region之间分布均匀,减少热点和负载不平衡的问题。

6. HDFS和HBase各自使用场景

首先一点需要明白:Hbase是基于HDFS来存储的。 HDFS: • 一次性写入,多次读取。 • 保证数据的一致性。 • 主要是可以部署在许多廉价机器中,通过多副本提高可靠性,提供了容错和恢复机制。 HBase: • 瞬间写入量很大,数据库不好支撑或需要很高成本支撑的场景。 • 数据需要长久保存,且量会持久增长到比较大的场景。 • HBase不适用与有 join,多级索引,表关系复杂的数据模型。 • 大数据量(100s TB级数据)且有快速随机访问的需求。如:淘宝的交易历史记录。数据量巨大无容置疑,面向普通用户的请求必然要即时响应。 • 业务场景简单,不需要关系数据库中很多特性(例如交叉列、交叉表,事务,连接等等)。

7.热点现象

某个小的时段内,对HBase的读写请求集中到极少数的Region上,导致这些region所在的RegionServer处理请求量骤增,负载量明显偏大,而其他的RgionServer明显空闲。

热点现象出现的原因

HBase中的行是按照rowkey的字典顺序排序的,这种设计优化了scan操作,可以将相关的行以及会被一起读取的行存取在临近位置,便于scan。然而糟糕的rowkey设计是热点的源头。

热点发生在大量的client直接访问集群的一个或极少数个节点(访问可能是读,写或者其他操作)。大量访问会使热点region所在的单个机器超出自身承受能力,引起性能下降甚至region不可用,这也会影响同一个RegionServer上的其他region,由于主机无法服务其他region的请求。

热点现象解决办法

为了避免写热点,设计rowkey使得不同行在同一个region,但是在更多数据情况下,数据应该被写入集群的多个region,而不是一个。常见的方法有以下这些:

• 加盐:在rowkey的前面增加随机数,使得它和之前的rowkey的开头不同。分配的前缀种类数量应该和你想使用数据分散到不同的region的数量一致。加盐之后的rowkey就会根据随机生成的前缀分散到各个region上,以避免热点。

• 哈希:哈希可以使负载分散到整个集群,但是读却是可以预测的。使用确定的哈希可以让客户端重构完整的rowkey,可以使用get操作准确获取某一个行数据

• 反转:第三种防止热点的方法时反转固定长度或者数字格式的rowkey。这样可以使得rowkey中经常改变的部分(最没有意义的部分)放在前面。这样可以有效的随机rowkey,但是牺牲了rowkey的有序性。反转rowkey的例子以手机号为rowkey,可以将手机号反转后的字符串作为rowkey,这样的就避免了以手机号那样比较固定开头导致热点问题

• 时间戳反转:一个常见的数据处理问题是快速获取数据的最近版本,使用反转的时间戳作为rowkey的一部分对这个问题十分有用,可以用 Long.Max_Value - timestamp 追加到key的末尾,例如[key][reverse_timestamp],[key]的最新值可以通过scan [key]获得[key]的第一条记录,因为HBase中rowkey是有序的,第一条记录是最后录入的数据。

比如需要保存一个用户的操作记录,按照操作时间倒序排序,在设计rowkey的时候,可以这样设计[userId反转] [Long.Max_Value - timestamp],在查询用户的所有操作记录数据的时候,直接指定反转后的userId,startRow是[userId反转][000000000000],stopRow是[userId反转][Long.Max_Value - timestamp] 如果需要查询某段时间的操作记录,startRow是[user反转][Long.Max_Value - 起始时间],stopRow是[userId反转][Long.Max_Value - 结束时间]

• HBase建表预分区:创建HBase表时,就预先根据可能的RowKey划分出多个region而不是默认的一个,从而可以将后续的读写操作负载均衡到不同的region上,避免热点现象。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-08-16,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. HBase 架构名词解释
  • 2. HBASE的读写流程
    • 写入数据的流程:
      • 读取数据的流程:
      • 3. rowkey的设计原则
        • 3.1 长度原则:
          • 3.2 散列性原则
            • 3.3 顺序性
              • 3.4 可扩展性
                • 3.5 查询需求
                  • HBase的列簇设计
                  • 4. HBase 中 compact 用途是什么,什么时候触发,分为哪两种,有什么区别,有哪些相关配置参数?
                  • 5. 解释Hbase预分区以及作用
                  • 6. HDFS和HBase各自使用场景
                  • 7.热点现象
                    • 热点现象出现的原因
                      • 热点现象解决办法
                      相关产品与服务
                      对象存储
                      对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
                      领券
                      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档