Hbase理论知识点概要
问题01:Hbase的功能与应用场景?
- 功能:Hbase是一个分布式的、基于分布式内存和HDFS的按列存储的、NoSQL数据库
- 应用:Hbase适合于需要实时的对大量数据进行快速、随机读写访问的场景
问题02:Hbase有什么特点?
- 分布式的,可以实现高并发的数据读写
- 上层构建分布式内存,可以实现高性能、随机、实时的读写
- 底层基于HDFS,可以实现大数据
- 按列存储,基于列实现数据存储,灵活性更高
问题03:Hbase设计思想是什么?
- 设计思想:冷热数据分离,Hbase将新数据直接写入内存中,如果内存中存储的数据过多,就将内存的数据写入HDFS
- 热数据是指刚产生的数据,先写内存,大概率的情况下,可以直接从内存中读取
- 冷数据是指先产生的数据,将内存中产生很久的数据写入HDFS中,被读取的概率较小
问题04:Hbase与HDFS的区别是什么?
- Hbase是一个高性能实时随机读写数据的数据库存储系统,用于实现实时数据存储
- HDFS是一个分布式离线大数据文件存储系统,用于实现离线的文件存储
问题05:Hbase与MySQL的区别是什么?
- Hbase是分布式NoSQL数据库,可以实现高性能的大数据存储
- MySQL是RDBMS关系型数据库,只能实现小数据量的结构化数据存储
问题06:Hbase与Hive的区别是什么?
- Hive是通过构建元数据,映射HDFS文件构建成表,本质还是HDFS,实现离线大数据仓库
- Hbase是通过构建上层分布式内存,底层HDFS,实现大数据实时存储的NoSQL数据库
问题07:Hbase的按列存储是什么?
- Hbase按列存储的设计是指Hbase中的最小操作单元是列,可以实现对每一行的每一列进行读写
- 每一行的列都是动态的,每一行可以拥有不同的列
问题08:请简述Namespace、Rowkey、ColumnFamily及多版本的功能及含义
- Namespace:命名空间,类似于数据库的设计,用于区分不同的业务表
- Rowkey:行健,类似于主键的设计,唯一标识一条数据并且作为Hbase中的唯一索引
- ColumnFamily:列族,用于将列进行分组,底层用于区分存储不同的列,提高查询性能
- 多版本:Hbase中允许一列存储多个版本的值,并通过数据写入的时间戳来区分不同版本 Hbase万能模板: Hbase是一个通过构建上层分布式内存,底层HDFS,分布式的、基于内存和HDFS的、按列存储的高性能快速实时随机读写数据的大数据NoSQL数据库存储系统
问题09:请简述Hbase的分布式主从架构
- 主节点:HMaster:管理节点、负责管理集群的从节点、元数据以及所有Region的分配
- 从节点:HRegionServer:存储节点,负责实现所有数据的存储,管理Region,构建分布式内存
问题10:请简述Table表与RegionServer的关系
- Table是Hbase中的表对象,一张表可以划分为多个Region分区
- RegionServer是Hbase中实现数据存储的节点,负责存储每个Region
问题11:表的Region的划分规则及数据写入分区的规则是什么?
- Region划分规则:范围划分,一张表可以在Rowkey行的方向上划分多个Region,每个Region构成一段连续的区间
- 数据划分规则:根据Rowkey属于哪个Region的范围,就将这条数据写入哪个Region分区中
问题12:Region的内部存储结构是什么?
- 每个RegionServer中管理多个Region
- 每个Region中根据列族划分多个Store
- 每个Store中有1个memstore和多个StoreFile文件
- 数据写入memstore中,如果达到内存阈值,memstore中的数据将写入StoreFile
问题13:什么是热点问题?
- 现象:在某个时间段内,大量的读写请求全部集中在某个Region中,导致这台RegionServer的负载比较高,其他的Region和RegionServer比较空闲
- 问题:这台RegionServer故障的概率就会增加,整体性能降低,效率比较差
- 原因:本质上的原因,数据分配不均衡
- 情况
- 一张表只有一个Region
- 一张表有多个Region,但是Rowkey是连续产生的
问题14:怎么解决热点问题?
- 合理的设计Rowkey,构建不连续的Rowkey
- 根据Rowkey的前缀,为表划分多个Region
问题15:Rowkey如何设计,设计规则是什么?
- 业务原则:贴合业务,保证前缀是最常用的查询字段
- 唯一原则:每条rowkey唯一表示一条数据
- 组合原则:常用的查询条件组合作为Rowkey
- 散列原则:rowkey构建不能连续
- 长度原则:满足业务需求越短越好
问题16:列族设计规则是什么?
- 个数原则:如果列的个数比较多,建议2 ~ 3个,如果列的个数比较少,建议1个
- 列族个数多了,导致比较次数变多,降低性能
- 列族个数少了,导致列的比较次数变多,降低性能
- 长度原则 :能满足业务需求的情况下,越短越好
问题17:Hive on Hbase的实现原理是什么?
- Hive on Hbase的原理是通过MapReduce实现对Hbase数据的读写
- MapReduce中提供了TableInputFormat读取Hbase数据,TableOutputFormat写入数据到Hbase
问题18:Phoenix是什么?
- Phoenix是一个专门为Hbase设计的SQL on Hbase的工具
- 底层通过Hbase API和大量的协处理器实现
- 可以实现基于SQL访问Hbase以及构建维护二级索引等功能
问题19:什么是二级索引?为什么要构建二级索引
- 二级索引指的是基于一级索引之上再构建一层索引
- Hbase使用Rowkey作为唯一索引,只有使用Rowkey前缀进行查询,才走索引查询
- 导致大部分的查询都是不走索引,性能比较差
- 通过建立二级索引,可以通过走两次索引代替全表扫描,加快查询速度
问题20:Phoenix实现二级索引时,可以构建哪些索引类型?
- 全局索引
- 覆盖索引
- 本地索引
- 函数索引
问题21:什么是全局索引?
- 创建全局索引,会自动构建一张索引表
- 索引表结构
- Rowkey:索引字段 原表的rowkey
- 列:占位置x
- 特点:如果查询字段或者查询条件不是索引字段,就不会走索引
- 应用:适合于读多写少
问题22:什么是覆盖索引?
- 创建覆盖索引,会自动构建一张索引表
- 索引表结构
- Rowkey:索引字段 原表的rowkey
- 列:将include中的列放入索引表
- 特点
- 如果查询字段或者查询条件不是索引字段,就不会走索引
- 如果查询的字段在索引表中,直接从索引表返回结果
问题23:什么是本地索引?
- 创建覆盖索引,会自动基于原表构建一个列族来实现索引存储
- 原表的数据中:多了一个索引列族
- 特点
- 不论查询字段是否是索引字段,都会走索引
- 将索引与数据存储在同一台RegionServer,提高索引读写性能
- 注意
- 本地索引会修改原数据表,对于本地索引只能使用Phoenix来操作表的数据
- 盐表不能使用本地索引
问题24:请简述Hbase写入数据的流程
- step1:获取元数据
- 客户端请求Zookeeper,获取meta表所在的regionserver的地址
- 读取meta表的数据:获取所有表的元数据
- step2:找到对应的Region
- 根据meta表中的元数据,找到表对应的所有的region
- 根据region的范围和写入的Rowkey,判断需要写入具体哪一个Region
- 根据region的Regionserver的地址,请求对应的RegionServer
- step3:写入数据
- 请求RegionServer写入对应Region:根据Region的名称来指定写入哪个Region
- 根据列族判断写入哪一个具体的Store
- 先写入WAL:Hlog预写日志中
- 写入对应Store的MemStore中
- MemStore
问题25:请简述Hbase读取数据的流程
- step1:获取元数据
- 客户端请求Zookeeper,获取meta表所在的regionserver的地址
- 读取meta表的数据
- 注意:客户端会缓存meta表的数据,只有第一次会连接ZK,读取meta表的数据,缓存会定期失效,要重新缓存
- 避免每次请求都要先连接zk,再读取meta表
- step2:找到对应的Region
- 根据meta表中的元数据,找到表对应的region
- 根据region的范围和写入的Rowkey,判断需要写入具体哪一个Region
- 根据region的Regionserver的地址,请求对应的RegionServer
- step3:读取数据
- 先查询memstore
- 如果查询的列族开启了缓存机制,就读取BlockCache
- 如果没有,就读取StoreFile,并将结果放入BlockCache中
问题26:请简述LSM模型的设计思想
- step1:数据写入的时候,只写入内存
- step2:将数据在内存构建有序,当数据量大的时候,将有序的数据写入磁盘,变成一个有序的数据文件
- step3:基于所有有序的小文件进行合并,合并为一个整体有序的大文件
问题27:什么是Flush,什么时候会触发Flush?
- Flush是指将memstore中的数据写入HDFS,变成StoreFile
- 2.0之前:判断memstore存储大小,单个memstore达到128M就会触发Flush,或者整个memstore达到95%就会触发
- 2.0之后:根据平均每个memstore的存储大小与16M取最大值计算水位线,高于水位线就Flush,不高于就不Flush,都不高于全部Flush
问题28:什么是Compaction,什么时候会触发Compaction?
- Compaction的功能是将多个单独有序StoreFile文件进行合并,合并为整体有序的大文件并且删除过期数据,加快读取速度
- 2.0之前:通过minor compaction和major compaction来实现
- minor compaction:用于合并最早生成的几个小文件,不清理过期数据
- major compaction:用于将所有storefile合并为一个StoreFile,并清理过期数据
- 2.0之后:除了minor compaction和major compaction,添加了in-memory-compaction
- In-memory compaction:在内存中进行合并,合并以后的结果再进行flush,有四种配置
- none:不开启
- basic:开启,但是合并时不删除过期数据
- eager:开启,合并时并清理删除过期数据
- adaptive:开启,并在合并时根据数据量来自动判断是否清理过期数据
- In-memory compaction:在内存中进行合并,合并以后的结果再进行flush,有四种配置
问题29:什么是Spit,什么时候会触发Split?
- Split是指当一个Region存储的数据过多,导致这个Region的负载比较高,Hbase中设定了一个Region最多存储的数据量的阈值,一旦达到阈值,允许Region分裂为两个region,老的region会下线,新的两个region对外提供服务
- 0.94之前:ConstantSizeRegionSplitPolicy
- 只要region中的storefile达到10G,就分裂
- 2.0之前:IncreasingToUpperBoundRegionSplitPolicy
- 根据Region个数来实现计算,当达到4个region以后,也是按照10GB来分裂
- 2.0之后:SteppingSplitPolicy
- Region个数等于1个:按照256M来分裂
- Region个数超过1个:按照10GB来分裂
问题30:MapReduce读取Hbase数据的原理及返回值是什么?
- MapReduce读取Hbase原理:封装了一个TableInputFormat来实现读取Hbase的数据
- 返回值
- 每个Region对应一个分片,每个分片启动一个MapTask进行处理
- 每个Rowkey的数据变成一个KV对
- K是Rowkey的字节对象:ImmutableBytesWriable类型
- V是Rowkey的数据对象:Result类型
问题31:MapReduce写入Hbase的原理和要求是什么?
- MapReduce写入Hbase原理:封装了一个TableOutputFormat来实现写入Hbase的数据
- 要求
- 写入Hbase的数据的V的类型必须为Put类型
问题32:什么是BulkLoad,用于什么场景?
- BulkLoad是指将数据直接转换为StoreFile文件,放入Hbase中,不经过Hbase的内存,避免大量数据进入内存,又从内存进入HDFS
- 应用:大数据量批量写入Hbase
问题33:协处理器是什么?Hbase中提供了几种协处理器?
- 协处理器指的是Hbase提供了一些开发接口,可以自定义开发一些功能集成到Hbase中
- 类似于Hive中的UDF,当没有这个功能时,可以使用协处理器来自定义开发,让Hbase支持对应的功能
- 协处理器分为两类
- Observer:观察者类,类似于监听器的实现
- Endpoint:终端者类,类似于存储过程的实现
问题34:Hbase常见优化有哪些?
- 内存优化:针对于不同的读写场景,合理的调整Memstore和BlockCache的比例大小
- 压缩优化:对列族配置压缩存储,减少IO消耗
- 布隆过滤:基于数据文件构建布隆索引,加快数据查询
- 提高客户端缓存空间、指定每次扫描的行数、设置合适的GC算法等
- 其他优化
- Linux句柄数优化,提高Linux线程、文件通道等资源句柄数
- HDFS句柄数优化:提高文件打开线程数、提高连接超时时间
- Zookeeper优化:优化连接超时时间