史上最全HBase面试题,高薪必备,架构必备

说在前面

本文《尼恩 大数据 面试宝典》 是 《尼恩Java面试宝典》姊妹篇。

这里特别说明一下:《尼恩Java面试宝典》41个专题 PDF 自首次发布以来, 已经汇集了 好几千题,大量的大厂面试干货、正货 ,足足4800多页,帮助很多小伙伴进了大厂,拿了高薪

《尼恩Java面试宝典》面试题集合, 已经变成Java 学习和面试的必读书籍。

于是,尼恩架构团队 趁热打铁,推出 《尼恩 大数据 面试宝典》,已经发布了几个专题:

尼恩大数据面试宝典专题1:史上最全Hadoop面试题

尼恩大数据面试宝典专题2:绝密100个Spark面试题,熟背100遍,猛拿高薪

尼恩大数据面试宝典专题3:史上最全Hive面试题,不断迭代,持续升级

尼恩大数据面试宝典专题4:史上最全Flink面试题,不断迭代,持续升级

《尼恩大数据面试宝典专题5:史上最全HBase面试题,不断迭代,持续升级》(本文)

《尼恩 大数据 面试宝典》 后面会不断升级,不断 迭代, 变成 大数据领域 学习和面试的必读书籍,帮助大家成长为 三栖合一架构师,进了大厂,拿了高薪。

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》的PDF,请到公号【技术自由圈】取

文章目录

作者介绍

一作:Mark, 资深大数据架构师、Java架构师,近20年Java、大数据架构和开发经验。资深架构导师,成功指导了多个中级Java、高级Java转型架构师岗位。

二作:尼恩,41岁资深老架构师, IT领域资深作家、著名博主。《Java 高并发核心编程 加强版 卷1、卷2、卷3》创世作者。 《K8S学习圣经》《Docker学习圣经》《Go学习圣经》等11个PDF 圣经的作者。 也是一个 资深架构导师、架构转化 导师, 成功指导了多个中级Java、高级Java转型架构师岗位, 最高的学员年薪拿到近100W

史上最全HBase面试题

1、HBase是什么?

  1. HBase一个分布式的基于列式存储的NoSQL数据库,基于Hadoop的hdfs存储,zookeeper进行管理。
  2. HBase适合存储半结构化或非结构化数据,对于数据结构字段不够确定或者杂乱无章很难按一个概念去抽取的数据。
  3. HBase为null的记录不会被存储.
  4. 基于的表包含rowkey,时间戳,和列族。新写入数据时,时间戳更新,同时可以查询到以前的版本.
  5. HBase是主从架构。hmaster作为主节点,hregionserver作为从节点。

2、说说 HBase 的存储结构

HBase 是一个分布式、可扩展、高性能的列式存储系统,它基于 Google 的 Bigtable 设计。HBase 的主要存储结构包括表(Table)、区域(Region)、列族(Column Family)、列(Column)和值(Value)。

  1. 表(Table):表是 HBase 中的数据容器,由行键(rowkey)和列族(Column Family)组成。表可以在 HBase 中进行创建、删除和修改操作。
  2. 区域(Region):区域是表按照行键范围划分成的子集。每个区域都有一个起始行键(start key)和一个结束行键(end key),其中起始行键包含了该区域的所有数据,而结束行键则是该区域数据的最后一个行键。当一个区域的大小超过 256MB 时,HBase 会自动将其分割成两个子区域。
  3. 列族(Column Family):列族是表中列的逻辑分组。每个列族都有一个唯一的名称,用于标识表中的不同列。列族在 HBase 中用于存储具有相同性质的数据,例如,一个列族可以存储用户的基本信息,另一个列族可以存储用户的订单信息。
  4. 列(Column):列是表中数据的具体属性。每个列都有一个唯一的名称和数据类型,用于表示表中的具体数据。HBase 支持多种数据类型,如字符串、数字、日期等。
  5. 价值(Value):价值是表中存储的具体数据。每个值都有一个对应的列和行键,用于在表中存储和检索数据。

HBase 的存储结构还包括以下组件:

  1. HRegionServer:HRegionServer 是一个管理 HRegion 实例的服务。它负责创建、删除和修改 HRegion 实例,并确保它们在 HBase 集群中正确地分配和运行。
  2. HMaster:HMaster 是 HBase 集群中的主控制器。它负责管理 HRegionServer 实例,并为每个表分配适当的 HRegion 实例。HMaster 还负责处理集群中的备份和恢复操作。
  3. HRegion:HRegion 是表在 HBase 中的物理存储单元。它包含一个或多个 Store 实例,每个 Store 实例都对应一个或多个 StoreFile。StoreFile 是 HFile 的实例,而 HFile 是 HBase 中的实际存储文件。
  4. MemStore:MemStore 是 HBase 中的内存存储组件。它用于存储新写入的数据,并定期将其刷新到磁盘上的 StoreFile。
  5. Store:Store 是 HBase 中的存储管理组件。它用于在 MemStore 和磁盘上的 StoreFile 之间进行数据同步,以确保数据的持久性和一致性。

总之,HBase 的存储结构由表、区域、列族、列和值组成,这些组件通过 HRegionServer、HMaster 和 Store 等组件进行管理。这种结构使得 HBase 具有高性能、可扩展性和高可用性,能够轻松地处理海量数据。

3、说说 HBase 详细架构及内部机制

HBase采用Master/Slave架构搭建集群,它隶属于Hadoop生态系统,由一下类型节点组成: HMaster 节点、HRegionServer 节点、 ZooKeeper 集群,而在底层,它将数据存储于HDFS中,因而涉及到HDFS的NameNode、DataNode等,总体结构如下:

各组件说明:

Client

访问数据的入口,包含访问HBase的API接口,维护着一些cache来加快对HBase的访问

  1. 使用HBase RPC机制与HMaster和HRegionServer进行通信;

  2. Client与HMaster进行通信进行管理类操作;

  3. Client与HRegionServer进行数据读写类操作;

HMaster:NAMENODE RESOURCEMANAGER

HMaster 没有单点问题,HBase中可以启动多个HMaster,通过Zookeeper保证总有一个Master在运行。

HMaster主要负责Table和Region的管理工作:

  1. 管理用户对表的增删改查操作;

  2. 管理HRegionServer的负载均衡,调整Region分布;

  3. Region Split后,负责新Region的分布;

  4. 在HRegionServer停机后,负责失效HRegionServer上Region 的迁移;

HRegionServer:DATANODE NODEMANAGER

HBase中最核心的模块;

  1. 维护region,处理对这些region的IO请求;

  2. Regionserver负责切分在运行过程中变得过大的region;

Zookeeper

  1. zookeeper的选举机制保证任何时候,集群中只有一个master

  2. 实时监控Region Server的状态,将Region server的上线和下线信息实时通知给Master

  3. 存储HBase的schema

  4. 存贮所有Region的寻址入口

4、说说HBase 的特点

  1. 海量存储:可以存储大批量的数据。

  2. 列(簇)式存储:HBase表的数据是基于列族进行存储的,列族是在列的方向上的划分。

  3. 极易扩展:底层依赖HDFS,当磁盘空间不足的时候,只需要动态增加 datanode节点服务(机器)就可以了;可以通过增加服务器来提高集群的存储能力。

  4. 高并发:支持高并发的读写请求。

  5. 稀疏:稀疏主要是针对HBase列的灵活性,在列族中,你可以指定任意多的列,在列数据为空的情况下,是不会占用存储空间的。

  6. 数据的多版本:HBase表中的数据可以有多个版本值,默认情况下是根据版本号去区分,版本号就是插入数据的时间戳。

  7. 数据类型单一:所有的数据在HBase中是以字节数组进行存储。

5、说说HBase 和 Hive 的区别?

HBaseHive
类型列式数据库数据仓库
内部机制数据库引擎MapReduce
增删改查都支持只支持导入和查询
Schema只需要预先定义列族,不需要具体到列列可以动态修改需要预先定义表格
应用场景实时离线处理
特点以K-V形式存储类SQL

Hive是一种类SQL的引擎,并且运行MapReduce任务,HBase是一种在Hadoop之上的NoSQL 的Key/vale数据库。

HBase运行在hdfs上,和hive不一样,HBase能够在数据库上实时运行,而不是运行MapReduce任务。

应用场景

Hive适合用来对一段时间内的数据进行分析查询,例如,用来计算趋势或者网站的日志。Hive不应该用来进行实时的查询。因为它需要很长时间才可以返回结果。

HBase非常适合用来进行大数据的实时查询。

6、说说 HDFS 和 HBase 各自使用场景

首先一点需要明白:Hbase是基于HDFS来存储的。

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

7、为什么 HBase 查询比较快?

主要原因是由其架构和底层的数据结构决定的,即由LSM-Tree(Log-Structured Merge-Tree)+HTable(region分区)+Cache决定。

客户端可以直接定位到要查数据所在的Hregion-server服务器,然后直接在服务器的一个region上查找要匹配的数据,并且这些数据部分是经过cache缓存的。

HBase会将数据保存到内存中,在内存中的数据是有序的,如果内存空间满了,会刷写到HFile中,而在HFile中保存的内容也是有序的。当数据写入HFile后,内存中的数据会被丢弃.HFile文件为磁盘顺序读取做了优化。

HBase的写入速度快是因为他其实并不是真的立即写入文件中,而是先写入内存,随后异步刷入HFile。所以在客户端看来,写入数据速度很快。另外,写入时候随机写入转换成顺序写,数据写入速度也很稳定。读取速度很快是因为他使用了LSM树形结构,而不是B或B+树。 磁盘顺序读取速度很快,但是相比而言,寻找磁道的速度就要慢很多。HBase的存储结构导致他需要磁盘寻道时间在可预测范围内,并且读取与所要查询的rowkey连续的任意数量的记录都不会引发额外的寻道开销。比如有五个存储文件,那么最多需要5次磁盘寻道就可以。而关系型数据库,即使有索引,也无法确定磁盘寻道次数。而且,HBase读取首先会在缓存(BlockCache)中查找,它采用了LRU(最近最少使用算法),如果缓存中没找到,会从内存中的MemStore中查找,只有这两个地方都找不到时,才会加载HFile中的内容。

8、说说 HBase 的 rowKey 的设计原则?

1. 散列原则:

如果是rowkey按照时间戳或者是顺序递增

那么将会产生热点现象 建议将rowkey的高位作为散列字段,由程序随机生成,低位放时间字段,这样将提高数据均衡分布在每个RegionServer,以实现负载均衡的几率

2. 长度原则:

RowKey的长度不宜过长,不宜超过16个字节,最大长度64kb,实际应用中一般为10-100bytes,以byte[]形式保存。一条数据是根据rowkey来当成索引的,如果过长就会快速占据memstore的128M,然后被刷写到磁盘,也就是说相同的空间存贮的内容被rowkey占据了一大部分,减少了主要内容的存贮。

3. 唯一原则:

必须在设计上保证其唯一性, rowkey可以锁定唯一的一行数据,rowkey重复的话后put的数据会覆盖前面插入的数据

9、说说 HBase 中 scan 和 get 的功能以及实现的异同

HBase的查询实现只提供两种方式:

1.按指定RowKey 获取唯一一条记录,get方法(org.apache.hadoop.HBase.client.Get)Get 的方法处理分两种 : 设置了ClosestRowBefore 和没有设置的rowlock .主要是用来保证行的事务性,即每个get 是以一个row 来标记的.一个row中可以有很多family 和column.

2.按指定的条件获取一批记录,scan方法(org.apache.Hadoop.HBase.client.Scan)实现条件查询功能使用的就是scan 方式.

1)scan 可以通过setCaching 与setBatch 方法提高速度(以空间换时间);

2)scan 可以通过setStartRow 与setEndRow 来限定范围([start,end)start 是闭区间,end 是开区间)。范围越小,性能越高。

3)scan 可以通过setFilter 方法添加过滤器,这也是分页、多条件查询的基础。

10、详细谈谈 HBase 中一个 cell 的结构?

HBase中的Cell表示的是表中的单元格,由{rowkey, column Family:columu, version} 唯一确定的单元。cell中的数据是没有类型的,全部是字节码形式存贮。其中 version 就是这个单元格中的 Time Stamp。

在 HBase 中,一个 cell 的结构由以下三个部分组成:

  1. rowkey:rowkey 是 cell 的唯一标识,用于唯一确定表中的每一行数据。rowkey 通常是一个字符串,由自然键(如 ID、用户名等)或组合键(如城市、省份、国家等)组成。
  2. column family:column family 是 cell 中的一个属性,用于标识 cell 所属的列族。列族是一个逻辑概念,用于将表中的列划分为不同的组。每个列族都有一个唯一的名称,用于标识该列族。
  3. column:column 是 cell 中的另一个属性,用于标识 cell 所属的列。列是一个逻辑概念,用于将表中的数据划分为不同的列。每个列都有一个唯一的名称,用于标识该列。

version:version 是 cell 的时间戳,用于记录 cell 的创建时间或修改时间。在 HBase 中,每个 cell 都有一个唯一的时间戳,用于唯一确定该 cell 的版本。

数据:data 是 cell 中存储的数据,数据类型可以是任何字节码形式。在 HBase 中,数据是以字节码形式存储的,而不是特定的数据类型。这种存储方式使得 HBase 可以存储任何类型的数据,例如文本、图片、音频等。

值:value 是 cell 中存储的实际数据值。在 HBase 中,值是由字节码形式存储的,而不是特定的数据类型。这种存储方式使得 HBase 可以存储任何类型的数据,例如文本、图片、音频等。

HBase 中的 cell 是表中的基本存储单元,由 rowkey、column family、column 和 version 唯一确定。cell 中的数据是以字节码形式存储的,可以是任何类型的数据。

11、HBase 中分布式存储的最小单元是什么?

在 HBase 中,分布式存储的最小单元是 Region。每个 Region 都是一个独立的存储单元,包含一个或多个 StoreFile。Region 是 HBase 中数据存储和访问的基本单位,也是 HBase 中分布式存储和负载均衡的基础。

然而,Region 并不是存储的最小单元。在 HBase 中,存储的最小单元是 StoreFile。StoreFile 是 HBase 中的数据存储文件,每个 StoreFile 都包含一个或多个列族的数据。StoreFile 的大小通常由

HBase.hstore.compactionThreshold 和 HBase.hstore.blockingStoreFiles 参数控制。当一个 StoreFile 的大小达到 compactionThreshold 时,HBase 会自动将其 compact 成一个更大的 StoreFile。当一个 StoreFile 的大小超过 blockingStoreFiles 参数设定的值时,HBase 会将其拆分成多个更小的 StoreFile。

因此,虽然 Region 是分布式存储的最小单元,但 StoreFile 才是 HBase 中存储的最小单元。

12、请描述如何解决 HBase 中 region 太小和 region 太大带来的冲突.

在 HBase 中,region 太小和 region 太大都可能导致性能问题和数据丢失。

下面是一些解决这些问题的方法:

  1. 调整 HBase.hregion.max.filesize:可以通过调整 HBase.hregion.max.filesize 参数来控制每个 region 的最大文件大小。默认情况下,该参数为256m。如果 region 太小,可以适当增加该参数值,以减少 split 操作的数量。如果 region 太大,可以适当减小该参数值,以避免 compaction 操作过多。
  2. 调整 HBase.hregion.min.size:可以通过调整 HBase.hregion.min.size 参数来控制每个 region 的最小大小。默认情况下,该参数为 1GB。如果 region 太小,可以适当增加该参数值,以减少 split 操作的数量。如果 region 太大,可以适当减小该参数值,以避免 compaction 操作过多。
  3. 使用 RegionSplitter 工具:RegionSplitter 工具可以帮助您在 HBase 中拆分过大的 region。可以使用以下命令来拆分 region:
hbase regionsplit --region=region_name  
  1. 预分区:预分区是一种避免 region 分裂的方法。在 HBase 中,可以使用预分区来创建一定数量的 region,以避免在数据写入时频繁进行 split 操作。预分区可以通过以下命令来实现:
hbase create_table -p 预分区_参数  

其中,预分区参数指定了要创建的 region 数量。

通过调整 HBase.hregion.max.filesize 和 HBase.hregion.min.size 参数、使用 RegionSplitter 工具和预分区方法,可以有效地解决 HBase 中 region 太小和 region 太大带来的冲突。

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

在 HBase 中,compact 用于合并多个 storefile,从而减少磁盘上的文件数量,提高查询效率。Compact 操作会清理过期数据和删除标记,从而避免数据丢失和磁盘空间浪费。

Compact 的作用:

  1. 合并文件
  2. 清除过期,多余版本的数据
  3. 提高读写数据的效率

ompact 的触发条件是当 storefile 的大小达到一定程度时,HBase 系统会自动触发 compaction 操作。这个大小的阈值可以通过配置参数来设置,例如通过修改 hbase.hstore.compactionThreshold 和 hbase.hstore.compaction.max 参数来调整。

HBase 中实现了两种compaction 的方式:minor 和 major。

  • Minor compaction 主要用于合并多个 storefile,并对数据进行版本合并和删除标记清理。

  • Major compaction 则是对整个 Region 的所有 storefile 进行合并,最终生成一个更大的 storefile。

Minor compaction 和 major compaction 的区别在于合并的范围和执行的频率。

  • Minor compaction 只合并一个 storefile,执行频率较高,通常每隔一定时间就会触发。
  • Major compaction 合并整个 Region 的所有 storefile,执行频率较低,通常在 Minor compaction 执行一定次数后才会触发。

在 HBase 中,compact 相关的配置参数主要包括:

  1. hbase.hstore.compactionThreshold:指定一个 storefile 的大小阈值,当 storefile 大小达到该阈值时,会触发 minor compaction 操作。
  2. hbase.hstore.blockingStoreFiles:指定一个 storefile 的数量阈值,当一个 Region 中的 storefile 数量达到该阈值时,会触发 major compaction 操作。
  3. hbase.hstore.compaction.max:指定一个 storefile 的最大大小,当 storefile 大小达到该阈值时,会触发 minor compaction 操作。
  4. hbase.hstore.compaction.min:指定一个 storefile 的最小大小,当 storefile 大小小于该阈值时,不会触发 compaction 操作。

此外,还可以通过调整 HBase 的其他参数来优化 compaction 操作,例如调整 memstore.size.上限、刷新和 Compaction 策略等。

14、每天百亿数据存入HBase,如何保证数据的存储正确和在规 定的时间里全部录入完毕,不残留数据?

需求分析:
  1. 百亿数据:证明数据量非常大;

  2. 存入HBase:证明是跟HBase的写入数据有关;

  3. 保证数据的正确:要设计正确的数据结构保证正确性;

  4. 在规定时间内完成:对存入速度是有要求的。

解决思路:
  1. 数据量百亿条,什么概念呢?假设一整天60x60x24 = 86400秒都在写入数据,那么每秒的
    写入条数高达100万条,HBase当然是支持不了每秒百万条数据的,所以这百亿条数据可能不是通
    过实时地写入,而是批量地导入。批量导入推荐使用BulkLoad方式(推荐阅读:Spark之读写HBase),性能是普通写入方式几倍以上;

  2. 存入HBase:普通写入是用JavaAPI put来实现,批量导入推荐使用BulkLoad;

  3. 保证数据的正确:这里需要考虑RowKey的设计、预建分区和列族设计等问题;

  4. 在规定时间内完成也就是存入速度不能过慢,并且当然是越快越好,使用BulkLoad。

15、HBase 如何进行预分区以及作用?

HBase默认建表时有一个region。这个region的rowkey是没有边界的,即没有startkey和endkey,在数据写入时,所有数据都会写入这个默认的region,随着数据的不断增加,此region已经不能承受不断增长的数据量,会进行split,分成2个region.。在此过程中,会产生两个问题:

  1. 数据往一个region上写,会有写热点问题.
  2. region split会消耗宝贵的集群I/O资源.

基于此我们可以控制在建表的时候,创建多个空region,并确定每个region的起始和终止rowkey,这样只要我们的rowkey设计能均匀的命中各个region,就不会存在写热点问题。自然split的几率也会大大降低。当然随着数量的不断增长,该split的还是要进行split。像这样预先创建HBase表分区的方式,称之为预分区

创建预分区可以通过shell或者java代码实现

#以下是shell方式
#指明分割点
create 't1','f1',SPLITS=>['10','20','30','40']
#HexStringSplit指明分割策略,-c 10 指明要分割的区域数量,-f指明表中的列族,用":"分割
HBase org.apache.hadoop.HBase.util.RegionSpliter test_table HexStringSplit -c 10 -f f1
#根据文件创建分区并压缩
create 'split_table_test',{NAME => 'cf',COMPRESSION => 'SNAPPY'},{SPLITS_FILE => 'region_split_info.txt'}

16、HRegionServer 宕机如何处理?

  1. ZooKeeper 会监控 HRegionServer 的上下线情况,当 ZK 发现某个 HRegionServer 宕机之后会通知 HMaster 进行失效备援;

  2. 该 HRegionServer 会停止对外提供服务,就是它所负责的 region 暂时停止对外提供服务;

  3. HMaster 会将该 HRegionServer 所负责的 region 转移到其他 HRegionServer 上,并且会对 HRegionServer 上存在 memstore 中还未持久化到磁盘中的数据进行恢复;

  4. 这个恢复的工作是由 WAL 重播来完成,这个过程如下:

  • wal 实际上就是一个文件,存在/HBase/WAL/对应 RegionServer 路径下。

  • 宕机发生时,读取该 RegionServer 所对应的路径下的 wal 文件,然后根据不同的region 切分成不同的临时文件 recover.edits。

  • 当 region 被分配到新的 RegionServer 中,RegionServer 读取 region 时会进行是否存在 recover.edits,如果有则进行恢复。

17、以 start-HBase.sh 为起点,HBase 启动的流程是什么?

start-HBase.sh 的流程如下:

  1. 运行HBase-config.shh, base-config.sh的作用:

1)装载相关配置,如HBase_HOME目录,conf目录,regionserver机器列表,JAVA_HOME 目录等,它会调用$HBase_HOME/conf/HBase-env.sh

2)解析参数(0.96 版本及以后才可以带唯一参数 autorestart,作用就是重启)

3)调用 HBase-daemon.sh 来启动 master

4)调用 HBase-daemons.sh 来启动 regionserver zookeeper master-backup

  1. HBase-env.sh 的作用:主要是配置 JVM 及其 GC 参数,还可以配置 log 目录及参数,配置是否需要 HBase 管理 ZK,配置进程 id 目录等

  2. HBase-daemons.sh 的作用:根据需要启动的进程,如 zookeeper,则调用 zookeepers.sh如 regionserver,则调用 regionservers.sh如 master-backup,则调用 master-backup.sh

  3. zookeepers.sh 的作用:如果 HBase-env.sh 中的 HBase_MANAGES_ZK"=“true”,那么通过ZKServerTool这个类解析xml配置文件,获取 ZK 节点列表,然后通过 SSH 向这些节点发送远程命令执行。

  4. regionservers.sh 的作用:与 zookeepers.sh 类似,通过配置文件,获取 regionserver 机器列表,然后 SSH 向这些机器发送远程命令:6.master-backup.sh 的作用:通过 backup-masters 这个配置文件,获取 backup-masters 机器列表,然后 SSH 向这些机器发送远程命令。

18、说说 HBase 的查询方式

HBase 是一个分布式、可扩展、高性能的列式存储系统,它支持多种查询方式以满足不同场景的需求。

以下是 HBase 的查询方式的详细描述:

  1. 全表查询:使用 scan 方法对整个表进行查询。例如,要查询名为 myTable 的表,可以使用以下命令:
Scanner scanner = connection.createScanner(Bytes.toBytes("myTable"));  
  1. 基于 rowkey 的单行查询:使用 get 方法按 rowkey 获取单行数据。例如,要获取 rowkey 为 "1" 的数据,可以使用以下命令:
Result result = connection.get(Bytes.toBytes("myTable"), Bytes.toBytes("1"));  
  1. 基于 rowkey 的范围扫描:使用 scan 方法进行基于 rowkey 的范围扫描。例如,要查询 rowkey 从 "1""2" 的数据,可以使用以下命令:
Scanner scanner = connection.createScanner(Bytes.toBytes("myTable"));  
scanner.setStartRow(Bytes.toBytes("1"));  
scanner.setStopRow(Bytes.toBytes("2"));  
  1. get scan 方法的其他用法

1)按指定的 rowkey 获取唯一一条数据,使用 get 方法。get 方法分为两种,分别是设置了 closestRowBefore 和没有设置的 rowlock。只要保证行的事务性,即每一个 get 以一个 row 来标记的,一个 row 中可以有多个 family 和 column。例如,获取 rowkey 为 "1" 的第一列数据,可以使用以下命令:

Result result = connection.get(Bytes.toBytes("myTable"), Bytes.toBytes("1"), Bytes.toBytes("column1"));  

2)按指定的条件获取一批记录,使用 scan 方法进行条件查询。scan 方法可以通过以下方式进行优化:

使用 setCachingsetBatch 方法来提高速度。例如,设置每次 RPC 请求返回的行数为 10,可以使用以下命令:

Scanner scanner = connection.createScanner(Bytes.toBytes("myTable"));  
scanner.setCaching(10);  

使用 setStartRowsetEndRow 方法来限定范围(左闭右开)。例如,要查询 rowkey 从 "1""2" 的数据,可以使用以下命令:

Scanner scanner = connection.createScanner(Bytes.toBytes("myTable"));  
scanner.setStartRow(Bytes.toBytes("1"));  
scanner.setStopRow(Bytes.toBytes("2"));  

使用 setFilter 方法来添加过滤器。例如,要查询列族 cf 中的列 column1,可以使用以下命令:

Scanner scanner = connection.createScanner(Bytes.toBytes("myTable"));  
scanner.setFilter(new SingleColumnFilter(Bytes.toBytes("cf"), Bytes.toBytes("column1")));  

总之,HBase 提供了多种查询方式以满足不同场景的需求。根据实际应用场景选择合适的查询方式,可以提高 HBase 的性能。

19、说说 HBase 的读写流程

1. HBase 的读流程:

1)HRegisonServer保存着.meta.表及数据表,首先client先访问zk,访问-ROOT-表,然后在zk上面获取.meta.表所在的位置信息,找到这个meta表在哪个HRegionServer上面保存着。

2)接着client访问HRegionServer表从而读取.meta.进而获取.meta.表中存放的元数据。

3)client通过.meta.中的元数据信息,访问对应的HRegionServer,然后扫描HRegionServer的Memstore和StoreFile来查询数据。

4)最后把HRegionServer把数据反馈给client。

2. HBase 的写流程:

1)client访问zk中的-ROOT-表,然后后在访问.meta.表,并获取.meta.中的元数据。

2)确定当前要写入的HRegion和HRegionServer。

3)clinet向HRegionServer发出写相应的请求,HRegionServer收到请求并响应。

4)client先将数据写入到HLog中,以防数据丢失。

5)然后将数据写入到MemStore中。

6)如果HLog和MemStore都写入成功了,那么表示这个条数据写入成功了。

7)如果MemStore写入的数据达到了阈值,那么将会flush到StoreFile中。

8)当StoreFile越来越多,会触发Compact合并操作,将过多的StoteFile合并成一个大的StoreFile。

9)当StoreFile越来越多时,Region也会越来越大,当达到阈值时,会触发spilit操作,将这个Region一分为二。

ps:HBase中所有的更新和删除操作都会在后续的compact中进行,使得用户的写操作只需要进入内存中就行了。实现了HBase的 I/O高性能。

20、请描述HBase的flush流程

HBase 的 flush 流程是指将内存中的数据写入磁盘的过程,它分为三个阶段:prepare、flush 和 commit。下面对这三个阶段进行详细描述:

1. prepare 阶段:
  • 添加 updateLock 锁,阻塞写请求。目的是确保在 prepare 阶段,没有其他的写请求进入,以保证数据的一致性和完整性。

  • 遍历 MemStore,将 MemStore 中的数据集 CellSkipSet 做一个快照 Snapshot。快照 Snapshot 是一个只读的、不可变的数据集,用于在 flush 阶段将数据写入磁盘。

  • 新建 CellSkipListSet,用于保存后续的写入数据。这一步是为了隔离准备阶段和 flush 阶段的数据,以便在 flush 阶段将数据写入磁盘时,不会影响到准备阶段的数据。

  • 阶段结束,释放 updateLock 锁。

2. flush 阶段:
  • 遍历所有的 Memstore,将 prepare 阶段生成的 snapshot 文件持久化到.tmp 目录下,生成临时文件。这一步是将准备阶段的数据写入磁盘的过程,由于涉及到磁盘 I/O 操作,所以相对耗时。

  • 刷新缓存,将新生成的 HFile 添加到缓存中。

3. commit 阶段:
  • 遍历 memstore,将临时文件移动到指定的 ColumnFamily 目录下。这一步是将 flush 阶段生成的临时文件替换掉准备阶段的 Snapshot,完成数据的持久化。

  • 针对 HFile 生成对应的 storefile 和 Reader,把 storefile 添加到 HStore 的 storefiles 列表中。

  • 最后再清空 prepare 阶段生成的 snapshot。

HBase 的 flush 流程旨在确保数据的一致性、完整性和高效性。通过将内存中的数据写入磁盘,可以释放内存资源,以便后续的读写操作。同时,flush 流程的设计也保证了数据在写入磁盘过程中的高可用性和可靠性。

21、HBase 在进行模型设计时重点在什么地方?一张表中定义多少个 Column Family 最合适?为什么?

HBase 是一个面向列的数据库,所以在进行模型设计时,重点在于如何高效地存储和查询数据。HBase 的设计目标是尽可能地利用列存储和查询的优势,提高系统的性能和可扩展性。

在设计 HBase 模型时,需要关注以下几个方面:

  1. 列族的设计:列族是 HBase 中列的集合,一个表可以包含多个列族。列族在存储和查询时具有独立的特性,因此需要根据数据的访问模式和特点来设计列族。一般来说,划分标准是根据数据访问频度,如一张表里有些列访问相对频繁,而另一些列访问很少,这时可以把这张表划分成两个列族,分开存储,提高访问效率。

  2. 列的设计:列是 HBase 中数据的基本单元,一个表可以包含多个列。在设计列时,需要考虑数据的类型、长度和访问频度等因素,以便合理地分配存储资源和提高查询效率。HBase 中的列数据类型包括字节数组、字符串、数字、日期等,每个列都有对应的数据类型和长度限制。

  3. 行键的设计:行键是 HBase 中数据的唯一标识,通过行键可以快速地定位和查询数据。在设计行键时,需要考虑数据的唯一性、分区性和排序性等因素,以便合理地分配存储资源和提高查询效率。HBase 支持两种行键类型,分别是自然行键和合成行键。自然行键是数据的自然标识,如 ID、用户名等;合成行键是由多个字段组合而成的,如时间、地点、用户名等。

  4. 二级索引的设计:HBase 对于多条件的组合查询支持不好,一般 HBase 的查询都是通过 RowKey(要把多条件组合查询的字段都拼接在 RowKey 中显然不太可能),或者全表扫描再结合过滤器筛选出目标数据 (太低效)。因此,通过设计 HBase 的二级索引可以提高查询效率。二级索引是基于行键的,可以通过索引定位到具体的行,然后再进行查询。

在一张表中定义多少个 Column Family 最合适,这个问题没有一个确切的答案,因为 Column Family 的个数具体看表的数据。一般来说,划分标准是根据数据访问频度,如一张表里有些列访问相对频繁,而另一些列访问很少,这时可以把这张表划分成两个列族,分开存储,提高访问效率。

另外,也需要考虑数据的类型、长度和访问模式等因素,以便合理地分配存储资源和提高查询效率。在实际应用中,根据业务场景和数据特点进行合理的列族和列的设计,以及行键和二级索引的设计,以最大化地利用 HBase 的存储和查询优势。

22、如何提高 HBase 客户端的读写性能?请举例说明

提高 HBase 客户端的读写性能需要从多个方面进行优化。

以下是一些可能有用的优化方法:

  1. 开启 bloomfilter 过滤器。Bloomfilter 是一种数据结构,用于判断一个 key 是否可能存在于某个集合中。在 HBase 中,开启 bloomfilter 可以显著提高读性能。根据实际测试,开启 bloomfilter 比没开启要快 3、4 倍。

  2. 配置足够的内存。HBase 对于内存有特别的需求,因为它需要存储大量的数据和索引。在硬件允许的情况下,为 HBase 配置足够的内存可以提高读写性能。可以通过修改 HBase-env.sh 文件来设置 Java Heap Size。例如:

export HBase_HEAPSIZE=3000 # 这里默认为 1000m  
  1. 增大 RPC 数量。RPC(远程过程调用)是 HBase 区域服务器(RegionServer)之间通信的方式。通过增大 RPC 数量,可以提高 HBase 集群的并发处理能力。可以修改 HBase-site.xml 文件中的 HBase.regionserver.handler.count 属性来适当放大 RPC 数量。默认值为 10,可以根据实际情况适当调整。

  2. 优化 Compaction 策略。Compaction 是 HBase 中一种重要的性能优化手段,用于合并多个 MemStore 文件为一个更大的文件。优化 Compaction 策略可以提高 HBase 的读写性能。HBase 提供了多种 Compaction 策略,可以根据实际情况选择合适的策略。

  3. 使用适当的缓存策略。HBase 提供了两种缓存策略:LRU(最近最少使用)和 LRU_CLOCK。使用适当的缓存策略可以提高 HBase 的读性能。可以通过修改 hbase.hstore.compactionThreshold 和 hbase.hstore.blockingStoreFiles 属性来配置缓存策略。

  4. 合理设置 MemStore 大小。MemStore 是 HBase 中存储数据的内存结构。合理设置 MemStore 大小可以避免频繁的 Compaction 操作,从而提高读性能。可以通过修改 hbase.hstore.memstore.size 属性来设置 MemStore 大小。

  5. 合理配置读写负载。合理分配读写负载可以提高 HBase 的性能。可以通过为不同的客户端分配不同的区域(Region)来实现。

总之,优化 HBase 客户端的读写性能需要从多个方面进行考虑,包括内存配置、Compaction 策略、缓存策略、MemStore 大小以及读写负载的分配等。根据实际情况调整这些参数,可以显著提高 HBase 的性能。

23、HBase 热点现象(数据倾斜)怎么产生的,以及解决方法有哪些?

热点现象

某个小的时段内,对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上,避免热点现象。

24、谈谈 HBase 的大合并、小合并?

HBase 中的大合并和小合并都是针对 HFile 文件的管理操作。HFile 是 HBase 中的存储文件,每个 HFile 文件都包含一个或多个 Region 的数据。当数据在 HFile 文件中被删除时,该记录会被打上标记 DeleteColumn,并且使用 get 和 scan 查询不到,但是该记录仍然存在于 HFile 文件中。

  • 大合并:是指将一个 Region 的所有 HFile 文件合并成一个 HFile 文件。在大合并过程中,HBase 会首先将所有 HFile 文件中的数据进行合并,然后将合并后的数据写入一个新的 HFile 文件中。在这个过程中,HBase 会删除标记为 DeleteColumn 的记录,从而真正删除这些记录。大合并通常在 HBase 集群中进行,以确保数据的一致性和完整性。

  • 小合并:是指将多个小的 HFile 文件合并成一个大的 HFile 文件,并将新文件设置为激活状态,删除小文件。小合并通常在 HBase 集群中进行,以减少 HFile 文件的数量,从而提高查询效率。在小合并过程中,HBase 会首先将所有参与合并的 HFile 文件中的数据进行合并,然后将合并后的数据写入一个新的 HFile 文件中。在新的 HFile 文件中,HBase 会设置激活状态,并将原来的小文件删除。

HBase 中的大合并和小合并都是通过 HFile 文件进行数据管理的操作。大合并用于删除标记为 DeleteColumn 的记录,并确保数据的一致性和完整性;小合并用于减少 HFile 文件的数量,提高查询效率。这两种合并操作在 HBase 集群中进行,以确保数据的安全性和一致性。

25、说说 HBase 和关系型(传统数据库)的区别?

由于字数限制,此处省略

完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩 取

26、谈谈 HBase 的高可用

由于字数限制,此处省略

完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩 取

27、说说 HBase 的优化方法

由于字数限制,此处省略

完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩 取

28、说说 HBase 中 RowFilter 和 BloomFilter 原理

由于字数限制,此处省略

完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩 取

29、说说 HBase 的布隆过滤器

由于字数限制,此处省略

完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩 取

30、HBase 的数据一致性是如何保证的?

由于字数限制,此处省略

完整内容,请参见《尼恩 大数据 面试宝典》,pdf 找尼恩 取

说在后面

本文《尼恩 大数据 面试宝典》 是 《尼恩Java面试宝典》 姊妹篇。

这里特别说明一下:《尼恩Java面试宝典》41个专题 PDF 自首次发布以来, 已经收集了 好几千题,大量的大厂面试干货、正货 ,足足4000多页,帮助很多小伙伴进了大厂,拿了高薪。 所以,《尼恩Java面试宝典》面试题集合, 已经变成Java 学习和面试的必读书籍。

于是,尼恩架构团队趁热打铁,推出 《尼恩 大数据 面试宝典》,已经发布了三个专题:

尼恩大数据面试宝典专题1:史上最全Hadoop面试题

尼恩大数据面试宝典专题2:绝密100个Spark面试题,熟背100遍,猛拿高薪

尼恩大数据面试宝典专题3:史上最全Hive面试题,不断迭代,持续升级

尼恩大数据面试宝典专题4:史上最全Flink面试题,不断迭代,持续升级

《尼恩大数据面试宝典专题5:史上最全HBase面试题,不断迭代,持续升级》(本文)

完整的pdf,可以到文末公号【技术自由圈】取。

并且,《尼恩 大数据 面试宝典》、 《尼恩Java面试宝典》 都会持续迭代、不断更新,以 吸纳最新的面试题,最新版本,具体请参见 文末公号【技术自由圈】

PDF发布预告:《大数据 Flink学习圣经》

未来职业,如何突围: 成长为 三栖架构师, Java 架构+GO 架构 + 大数据 架构

尼恩即将为大家编写,《大数据 Flink学习圣经》 《大数据 HBase 学习圣经》

《尼恩 架构笔记》《尼恩高并发三部曲》《尼恩Java面试宝典》PDF,请到下面公号【技术自由圈】取↓↓↓

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值