为什么考察HBase?
作为一个高可靠性、高性能、列存储、可伸缩、实时读写的分布式数据库系统,HBase在大数据生态系统中占据重要的地位。我们必须要了解其基本原理和概念,一方面可以对数据分析工作中排查问题有比较大的帮助,另一方面方便我们与他人沟通交流。
1.hbase是一个分布式的,基于列式存储的数据库,基于hadoop的hdfs存储,zookeeper进行管理。
2.hbase 适合存储半结构化或非结构化的数据,比如数据结构字段不够确定或者杂乱无章很难按照一个概念去抽取的数据。
3.hbase的存储效率比较高,为null的数据不会被存储。
4.hbase的表包含rowKey、列族和列,存储数据的最小单元是单元格,单元格包含数据及其对应的写入时间戳,新写入数据时,附带写入时间戳,可以查询到之前写入的多个版本。
5.hbase是主从结构,hmaster作为主节点,hregionServer作为从节点。
答:Hbase 中的每张表都通过行键(rowkey)按照一定的范围被分割成多个子表(HRegion),默认一个 HRegion 超过 256M 就要被分割成两个,由 HRegionServer 管理,管理哪些 HRegion由 Hmaster 分配。HRegion 存取一个子表时,会创建一个 HRegion 对象,然后对表的每个列族(Column Family)创建一个 store 实例,每个 store 都会有 0 个或多个 StoreFile 与之对应,每个 StoreFile 都会对应一个 HFile, HFile 就是实际的存储文件;一个 HRegion 还拥有一个 MemStore 实例。
答:HBase遵守主从架构的技术,由一个主HMaster和若干个从HRegionServer组成。HBase中的一张表的数据由若干个HRegion组成,也就是说每一个HRegion负责管理一张表中的一段数据,HRegion都是分布式的存在于HRegionServer中,所以说HRegion是HBase表中数据分布式存储的单位。那么一个HRegion中又是由若干个column family的数据组成;在HRegion中每个column family数据由一个store管理,每个store包含了一个memory store和若干个HFile组成,HFile的数据最终会落地到HDFS文件中,所以说HBase依赖HDFS。
在HBase中还有一部分元数据信息,比如HMaster的状态信息、HRegionServer的状态信息以及HRegion的状态信息等,这些信息都是存储在zookeeper集群中。请看下图便于理解。
答:Get的功能是精准查找,按指定RowKey 获取唯一一条记录。Scan的功能是范围查找,按指定的条件获取一批记录。实际上它们的实现是一样的,get操作就是一种特殊的scan(begin和end相同的scan操作)。而且hbase读数据的操作都是scan,代码级别实现的是scan,并没有特别针对get的操作。
答:cell:由{row key, column(=<family> + <label>), version}唯一确定的单元,cell中的数据是没有类型的,全部是字节码形式存储。
答:在 hbase 中每当有 memstore 数据 flush 到磁盘之后,就形成一个 storefile,当 storeFile 的数量达到一定程度后,就需要将 storefile 文件来进行 compaction 操作。
Compact 的作用:
1>.合并文件
2>.清除过期,多余版本的数据
3>.提高读写数据的效率
HBase 中实现了两种 compaction 的方式:minor and major。
这两种 compaction 方式的区别是:
1、 Minor 操作只用来做部分文件的合并操作以及包括 minVersion=0,并且设置 ttl 的过期版本清理,不做任何删除数据、多版本数据的清理工作。
2、 Major 操作是对 Region 下的 HStore 下的所有 StoreFile 执行合并操作,最终的结果是整理合并出一个文件。
答:宕机分为 HMaster 宕机和 HRegisoner 宕机,如果是 HRegisoner 宕机, HMaster 会将其所管理的 region 重新分布到其他活动的 RegionServer 上,由于数据和日志都持久在 HDFS中,该操作不会导致数据丢失。所以数据的一致性和安全性是有保障的。如果是 HMaster 宕机,会通过Zookeeper 的 Master Election 机制重新选出一个正在运行的Master 进程作为活跃节点,继续提供服务。
Hbase读写流程
读:
① HRegionServer 保存着 meta 表以及表数据,要访问表数据,首先 Client 先去访问zookeeper,从 zookeeper 里面获取 meta 表所在的位置信息,即找到这个 meta 表在哪个HRegionServer 上保存着。
② 接着 Client 通过刚才获取到的 IP 访问对应的HRegionServer,获取到 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支持动态添加列。
2.记录很稀疏:
关系型数据库的列的数量是相对稳定的,null值也会占据存储位,为null的列浪费了存储空间。HBase为null的Column不会被存储,这样既节省了空间又提高了读性能。
3.多版本数据:
依据Row key和Column key定位到的Value能够有随意数量的版本号值,因此对于需要存储变动历史记录的数据,用HBase是很方便的。比如某个用户的Address变更,其变更记录也许也是具有研究意义的。
4.仅要求最终一致性:
对于数据存储事务的要求不像金融行业和财务系统这么高,只要保证最终一致性就行。
5.要求高可用性和支持海量数据以及很大的瞬间写入量:
1)WAL解决高可用,支持PB级数据,写入性能高。
2)索引插入比查询操作更频繁的情况。比如,对于历史记录表和日志文件。(HBase的写操作更加高效)。
① Rowkey 长度原则
Rowkey 是一个二进制码流,一般是10~100个字节,建议越短越好,不超过16字节为宜。
② Rowkey 散列原则
如果Rowkey 是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将Rowkey的高位作为散列字段,由程序循环生成,低位放时间字段,这样将提高数据均衡分布在每个Regionserver 实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息将产生所有新数据都在一个 RegionServer 上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别 RegionServer,降低查询效率。
③ Rowkey 唯一原则
必须在设计上保证其唯一性。
1.开启 bloomfilter 过滤器,开启 bloomfilter 比没开启要快 3、4 倍。
2.Hbase 对于内存有特别的需求,在硬件允许的情况下配足够多的内存给它。
3.增大 RPC 数量,通过修改 hbase-site.xml 中的 hbase.regionserver.handler.count 属性,可以适当的放大RPC 数量,默认值为 10 有点小。
答:Region过小会发生多次compaction,将数据读一遍并重写一遍到hdfs上,占用io,region过大会造成多次split,region 会下线,影响访问服务.
HBase的关键组件是什么?
1)Table:可理解为传统数据库中的一个表,但因为SchemaLess的设计,它较之传统数据库的表而言,在设计上更加灵活。
2)Region:将表横向切割为一个个子表,子表在HBase中被称之为Region。
3)RegionServer:数据服务进程,Region必须部署在某一个RegionServer上才可以提供读写服务。
4)HFile:HBase数据库在底层分布式文件系统中的文件组织形式。
5)Column Family:一些列的集合。不同的Column Family数据被存储在不同的路径中。MemStore:用来在内存中缓存一定大小的数据,达到设定的阈值后批量写入到底层文件系统中。数据是有序的。
下图清晰的展示了Table,Region,RegionServer,HFile,MemStore,Column Family在HBase的逻辑关系。
Hbase中有哪些数据操作命令类型?
-
get:查询操作
-
put:插入操作
-
delete:删除操作
-
scan:扫描所有记录
在HBase中什么是列族?
解释Hbase如何实际删除一行
介绍下RowFilter
Region如何预建分区
create 't1', 'f1',SPLITS=>['10','20','30']
create 't1','f1',SPLITS_FILE =>'splits.txt'
创建一个byte[][] splitKeys = {{1,2,3},{4,5,6}}
admin.createTable(tableDesc,splitKeys)
Hbase中有多少数据操作命令类型
create_namespace 'test_ns'
在新的namespace中创建表:
//test表中有2个column familycreate 'test_ns:test','f','e'
put 'test_ns:test','rowkey-1','f:a','value1'put 'test_ns:test','rowkey-1','e:b','value2'
//删除一列delete 'test_ns:test','rowkey-1','f:a'//删除一行deleteall 'test_ns:test','rowkey-1'
put 'test_ns:test','rowkey-1','f:a','value1'
get 'test_ns:test','rowkey-1'
get 'test_ns:test','rowkey-1',{COLUMN => 'f:a'}
使用HBase shell创建一张表,并对其进行增删改查?
简述下HBASE中split机制
Hbase如何借助其他技术实现二级索引
众所周知,在hbase中使用rowKey检索数据是非常快速的,但是如果想要根据某一列进行数据的检索,速度就会慢很多,这是因为hbase没有二级索引,对某一列进行检索就需要做全表扫描。
明白了这一点,那么我们就可以借助其他技术来实现hbase的二级索引功能,最常用的技术手段便是,借助Solr或者ElasticSearch。它的核心思想是,在数据写入hbase的同时,将rowKey以及需要用于检索的列写入Solr或者ElasticSearch建立倒排索引,那么我们在对某一列进行检索时,可以先去Solr或者ElasticSearch中检索出对应的rowKey,然后再去Hbase中进行查找,这样两段式查找,就避免了全表扫描,大大提高了检索的速度。
RowKey设计实例
一款视频APP的播放行为统计数据,需要查询每天每个视频类型播放量TopN的视频(播放量从高到低排序),如何设计rowkey?
需求分析:首先我们存储的数据是每个视频在某天的播放量统计数据,我们读取数据的场景是获取某天某个视频类型的播放量TopN(可以是Top10、Top100、Top200等)视频列表,那么我们的设计思路可以是将RowKey分为三段,第一段存储播放日期,第二段存放视频类型,第三段存储倒排的播放量。这样在检索时,我们可以设置过滤RowKey前缀是播放日期+视频类型,然后提取前N条记录。
参考示例:key_day + content_type + (99999999-play_num)
说明:key_day是播放日期,content_type是视频类型,play_num是视频的播放量,用(9999999999-play_num)是为了反转排序,将播放量大的视频排在前面。需要注意的是,RowKey每段的长度一定要保持一致,如果长度不够,需要用其他字符补足位数。
这样设计rowkey就可以满足每天每个视频类型的TopN查询,查询的时候要配合前缀过滤器PrefixFilter进行升序排序,得到的就是一个播放量倒排的视频列表。
小结
本篇HBase面试指南,结合网络上的经典考题和工作中总结改编的题目一共24道,考点涉及了基本概念和基本操作以及原理方面的内容,希望读者可以查漏补缺,完善HBase面试知识点。