HBase⾯试题整理
1、 HBase的特点是什么?
1)⼤:⼀个表可以有数⼗亿⾏,上百万列;
2)⽆模式:每⾏都有⼀个可排序的主键和任意多的列,列可以根据需要动态的增加,同⼀张表中不同的⾏可以有截然不同的列;
3)⾯向列:⾯向列(族)的存储和权限控制,列(族)独⽴检索;
4)稀疏:空(null)列并不占⽤存储空间,表可以设计的⾮常稀疏;
5)数据多版本:每个单元中的数据可以有多个版本,默认情况下版本号⾃动分配,是单元格插⼊时的时间戳;
6)数据类型单⼀:Hbase中的数据都是字符串,没有类型。
2、HBase和Hive的区别?
Hive和Hbase是两种基于Hadoop的不同技术–Hive是⼀种类SQL的引擎,并且运⾏MapReduce任务,H
base是⼀种在Hadoop之上的NoSQL 的Key/vale数据库。
当然,这两种⼯具是可以同时使⽤的。就像⽤Google来搜索,⽤FaceBook进⾏社交⼀样,Hive可以⽤来进⾏统计查询,HBase可以⽤来进⾏实时查询,
数据也可以从Hive写到Hbase,设置再从Hbase写回Hive。
3、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)。
4、描述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唯⼀原则
必须在设计上保证其唯⼀性。
5、描述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 ⽅法添加过滤器,这也是分页、多条件查询的基础。
6、请描述HBase中scan对象的setCache和setBatch⽅法的使⽤?(☆☆☆☆☆)
setCache⽤于设置缓存,即设置⼀次RPC请求可以获取多⾏数据。对于缓存操作,如果⾏的数据量⾮常⼤,多⾏数据有可能超过客户端进程的内存容量,
由此引⼊批量处理这⼀解决⽅案。
setBatch ⽤于设置批量处理,批量可以让⽤户选择每⼀次ResultScanner实例的next操作要取回多少列,例如,在扫描中设置setBatch(5),则⼀次next()返回的Result实例会包括5列。如果⼀⾏包括的列数超过了批量中设置的值,则可以将这⼀⾏分⽚,每次next操作返回⼀⽚,当⼀⾏的列数不能被批量中
设置的值整除时,最后⼀次返回的Result实例会包含⽐较少的列,如,⼀⾏17列,batch设置为5,则⼀共返回4个Result实例,这4个实例中包括的列数分别
为5、5、5、2。
组合使⽤扫描器缓存和批量⼤⼩,可以让⽤户⽅便地控制扫描⼀个范围内的⾏键所需要的RPC调⽤次数。Cache设置了服务器⼀次返回的⾏数,
⽽Batch设置了服务器⼀次返回的列数。
假如我们建⽴了⼀张有两个列族的表,添加了10⾏数据,每个⾏的每个列族下有10列,这意味着整个表⼀共有200列(或单元格,因为每个列只有⼀个版本),
其中每⾏有20列。
① Batch参数决定了⼀⾏数据分为⼏个Result,它只针对⼀⾏数据,Batch再⼤,也只能将⼀⾏的数据放⼊⼀个Result中。所以当⼀⾏数据有10列,
⽽Batch为100时,也只能将⼀⾏的所有列都放⼊⼀个Result,不会混合其他⾏;
②缓存值决定⼀次RPC返回⼏个Result,根据Batch划分的Result个数除以缓存个数可以得到RPC消息个数(之前定义缓存值决定⼀次返回的⾏数,
这是不准确的,准确来说是决定⼀次RPC返回的Result个数,由于在引⼊Batch之前,⼀⾏封装为⼀个Result,因此定义缓存值决定⼀次返回的⾏数,但引⼊Batch后,
更准确的说法是缓存值决定了⼀次RPC返回的Result个数);
RPC请求次数 = (⾏数 * 每⾏列数) / Min(每⾏的列数,批量⼤⼩) / 扫描器缓存
下图展⽰了缓存和批量两个参数如何联动,下图中有⼀个包含9⾏数据的表,每⾏都包含⼀些列。使⽤了⼀个缓存为6、批量⼤⼩为3的扫描器,
需要三次RPC请求来传送数据:
7、请详细描述HBase中⼀个cell的结构?
HBase中通过row和columns确定的为⼀个存贮单元称为cell。
Cell:由{row key, column(=<family> + <label>), version}唯⼀确定的单元。cell 中的数据是没有类型的,全部是字节码形式存贮。
8、简述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执⾏合并操作,最终的结果是整理合并出⼀个⽂件。
9、每天百亿数据存⼊HBase,如何保证数据的存储正确和在规定的时间⾥全部录⼊完毕,不残留数据?(☆☆☆☆☆)
需求分析:
1)百亿数据:证明数据量⾮常⼤;
2)存⼊HBase:证明是跟HBase的写⼊数据有关;
3)保证数据的正确:要设计正确的数据结构保证正确性;
4)在规定时间内完成:对存⼊速度是有要求的。
解决思路:
1)数据量百亿条,什么概念呢?假设⼀整天60x60x24 = 86400秒都在写⼊数据,那么每秒的写⼊条数⾼达100万条,HBase当然是⽀持不了每秒百万条数据的,
所以这百亿条数据可能不是通过实时地写⼊,⽽是批量地导⼊。批量导⼊推荐使⽤BulkLoad⽅式(推荐阅读:Spark之读写HBase),性能是普通写⼊⽅式⼏倍以上;
2)存⼊HBase:普通写⼊是⽤JavaAPI put来实现,批量导⼊推荐使⽤BulkLoad;
3)保证数据的正确:这⾥需要考虑RowKey的设计、预建分区和列族设计等问题;
4)在规定时间内完成也就是存⼊速度不能过慢,并且当然是越快越好,使⽤BulkLoad。
10、请列举⼏个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开销。
11、Region如何预建分区?
预分区的⽬的主要是在创建表的时候指定分区数,提前规划表有多个分区,以及每个分区的区间范围,这样在存储的时候rowkey按照分区的区间存储,
可以避免region热点问题。
通常有两种⽅案:
⽅案1:shell ⽅法
create ‘tb_splits’, {NAME => ‘cf’,VERSIONS=> 3},{SPLITS => [‘10’,‘20’,‘30’]}
⽅案2:JAVA程序控制
①取样,先随机⽣成⼀定数量的rowkey,将取样数据按升序排序放到⼀个集合⾥;
②根据预分区的region个数,对整个集合平均分割,即是相关的splitKeys;
③ ateTable(HTableDescriptor tableDescriptor,byte[][]splitkeys)可以指定预分区的splitKey,
即是指定region间的rowkey临界值。
12、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,如果有则进⾏恢复。
13、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⼀分为⼆。
14、HBase内部机制是什么?
Hbase是⼀个能适应联机业务的数据库系统
物理存储:hbase的持久化数据是将数据存储在HDFS上。
hbase主要用来储存什么数据
存储管理:⼀个表是划分为很多region的,这些region分布式地存放在很多regionserver上Region内部还可以划分为store,
store内部有memstore和storefile。
版本管理:hbase中的数据更新本质上是不断追加新的版本,通过compact操作来做版本间的⽂件合并Region的split。
集管理:ZooKeeper + HMaster + HRegionServer。
15、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中。
16、HBase在进⾏模型设计时重点在什么地⽅?⼀张表中定义多少个Column Family最合适?为什么?(☆☆☆☆☆)
Column Family的个数具体看表的数据,⼀般来说划分标准是根据数据访问频度,如⼀张表⾥有些列访问相对频繁,⽽另⼀些列访问很少,这时可以把这张表划分成两个列族,分开存储,提⾼访问效率。
17、如何提⾼HBase客户端的读写性能?请举例说明(☆☆☆☆☆)
①开启bloomfilter过滤器,开启bloomfilter⽐没开启要、4倍
② Hbase对于内存有特别的需求,在硬件允许的情况下配⾜够多的内存给它
③通过修改hbase-env.sh中的 export HBASE_HEAPSIZE=3000 #这⾥默认为1000m
④增⼤RPC数量
通过修改l中的unt属性,可以适当的放⼤RPC数量,默认值为10有点⼩。
18、HBase集安装注意事项?
① HBase需要HDFS的⽀持,因此安装HBase前确保Hadoop集安装完成;
② HBase需要ZooKeeper集的⽀持,因此安装HBase前确保ZooKeeper集安装完成;
③注意HBase与Hadoop的版本兼容性;
④注意hbase-env.sh配置⽂件和l配置⽂件的正确配置;
⑤注意regionservers配置⽂件的修改;
⑥注意集中的各个节点的时间必须同步,否则启动HBase集将会报错。
19、直接将时间戳作为⾏健,在写⼊单个region 时候会发⽣热点问题,为什么呢?(☆☆☆☆☆)
region中的rowkey是有序存储,若时间⽐较集中。就会存储到⼀个region中,这样⼀个region的数据变多,其它的region数据很少,加载数据就会很慢,
直到region分裂,此问题才会得到缓解。
20、请描述如何解决HBase中region太⼩和region太⼤带来的冲突?(☆☆☆☆☆)
Region过⼤会发⽣多次compaction,将数据读⼀遍并重写⼀遍到hdfs 上,占⽤io,region过⼩会造成多次split,region 会下线,影响访问服务,
最佳的解决⽅法是调整hbase.hregion. max.filesize 为256m。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。