大数据面试——HBase篇
众人拾柴火焰高,这里贴个本面经的共享在线文档,大家可以自由编辑,共同丰富题库。
整理不易,来个关注+收藏+点赞呗
在线文档:
-----------------------------------------分界线-----------------------------------------
1.介绍下HBase
HBase是一种基于Hadoop的列示分布式非关系型数据库,它是高可靠性、高性能、面向列、可伸缩的分布式存储系统,利用HBase技术可在廉价服务器上搭建起大规模结构化存储集群。它是Google论文BigTable的实现。
2.HBase优缺点
优点
a. 高容错性,高扩展性,高吞吐量
b. 强一致性和持久性,数据写入内存后异步刷新到磁盘
c. 采用k-v存储方式,意味着即使数据海量增长,查询性能也不会急剧下降
d. 列式存储,数据模型灵活,具备动态添加列簇和列的能力
e. 与大数据生态系统整合紧密,可无缝与其他大数据组件协同工作
缺点
a. 由于HBASE按照Row key来读写,不支持范围条件查询
b. 结构设计复杂,因此数据量少的时候,性能并不占优势
c. 不支持表的关联操作,并且聚合查询能力差
3.介绍下的HBase的架构
(1) Zookeeper
a. 保证HMaster的高可用;
b. 存储所有的HRegion的寻址入口;
c. 实时监控HRegionServer的上线和下线信息,并实时通知给HMaster;
d. 存储HBase的schema和table元数据;
e. Zookeeper Quorum存储-ROOT-表地址、HMaster地址
(2) HMaster
所有Region Server的管理者
a. 对于表的操作:create, delete, alter
b. 对于RegionServer的操作:分配regions到每个RegionServer,监控每个RegionServer的状态,负载均衡和故障转移
(3) HRegionServer
a. 对于数据的操作:get, put, delete
b. 对于Region的操作:splitRegion、compactRegion
(4) HFile
HBase中KeyValue数据的存储格式,
(5) HStore
存储核心由MemStore和StoreFile组成。StoreFile文件数量增长到阈值后会触发Compact合并操作,多个StoreFile合并为一个StoreFile,合并过程中会进行版本合并和数据删除。当单个StoreFile达到一定阈值后,会触发Split操作,将当前一个Regin分为两个Regin,父Regin下线,新Regin由HMaster分配到新ReginServer
(6) HLog(WAL)
每个HReginServer中有一个HLog,避免HBase意外宕机时,MemStore数据丢失。HLog定期删除已经持久化的数据。当HReginServer意外终止后,HMaster通过Zookeeper感知到,先处理遗留的HLog,将其中不同Regin的Log数据拆分,分发到相应的Regin目录下,然后再将失效的Regin重新分配,领取到这些Regin的HReginServer在Load Regin时发现有历史HLog需要处理,就将其中数据Replay到MemStore中,然后Flush到StoreFile,完成数据恢复
(7) HDFS
HDFS为Hbase提供最终的底层数据存储服务,同时为HBase提供高可用的支持
(8) hbase-client
用来访问hbase集群
4.HBase的读写缓存
读缓存BlockCache
写缓存MemStore
5.在删除HBase中的一个数据的时候,它是立马就把数据删除掉了吗?
不是,只是将删除操作记录下来,在StoreFile文件比较多进行合并时,清理过期或者删除的数据。
6.HBase中的二级索引
(1)背景
HBASE中只有RowKey作为以及索引,在查询非RowKey数据时,需要通过MR或Spark等计算框架,效率特别低,并且特别消耗资源。
(2)原理
建立各列值与行键之间的映射关系。
7.HBase的RegionServer宕机以后怎么恢复的?
(1) HMaster检测到服务器宕机(通过Zookeeper);
(2) HLog切分,一个ReginServer只有一个HLog,因此要将HLog按照Regin进行切分,完成后Regin连同对应的HLog被HMaster分往新的ReginServer;
(3) 被分配了新的Regin的ReginServer根据HLog进行丢失数据的恢复,恢复完成后继续对外服务。
8.HBase的一个region由哪些东西组成?
有一个或多个Store,每个Store存放一个列簇;
每个Store由一个MemStore和0个或多个StoreFile组成。
9.HBase高可用怎么实现的?
数据复制:数据能够在不同的ReginServer之间进行复制;
Zookeeper:用于检测和管理各个节点的状态,并触发相应的操作;
RegionServer自动恢复:出现故障后,上面的数据会被HMaster发到其他ReginServer。
10.为什么HBase适合写多读少业务?
HBase存储引擎使用LSM树实现
- 写的时候先将数据存在内存中,达到阈值后再顺序写到磁盘上,避免了随机写;
- 读的时候,HBase只有rowkey索引,并且很难命中内存中数据,需要访问较多磁盘。
11.列式数据库的适用场景和优势?
适用场景:
a. 查询过程中,可针对各列的运算并发执行,在内存中聚合完整记录集,降低查询响应时间
b. 因为各列独立存储,且数据类型已知,可以针对该列的数据类型、数据量大小等因素动态选择压缩算法,以提高物理存储利用率
优势:
a. 列存模式下,只需要读取参与计算的列即可,极大的减低了IO花费
b. 同一列中的数据属于同一类型,压缩效果显著
适合OLAP系统
12.HBase的rowkey设计原则
(1)长度
Rowkey是一个二进制码流,太长浪费磁盘,并且MemStore中存储数据量也少建议10~100长度,最佳为16,因为64位操作系统内存8字节对齐,为8的整数倍最佳;
(2)散列原则
将RowKey高位字段作为散列字段,避免热点数据集中在一个ReginServer上;
(3)唯一原则
rowkey 是按照字典顺序排序存储的,因此可以将经常读到的数据放在一起。
13.HBase的rowkey为什么要唯一?
因为HBase是k-v存储,重复的话旧数据会被新数据覆盖
14.HBase的大合并、小合并是什么?
- 小合并(Minor Compaction)
合并相邻的StoreFile为一个较大的StoreFile
- 大合并(Major Compartion)
将所有StoreFile合并为一个StoreFile,伴随着数据的删除清理
15.HBase和关系型数据库(传统数据库)的区别(优点)?
(1)数据类型
HBase只有字符串存储,传统的关系型数据有着丰富的存储类型
(2)数据的操作
HBase只有表内数据的操作,没有表之间的关联
(3)存储方式
HBase是列式存储
(4)数据维护
HBase的修改和删除不是马上执行,操作后并不是第一时间内生效
(5)可伸缩性
HBase能够很容易的增加/减少节点
16.HBase为什么随机查询很快?
(1)只需要遍历相关Regin
(2)只需要遍历相关列簇
(3)先内存再磁盘
(4)根据key遍历
17.HBase的Get和Scan的区别和联系?
区别:
a. Get根据RowKey获取唯一值;
b. Scan按照指定的条件和顺序扫描表中的多行数据;
c. Get操作在内部对数据进行缓存,因此适用于对特定行的频繁读取。而Scan操作不会缓存数据,适用于一次性读取大量数据或按顺序遍历数据。
联系:
a. Get和Scan都可以使用过滤器(Filters)进行数据过滤,以便按照特定条件筛选所需的数据;
b. Get和Scan都可以选择返回的列族和列限定符,以获取特定的列数据。
18.HBase数据compact流程
(1) 触发
(2) 选择合并目标
(3) 合并:对选中的StoreFile进行归并排序,并进行合并,合并同时处理文件版本,时间戳等信息
(4) 清理:合并完成后,原有StoreFile会废弃,HBase会将其删除,并释放相应空间
(5) 更新元数据:Compaction完成后,HBase会更新相应的元数据信息
19.MemStore Flush条件
- MemStore达到阈值,所在regin都会flush
达到MemStore的4倍(默认),停止写入MemStore
- ReginServer中MemStore总大小达到阈值,全体flush
- 达到时间阈值,触发flush
- WAL文件数量超过阈值,regin整体flush
20.既然HBase底层数据是存储在HDFS上,为什么不直接使用HDFS,而还要用HBase
- HDFS更多的功能是大文件的存储,创建/删除文件,管理权限,对大文件的数据读取/追加。但是如果要对所存储的数据做修改/删除/插入/随机写,HDFS就做不到了
- HBase是基于HDFS进行超大数据集的分布式存储以及对数据的增删改查
21.HBase和Phoenix的区别
- Phoenix是HBase的开源SQL中间层,允许使用JDBC方式操作HBase上的数据
- HBase创建的表Phoenix看不到,Phoenix创建的表HBase能看到
- Phoenix具备二级索引
- Phoenix支持表之间的Join操作
22.HBase支持SQL操作吗
不直接支持传统SQL语句,使用自身API实现操作数据
23.HBase表设计
- 列簇设计在合理范围内能尽量少的减少列簇就尽量减少列簇数据保留的版本数数据保留时间
- rowkey设计预分区
主要解决热点问题,避免数据吞吐量过大时单个Regin负载过大
- rowkey长度不宜过大
- 唯一性原则
24.Region分配
- 任何时刻,一个Regin只能分给一个ReginServer
- Master记录了有哪些可用的ReginServer,以及当前有哪些Regin分配给了哪些ReginServer。当需要分配新的Regin,并且一个ReginServer有空间时,Master则会向ReginServer发送装载请求,ReginServer开始提供服务。
25.HBase的Region切分
(1)prepare阶段
在内存中初始化两个HReginInfo对象,包含tableName,reginName,startKey,endKey以及transaction journal用来记录切分的进展。
(2)execute阶段
a. RegionServer 更改ZK节点 /region-in-transition 中该Region的状态为SPLITING
b. Master通过watch节点/region-in-transition检测到Region状态改变,并修改内存中Region的状态
c. 在父存储目录下新建临时文件夹.split保存split后的daughter region信息
d. 关闭parent regin(会触发flush操作,确保数据全部落盘)
e. 核心分裂步骤:在.split文件夹下新建两个子文件夹,称之为daughter A、daughter B,并在文件夹中生成reference文件,分别指向父region中对应文件
f. 父region分裂为两个子region后, 将daughter A、daughter B拷贝到HBase根目录下,形成两个新的region
g. parent region通知修改 hbase.meta 表后下线,不再提供服务
h. 开启daughter A、daughter B两个子region。通知修改 hbase.meta 表,正式对外提供服务
(3)rollback阶段
如果execute阶段出现异常,则执行rollback操作
26.介绍下HBase中的LSM树
(1)设计思想
将对数据的修改增量保持在内存中,达到指定的大小限制后将这些修改操作批量写入磁盘,不过读取的时候稍微麻烦,需要合并磁盘中历史数据和内存中最近修改操作,所以写入性能大大提升,读取时可能需要先看是否命中内存,否则需要访问较多的磁盘文件。极端的来说,基于LSM树实现的HBase的写性能比Mysql高了一个数量级,读性能低了一个数量级。
本质是将写入操作全部转化成磁盘的顺序写入,极大地提高了写入操作的性能。
(2)数据写
a. 数据首先会插入到内存中的树,为了防止数据丢失,写内存的同时需要暂时持久化到磁盘(WAL),即输入数据时数据会以完全有序的形式先存储在日志文件中(对应HBase的MemStore和HLog)。当日志文件被修改时,对应的更新会被先保存在内存中来加速查询。
b. 当内存中树的数据大小达到阈值时,会进行合并操作。合并操作会从左至右遍历内存中的叶子节点与磁盘中树的叶子节点进行合并,当合并的数据量达到磁盘的存储页的大小时,会将合并的数据持久化到磁盘。同时更新父亲节点对叶子节点的指针。
27.HBase写数据流程
a. Client先访问zookeeper,获取hbase:meta表位于哪个RegionServer
b. 访问对应的RegionServer,获取hbase:meta表中数据,查询要写入数据Region所在RegionServer
c. 访问RegionServer,发送写请求
d. ReginServer将数据顺序写入(追加)到HLog(WAL)
e. 将数据写入对应的MemStore,数据会在MemStore进行排序
f. 向客户端发送ack
g. 等达到MemStore的刷写时机后,将数据刷写到HFile
28.HBase读数据流程
a. Client先访问zookeeper,获取hbase:meta表位于哪个Region Server
b. 访问对应的Region Server,获取hbase:meta表,根据读请求的namespace:table/rowkey,查询出目标数据位于哪个Region Server中的哪个Region中。并将该table的region信息以及meta表的位置信息缓存在客户端的meta cache,方便下次访问
c. 与目标RegionServer进行通讯
d. 分别在MemStore、Block Cache和Store File(HFile)中查询目标数据,并将查到的所有数据进行合并。此处所有数据是指同一条数据的不同版本(time stamp)或者不同的类型(Put/Delete)
e. 将查询到的新的数据块(Block,HFile数据存储单元,默认大小为64KB)缓存到Block Cache
f. 将合并后的最终结果返回给客户端
29.HBase优化
(1)预分区
每一个region维护着startRow与endRowKey,如果加入的数据符合某个region维护的rowKey范围,则该数据交给这个region维护。那么依照这个原则,我们可以将数据所要投放的分区提前大致的规划好,以提高HBase性能
(2)RowKey设计
生成随机数、hash、散列值;
字符串反转;
字符串拼接。
(3)内存优化
适合就好,过大的话虽然性能高,但是GC时候时间特别长。
(4)设置RPC监听数量
默认值为30,用于指定RPC监听的数量,可以根据客户端的请求数进行调整,读写请求较多时,增加此值。
(RPC监听是指Region Compact后的监听器,当一个Region没有被写入新数据,并且仅存在较少的数量的旧数据时,HBase会自动压缩该Region。在这种情况下,HBase将触发rck监听器,以便通知相关进程可以将该Region从内存中卸载,以释放更多的资源。通过这种方式,rck监听器可以帮助保持HBase集群的高性能和稳定性。)
(5)手动控制Major Compaction
默认值:604800000秒(7天), Major Compaction的周期,若关闭自动Major Compaction,可将其设为0
(6)优化HStore文件大小
默认值10737418240(10GB),如果需要运行HBase的MR任务,可以减小此值,因为一个region对应一个map任务,如果单个region过大,会导致map任务执行时间过长。该值的意思就是,如果HFile的大小达到这个数值,则这个region会被切分为两个Hfile
(7)优化HBase客户端缓存
默认值2097152bytes(2M)用于指定HBase客户端缓存,增大该值可以减少RPC调用次数,但是会消耗更多内存,反之则反之。一般我们需要设定一定的缓存大小,以达到减少RPC次数的目的
(8)指定scan.next扫描HBase所获取的行数
用于指定scan.next方法获取的默认行数,值越大,消耗内存越大
(9)BlockCache占用RegionServer堆内存的比例默认0.4,读请求比较多的情况下,可适当调大
(10)MemStore占用RegionServer堆内存的比例默认0.4,写请求较多的情况下,可适当调大