HBase面试题整理

2021年11月22日 阅读数:1
这篇文章主要向大家介绍HBase面试题整理,主要内容包括基础应用、实用技巧、原理机制等方面,希望对大家有所帮助。

关注公众号:大数据技术派,回复“资料”,领取1000G资料。
本文发于个人我的博客:HBase面试题整理面试

一、 HBase的特色是什么?

1)大:一个表能够有数十亿行,上百万列;
2)无模式:每行都有一个可排序的主键和任意多的列,列能够根据须要动态的增长,同一张表中不一样的行能够有大相径庭的列;
3)面向列:面向列(族)的存储和权限控制,列(族)独立检索;
4)稀疏:空(null)列并不占用存储空间,表能够设计的很是稀疏;
5)数据多版本:每一个单元中的数据能够有多个版本,默认状况下版本号自动分配,是单元格插入时的时间戳;
6)数据类型单一:Hbase中的数据都是字符串,没有类型。 shell

二、HBase和Hive的区别?

HBase和Hive区别

Hive和Hbase是两种基于Hadoop的不一样技术--Hive是一种类SQL的引擎,而且运行MapReduce任务,Hbase是一种在Hadoop之上的NoSQL 的Key/vale数据库。
固然,这两种工具是能够同时使用的。就像用Google来搜索,用FaceBook进行社交同样,Hive能够用来进行统计查询,HBase能够用来进行实时查询,
数据也能够从Hive写到Hbase,设置再从Hbase写回Hive。 数据库

三、HBase适用于怎样的情景?

① 半结构化或非结构化数据
对于数据结构字段不够肯定或杂乱无章很难按一个概念去进行抽取的数据适合用HBase。以上面的例子为例,当业务发展须要存储author的email,phone,
address信息时RDBMS须要停机维护,而HBase支持动态增长。
② 记录很是稀疏
RDBMS的行有多少列是固定的,为null的列浪费了存储空间。而如上文提到的,HBase为null的Column不会被存储,这样既节省了空间又提升了读性能。
③ 多版本数据
如上文提到的根据Row key和Column key定位到的Value能够有任意数量的版本值,所以对于须要存储变更历史记录的数据,用HBase就很是方便了。
好比上例中的author的Address是会变更的,业务上通常只须要最新的值,但有时可能须要查询到历史值。
④ 超大数据量
当数据量愈来愈大,RDBMS数据库撑不住了,就出现了读写分离策略,经过一个Master专门负责写操做,多个Slave负责读操做,服务器成本倍增。
随着压力增长,Master撑不住了,这时就要分库了,把关联不大的数据分开部署,一些join查询不能用了,须要借助中间层。随着数据量的进一步增长,
一个表的记录愈来愈大,查询就变得很慢,因而又得搞分表,好比按ID取模分红多个表以减小单个表的记录数。经历过这些事的人都知道过程是多么的折腾。
采用HBase就简单了,只须要加机器便可,HBase会自动水平切分扩展,跟Hadoop的无缝集成保障了其数据可靠性(HDFS)和海量数据分析的高性能(MapReduce)。 apache

四、描述HBase的rowKey的设计原则?(☆☆☆☆☆)

(1)Rowkey长度原则
Rowkey 是一个二进制码流,Rowkey 的长度被不少开发者建议说设计在10~100 个字节,不过建议是越短越好,不要超过16 个字节。
缘由以下:
① 数据的持久化文件HFile 中是按照KeyValue 存储的,若是Rowkey 过长好比100 个字节,1000 万列数据光Rowkey 就要占用100*1000 万=10 亿个字节,
将近1G 数据,这会极大影响HFile 的存储效率;
② MemStore 将缓存部分数据到内存,若是Rowkey 字段过长内存的有效利用率会下降,系统将没法缓存更多的数据,这会下降检索效率。
所以Rowkey 的字节长度越短越好。
③ 目前操做系统是都是64 位系统,内存8 字节对齐。控制在16 个字节,8 字节的整数倍利用操做系统的最佳特性。
(2)Rowkey散列原则
若是Rowkey是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将Rowkey的高位做为散列字段,由程序循环生成,低位放时间字段,
这样将提升数据均衡分布在每一个Regionserver 实现负载均衡的概率。若是没有散列字段,首字段直接是时间信息将产生全部新数据都在一个 RegionServer 上堆积的
热点现象,这样在作数据检索的时候负载将会集中在个别RegionServer,下降查询效率。
(3)Rowkey惟一原则
必须在设计上保证其惟一性。 缓存

五、描述HBase中scan和get的功能以及实现的异同?(☆☆☆☆☆)

HBase的查询实现只提供两种方式:
1)按指定RowKey 获取惟一一条记录,get方法(org.apache.hadoop.hbase.client.Get) Get 的方法处理分两种 : 设置了ClosestRowBefore 和
没有设置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 方法添加过滤器,这也是分页、多条件查询的基础。 服务器

六、请描述HBase中scan对象的setCache和setBatch方法的使用?(☆☆☆☆☆)

setCache用于设置缓存,即设置一次RPC请求能够获取多行数据。对于缓存操做,若是行的数据量很是大,多行数据有可能超过客户端进程的内存容量,
由此引入批量处理这一解决方案。
setBatch 用于设置批量处理,批量可让用户选择每一次ResultScanner实例的next操做要取回多少列,例如,在扫描中设置setBatch(5),
则一次next()返回的Result实例会包括5列。若是一行包括的列数超过了批量中设置的值,则能够将这一行分片,每次next操做返回一片,当一行的列数不能被批量中
设置的值整除时,最后一次返回的Result实例会包含比较少的列,如,一行17列,batch设置为5,则一共返回4个Result实例,这4个实例中包括的列数分别
为五、五、五、2。
组合使用扫描器缓存和批量大小,可让用户方便地控制扫描一个范围内的行键所须要的RPC调用次数。Cache设置了服务器一次返回的行数,
而Batch设置了服务器一次返回的列数。
假如咱们创建了一张有两个列族的表,添加了10行数据,每一个行的每一个列族下有10列,这意味着整个表一共有200列(或单元格,由于每一个列只有一个版本),
其中每行有20列。 markdown

HBase中scan对象的setCache和setBatch方法

① Batch参数决定了一行数据分为几个Result,它只针对一行数据,Batch再大,也只能将一行的数据放入一个Result中。因此当一行数据有10列,
而Batch为100时,也只能将一行的全部列都放入一个Result,不会混合其余行;
② 缓存值决定一次RPC返回几个Result,根据Batch划分的Result个数除以缓存个数能够获得RPC消息个数(以前定义缓存值决定一次返回的行数,
这是不许确的,准确来讲是决定一次RPC返回的Result个数,因为在引入Batch以前,一行封装为一个Result,所以定义缓存值决定一次返回的行数,但引入Batch后,
更准确的说法是缓存值决定了一次RPC返回的Result个数);
RPC请求次数 = (行数 * 每行列数) / Min(每行的列数,批量大小) / 扫描器缓存
下图展现了缓存和批量两个参数如何联动,下图中有一个包含9行数据的表,每行都包含一些列。使用了一个缓存为六、批量大小为3的扫描器,
须要三次RPC请求来传送数据: 数据结构

HBase Table

七、请详细描述HBase中一个cell的结构?

HBase中经过row和columns肯定的为一个存贮单元称为cell。
Cell:由{row key, column(=<family> + <label>), version}惟一肯定的单元。cell 中的数据是没有类型的,所有是字节码形式存贮。 app

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

在hbase中每当有memstore数据flush到磁盘以后,就造成一个storefile,当storeFile的数量达到必定程度后,就须要将 storefile 文件来
进行 compaction 操做。
Compact 的做用:
① 合并文件
② 清除过时,多余版本的数据
③ 提升读写数据的效率
HBase 中实现了两种 compaction 的方式:minor and major. 这两种 compaction 方式的区别是:
1)Minor 操做只用来作部分文件的合并操做以及包括 minVersion=0 而且设置 ttl 的过时版本清理,不作任何删除数据、多版本数据的清理工做。
2)Major 操做是对 Region 下的HStore下的全部StoreFile执行合并操做,最终的结果是整理合并出一个文件。 负载均衡

九、天天百亿数据存入HBase,如何保证数据的存储正确和在规定的时间里所有录入完毕,不残留数据?(☆☆☆☆☆)

需求分析:
1)百亿数据:证实数据量很是大;
2)存入HBase:证实是跟HBase的写入数据有关;
3)保证数据的正确:要设计正确的数据结构保证正确性;
4)在规定时间内完成:对存入速度是有要求的。
解决思路:
1)数据量百亿条,什么概念呢?假设一成天60x60x24 = 86400秒都在写入数据,那么每秒的写入条数高达100万条,HBase固然是支持不了每秒百万条数据的,
因此这百亿条数据可能不是经过实时地写入,而是批量地导入。批量导入推荐使用BulkLoad方式(推荐阅读:Spark之读写HBase),性能是普通写入方式几倍以上;
2)存入HBase:普通写入是用JavaAPI put来实现,批量导入推荐使用BulkLoad;
3)保证数据的正确:这里须要考虑RowKey的设计、预建分区和列族设计等问题;
4)在规定时间内完成也就是存入速度不能过慢,而且固然是越快越好,使用BulkLoad。

十、请列举几个HBase优化方法?(☆☆☆☆☆)

1)减小调整
减小调整这个如何理解呢?HBase中有几个内容会动态调整,如region(分区)、HFile,因此经过一些方法来减小这些会带来I/O开销的调整。
① Region
若是没有预建分区的话,那么随着region中条数的增长,region会进行分裂,这将增长I/O开销,因此解决方法就是根据你的RowKey设计来进行预建分区,
减小region的动态分裂。
② HFile
HFile是数据底层存储文件,在每一个memstore进行刷新时会生成一个HFile,当HFile增长到必定程度时,会将属于一个region的HFile进行合并,
这个步骤会带来开销但不可避免,可是合并后HFile大小若是大于设定的值,那么HFile会从新分裂。为了减小这样的无谓的I/O开销,建议估计项目数据量大小,
给HFile设定一个合适的值。
2)减小启停
数据库事务机制就是为了更好地实现批量写入,较少数据库的开启关闭带来的开销,那么HBase中也存在频繁开启关闭带来的问题。
① 关闭Compaction,在闲时进行手动Compaction。
由于HBase中存在Minor Compaction和Major Compaction,也就是对HFile进行合并,所谓合并就是I/O读写,大量的HFile进行确定会带来I/O开销,
甚至是I/O风暴,因此为了不这种不受控制的意外发生,建议关闭自动Compaction,在闲时进行compaction。
② 批量数据写入时采用BulkLoad。
若是经过HBase-Shell或者JavaAPI的put来实现大量数据的写入,那么性能差是确定而且还可能带来一些意想不到的问题,因此当须要写入大量离线数据时
建议使用BulkLoad。
3)减小数据量
虽然咱们是在进行大数据开发,可是若是能够经过某些方式在保证数据准确性同时减小数据量,何乐而不为呢?
① 开启过滤,提升查询速度
开启BloomFilter,BloomFilter是列族级别的过滤,在生成一个StoreFile同时会生成一个MetaBlock,用于查询时过滤数据
② 使用压缩
通常推荐使用Snappy和LZO压缩
4)合理设计
在一张HBase表格中RowKey和ColumnFamily的设计是很是重要,好的设计可以提升性能和保证数据的准确性
① RowKey设计:应该具有如下几个属性
散列性:散列性可以保证相同类似的rowkey聚合,相异的rowkey分散,有利于查询。
简短性:rowkey做为key的一部分存储在HFile中,若是为了可读性将rowKey设计得过长,那么将会增长存储压力。
惟一性:rowKey必须具有明显的区别性。
业务性:举例来讲:
假如个人查询条件比较多,并且不是针对列的条件,那么rowKey的设计就应该支持多条件查询。
若是个人查询要求是最近插入的数据优先,那么rowKey则能够采用叫上Long.Max-时间戳的方式,这样rowKey就是递减排列。
② 列族的设计:列族的设计须要看应用场景
优点:HBase中数据时按列进行存储的,那么查询某一列族的某一列时就不须要全盘扫描,只须要扫描某一列族,减小了读I/O;
其实多列族设计对减小的做用不是很明显,适用于读多写少的场景
劣势:下降了写的I/O性能。缘由以下:数据写到store之后是先缓存在memstore中,同一个region中存在多个列族则存在多个store,
每一个store都一个memstore,当其实memstore进行flush时,属于同一个region的store中的memstore都会进行flush,增长I/O开销。

十一、Region如何预建分区?

预分区的目的主要是在建立表的时候指定分区数,提早规划表有多个分区,以及每一个分区的区间范围,这样在存储的时候rowkey按照分区的区间存储,
能够避免region热点问题。
一般有两种方案:
方案1:shell 方法
create 'tb_splits', {NAME => 'cf',VERSIONS=> 3},{SPLITS => ['10','20','30']}
方案2:JAVA程序控制
① 取样,先随机生成必定数量的rowkey,将取样数据按升序排序放到一个集合里;
② 根据预分区的region个数,对整个集合平均分割,便是相关的splitKeys;
③ HBaseAdmin.createTable(HTableDescriptor tableDescriptor,byte[][]splitkeys)能够指定预分区的splitKey,
便是指定region间的rowkey临界值。

十二、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,若是有则进行恢复。

1三、HBase读写流程?(☆☆☆☆☆)


① HRegionServer保存着meta表以及表数据,要访问表数据,首先Client先去访问zookeeper,从zookeeper里面获取meta表所在的位置信息,
即找到这个meta表在哪一个HRegionServer上保存着。
② 接着Client经过刚才获取到的HRegionServer的IP来访问Meta表所在的HRegionServer,从而读取到Meta,进而获取到Meta表中存放的元数据。
③ Client经过元数据中存储的信息,访问对应的HRegionServer,而后扫描所在HRegionServer的Memstore和Storefile来查询数据。
④ 最后HRegionServer把查询到的数据响应给Client。

① Client先访问zookeeper,找到Meta表,并获取Meta表元数据。
② 肯定当前将要写入的数据所对应的HRegion和HRegionServer服务器。
③ Client向该HRegionServer服务器发起写入数据请求,而后HRegionServer收到请求并响应。
④ Client先把数据写入到HLog,以防止数据丢失。
⑤ 而后将数据写入到Memstore。
⑥ 若是HLog和Memstore均写入成功,则这条数据写入成功。
⑦ 若是Memstore达到阈值,会把Memstore中的数据flush到Storefile中。
⑧ 当Storefile愈来愈多,会触发Compact合并操做,把过多的Storefile合并成一个大的Storefile。
⑨ 当Storefile愈来愈大,Region也会愈来愈大,达到阈值后,会触发Split操做,将Region一分为二。

1四、HBase内部机制是什么?

Hbase是一个能适应联机业务的数据库系统
物理存储:hbase的持久化数据是将数据存储在HDFS上。
存储管理:一个表是划分为不少region的,这些region分布式地存放在不少regionserver上Region内部还能够划分为store,
store内部有memstore和storefile。
版本管理:hbase中的数据更新本质上是不断追加新的版本,经过compact操做来作版本间的文件合并Region的split。
集群管理:ZooKeeper + HMaster + HRegionServer。

1五、Hbase中的memstore是用来作什么的?

hbase为了保证随机读取的性能,因此hfile里面的rowkey是有序的。当客户端的请求在到达regionserver以后,为了保证写入rowkey的有序性,
因此不能将数据马上写入到hfile中,而是将每一个变动操做保存在内存中,也就是memstore中。memstore可以很方便的支持操做的随机插入,
并保证全部的操做在内存中是有序的。当memstore达到必定的量以后,会将memstore里面的数据flush到hfile中,这样能充分利用hadoop写入大文件的性能优点,
提升写入性能。
因为memstore是存放在内存中,若是regionserver由于某种缘由死了,会致使内存中数据丢失。全部为了保证数据不丢失,
hbase将更新操做在写入memstore以前会写入到一个write ahead log(WAL)中。WAL文件是追加、顺序写入的,WAL每一个regionserver只有一个,
同一个regionserver上全部region写入同一个的WAL文件。这样当某个regionserver失败时,能够经过WAL文件,将全部的操做顺序从新加载到memstore中。

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

Column Family的个数具体看表的数据,通常来讲划分标准是根据数据访问频度,如一张表里有些列访问相对频繁,而另外一些列访问不多,
这时能够把这张表划分红两个列族,分开存储,提升访问效率。

1七、如何提升HBase客户端的读写性能?请举例说明(☆☆☆☆☆)

① 开启bloomfilter过滤器,开启bloomfilter比没开启要快三、4倍
② Hbase对于内存有特别的需求,在硬件容许的状况下配足够多的内存给它
③ 经过修改hbase-env.sh中的 export HBASE_HEAPSIZE=3000 #这里默认为1000m
④ 增大RPC数量
经过修改hbase-site.xml中的hbase.regionserver.handler.count属性,能够适当的放大RPC数量,默认值为10有点小。

1八、HBase集群安装注意事项?

① HBase须要HDFS的支持,所以安装HBase前确保Hadoop集群安装完成;
② HBase须要ZooKeeper集群的支持,所以安装HBase前确保ZooKeeper集群安装完成;
③ 注意HBase与Hadoop的版本兼容性;
④ 注意hbase-env.sh配置文件和hbase-site.xml配置文件的正确配置;
⑤ 注意regionservers配置文件的修改;
⑥ 注意集群中的各个节点的时间必须同步,不然启动HBase集群将会报错。

1九、直接将时间戳做为行健,在写入单个region 时候会发生热点问题,为何呢?(☆☆☆☆☆)

region中的rowkey是有序存储,若时间比较集中。就会存储到一个region中,这样一个region的数据变多,其它的region数据不多,加载数据就会很慢,
直到region分裂,此问题才会获得缓解。

20、请描述如何解决HBase中region过小和region太大带来的冲突?(☆☆☆☆☆)

Region过大会发生屡次compaction,将数据读一遍并重写一遍到hdfs 上,占用io,region太小会形成屡次split,region 会下线,影响访问服务,
最佳的解决方法是调整hbase.hregion. max.filesize 为256m。

猜你喜欢
Hive计算最大连续登录天数
Hadoop 数据迁移用法详解
Hbase修复工具Hbck
数仓建模分层理论
一文搞懂Hive的数据存储与压缩
大数据组件重点学习这几个