1.HBase 来源于哪篇博文?
A TheGoogle File System B MapReduce C BigTable
D Chubby 解析
谷歌的发布的三篇论文:21世纪前三架马车 分布式文件系统:GFS => HDFS 分布式计算:MapReduce => MAPReduce 分布式列式存储数据库:BigTable[Chubby] => Hbase[Zookeeper]
2. 下面对 HBase 的描述哪些是正确的?
A 不是开源的 B 是面向列的
C 是分布式的
D 是一种 NoSQL 数据库
3.HBase 依靠()存储底层数据
A HDFS
B Hadoop C Memory D MapReduce
4. HBase 依赖()提供消息通信机制
A Zookeeper
B Chubby C RPC D Socket
5.HBase 依赖()提供强大的计算能力
AZookeeper B Chubby C RPC DMapReduce
6. MapReduce 与 HBase 的关系,哪些描述是正确的?
A 两者不可或缺,MapReduce 是 HBase 可以正常运行的保证 B 两者不是强关联关系,没有 MapReduce,HBase 可以正常运行
CMapReduce 可以直接访问 HBase
D 它们之间没有任何关系
7.下面哪些选项正确描述了HBase 的特性?
8.下面哪些概念是 HBase 框架中使用的?
A HDFS B GridFS CZookeeper
D EXT3
9. LSM 含义是?
A 日志结构合并树
B 二叉树 C 平衡二叉树 D 长平衡二叉树
10.下面对 LSM 结构描述正确的是? A、C
A 顺序存储
B 直接写硬盘 C 需要将数据 Flush 到磁盘
D 是一种搜索平衡树
11.LSM 更能保证哪种操作的性能?B
12.LSM 的读操作和写操作是独立的?A
A 是
。 B 否。 C LSM 并不区分读和写 D LSM 中读写是同一种操作
13.LSM 结构的数据首先存储在()。 B
14.HFile 数据格式中的 Data 字段用于()。A
A 存储实际的 KeyValue 数据
B 存储数据的起点 C 指定字段的长度 D 存储数据块的起点
15.HFile 数据格式中的 MetaIndex 字段用于()。D
A Meta 块的长度 B Meta 块的结束点 C Meta 块数据内容 D Meta 块的起始点
16.HFile 数据格式中的 Magic 字段用于()。A
A 存储随机数,防止数据损坏
B 存储数据的起点 C 存储数据块的起点 D 指定字段的长度
17. HFile 数据格式中的 KeyValue 数据格式,下列选项描述正确的是()。A、D
A 是 byte[]数组
B 没有固定的结构 C 数据的大小是定长的 D有固定的结构
18.HFile 数据格式中的 KeyValue 数据格式中 Value 部分是()。C
A 拥有复杂结构的字符串 B 字符串 C 二进制数据
D 压缩数据
19. HBase 中的批量加载底层使用()实现。A
A MapReduce
B Hive C Coprocessor D BloomFilter
20.HBase 性能优化包含下面的哪些选项?A、B、C、D
21.Rowkey 设计的原则,下列哪些选项的描述是正确的?A、B、C
A 尽量保证越短越好
B 可以使用汉字
C 可以使用字符串
D 本身是无序的
22.HBase 构建二级索引的实现方式有哪些? A、B
A MapReduce
B Coprocessor
C BloomFilter D Filter
23.关于 HBase 二级索引的描述,哪些是正确的?A、B
A 核心是倒排表
B 二级索引概念是对应 Rowkey 这个“一级”索引
C 二级索引使用平衡二叉树 D 二级索引使用 LSM 结构
24.下列关于 Bloom Filter 的描述正确的是?A、C
A 是一个很长的二进制向量和一系列随机映射函数
B 没有误算率 C 有一定的误算率
D 可以在 Bloom Filter 中删除元素
25.HBase 官方版本可以安装在什么操作系统上?A、B、C
A CentOS
B Ubuntu
C RedHat
D Windows
26.HBase 虚拟分布式模式需要()个节点?A
27.HBase 分布式模式最好需要()个节点?C
28.下列哪些选项是安装 HBase 前所必须安装的?A、B
A 操作系统
B JDK
C ShellScript D JavaCode
29.解压.tar.gz 结尾的 HBase 压缩包使用的 Linux 命令是?A
A tar-zxvf
B tar -zx C tar -s D tar -nf
30.HBase 的特点是什么?
1)数据量大:⼀个表可以有数⼗亿⾏,上百万列; 2)不同行,列可以不同:每⾏都有⼀个可排序的主键和任意多的列,列可以根据需要动态的增加,同⼀张表中不同的⾏可以有截然不同的列; 3)⾯向列存储
:⾯向列(族)的存储和权限控制,列(族)独⽴检索; 4)稀疏:空(null)列并不占⽤存储空间,表可以设计的⾮常稀疏
; 5)数据多版本
:每个单元中的数据可以有多个版本,默认情况下版本号⾃动分配,是单元格插⼊时的时间戳
; 6)数据类型单⼀:Hbase 中的数据都是字节,没有类型。
31.HBase 和 Hive 的区别详解?
两者是什么?
Hive
是⼀个构建在 Hadoop 基础设施之上的数据仓库
。通过 Hive 可以使⽤ HQL语⾔查询存放在 HDFS 上的数据。HQL 是⼀种类 SQL 语⾔,这种语⾔最终被转化为Map/Reduce
. 虽然 Hive 提供了 SQL 查询功能,但是 Hive 不能够进⾏交互查询–因为它只能够在 Haoop 上批量的执⾏ Hadoop。HBase
是⼀种 Key/Value 系统
,它运⾏在 HDFS 之上
。和 Hive 不⼀样,Hbase 的能够在它的数据库上实时运⾏,⽽不是运⾏ MapReduce 任务
。Hbase 被分区为表格,表格⼜被进⼀步分割为列簇
。列簇必须使⽤ schema 定义,列簇将某⼀类型列集合起来(列不要求schema 定义)。例如,“message”列簇可能包含:“to”, ”from” “date”, “subject”, 和”body”. 每⼀个 key/value 对在 Hbase 中被定义为⼀个 cell,每⼀个 key 由 row-key,列簇、列和时间戳。在 Hbase 中,⾏是 key/value 映射的集合,这个映射通过 row-key 来唯⼀标识。Hbase 利⽤Hadoop 的基础设施,可以利⽤通⽤的设备进⾏⽔平的扩展。
两者的特点
Hive 帮助熟悉 SQL 的⼈运⾏ MapReduce 任务。因为它是 JDBC 兼容的,同时,它也能够和现存的 SQL ⼯具整合在⼀起。运⾏ Hive 查询会花费很⻓时间,因为它会默认遍历表中所有的数据。虽然有这样的缺点,⼀次遍历的数据量可以通过 Hive 的分区机制来控制。分区允许在数据集上运⾏过滤查询,这些数据集存储在不同的⽂件夹内,查询的时候只遍历指定⽂件夹(分区)中的数据。这种机制可以⽤来,例如,只处理在某⼀个时间范围内的⽂件,只要这些⽂件名中包括了时间格式。 HBase 通过存储 key/value 来⼯作。它⽀持四种主要的操作:增加或者更新⾏,查看⼀个范围内的 cell,获取指定的⾏,删除指定的⾏、列或者是列的版本。版本信息⽤来获取历史数据(每⼀⾏的历史数据可以被删除,然后通过 Hbase compactions 就可以释放出空间)。虽然 HBase 包括表格,但是 schema 仅仅被表格和列簇所要求,列不需要 schema。Hbase 的表格包括增加/计数功能。
限制
Hive ⽬前不⽀持更新操作
。另外,由于 hive 在 hadoop 上运⾏批量操作,它需要花费很⻓的时间,通常是⼏分钟到⼏个⼩时才可以获取到查询的结果。Hive 必须提供预先定义好的 schema 将⽂件和⽬录映射到列,并且 Hive 与 ACID 不兼容。HBase 查询是通过特定的语⾔来编写的,这种语⾔需要重新学习。类 SQL 的功能可以通过 Apache Phonenix 实现,但这是以必须提供 schema 为代价的。另外,Hbase 也并不是兼容所有的 ACID 特性,虽然它⽀持某些特性。最后但不是最重要的–为了运⾏ Hbase,Zookeeper是必须的,zookeeper 是⼀个⽤来进⾏分布式协调的服务,这些服务包括配置服务,维护元信息和命名空间服务。
应⽤场景
Hive 适合⽤来对⼀段时间内的数据进⾏分析查询,例如,⽤来计算趋势或者⽹站的⽇志。Hive 不应该⽤来进⾏实时的查询
。因为它需要很⻓时间才可以返回结果。 Hbase ⾮常适合⽤来进⾏⼤数据的实时查询
。Facebook ⽤ Hbase 进⾏消息和实时的分析。它也可以⽤来统计 Facebook 的连接数。
总结
Hive 和 Hbase 是两种基于 Hadoop 的不同技术 Hive 是⼀种类 SQL 的引擎,并且运⾏MapReduce 任务 Hbase 是⼀种在 Hadoop 之上的 NoSQL 的 Key/vale 数据库。 当然,这两种⼯具是可以同时使⽤的。就像⽤ Google 来搜索,⽤ FaceBook 进⾏社交⼀样,Hive 可以⽤来进⾏统计查询,HBase 可以⽤来进⾏实时查询,数据也可以从 Hive 写到 Hbase,设置再从Hbase 写回 Hive。
32.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)。
33.描述 HBase 的 rowKey 的设计原则?
1.业务原则:必须严格按照业务需求来设计rowkey
有别于传统数据库的设计
主键:只要有一列能区分每一行的唯一性,就可以作为主键
Hbase的rowkey不仅仅只有唯一性,还要考虑业务
用什么作为rowkey的前缀,就可以走索引查询 将最常用的查询条件作为前缀
例如:经常按照日期查询这张表,就用日期作为rowkey前缀
2.唯⼀原则
3.组合原则 :根据业务需求,将经常被查询的列放在rowkey中,共同构成rowkey
在查询时,将最常用的一些查询条件的列,放在rowkey中,让常用查询可以走索引
本身数据中还是有这些列的
userid/time/orderid/productid 商品表
rowkey:type_productid_name
水果 _ 001_ 荔枝
type:水果 productid:001 name:荔枝 颜色 价格 水果 _ 002_ 西瓜 数码 _ 003 _ 手机 查询所有的水果
scan. set ( new PrefiexFilter ( "水果" ) )
scan. set ( new PrefiexFilter ( "水果_001" ) )
订单表
后台:rowkey:orderId_userId_timestamp
ddfkjdlkfjdj_001_1593570797
userid serverTime orderid price productid paytype …… dffjklfksdss_002_1593570797 fklfjklfsklds_003_1593570797 dfdifjdkfjdd_004_1593570798 dffdsdseerd_001_1593570799 满足索引的
查询某个订单的信息 查询某个订单对应用户在某个时间的信息 如果我只知道时间,能不能查询?
可以查询,但是不走索引,走全表扫描,对时间这一列进行过滤 scan tbname {valuefilter {serverTime= 20200101}} 因为时间在rowkey中,但不是前缀,不能做前缀匹配的索引查询 用户:rowkey:userId_timestamp_orderId
001_1593570797_ddfkjdlkfjdj
userid serverTime orderid price productid paytype …… 001_1593570799_dffdsdseerd 002_1593570797_dffjklfksdss 003_1593570797_fklfjklfsklds 004_ 满足索引查询
用户登录,能查询所有的订单 用户登录,根据用户名查询这个用户在任何一个时间的订单
4.⻓度原则
如果rowkey越长,在底层进行查询比较时候就比较慢 在满足业务需求的情况下,越短越好 rowkey在底层每一列的存储中都有,是冗余的
如果长度真的无法缩短,可以使用编码变成16位或者32位的rowkey
Rowkey 是⼀个⼆进制码流,Rowkey 的⻓度被很多开发者建议说设计在 10~100 个字节,不过建议是越短越好,不要超过 16 个字节。
原因如下: (1)数据的持久化⽂件 HFile 中是按照 KeyValue 存储的,如果 Rowkey 过⻓⽐如 100个字节,1000 万列数据光 Rowkey 就要占⽤ 100*1000 万=10 亿个字节,将近 1G 数据,这会极⼤影响 HFile 的存储效率; (2)MemStore 将缓存部分数据到内存,如果 Rowkey 字段过⻓内存的有效利⽤率会降低,系统将⽆法缓存更多的数据,这会降低检索效率。因此 Rowkey 的字节⻓度越短越好。 (3)⽬前操作系统是都是 64 位系统,内存 8 字节对⻬。控制在 16 个字节,8 字节的整数倍利⽤操作系统的最佳特性。
5.散列原则
如果Rowkey 是按时间戳的⽅式递增,不要将时间放在⼆进制码的前⾯,建议将 Rowkey的⾼位作为散列字段,由程序循环⽣成,低位放时间字段
,这样将提⾼数据均衡分布在每个Regionserver 实现负载均衡的⼏率。如果没有散列字段,⾸字段直接是时间信息将产⽣所有新数据都在⼀个 RegionServer 上堆积的热点现象,这样在做数据检索的时候负载将会集中在个别 RegionServer,降低查询效率。 rowkey:时间 _ 订单Id _ 用户id
1593570797_dffjklfksdss_002 1593570797_fklfjklfsklds_003 1593570798_dfdifjdkfjdd_003 1593570799_dffdsdseerd_001 1593570800 1593570801 1593570802 …… 1600000000: | 2000000000 按照时间作为前缀,写入表中 因为region是有序的,如果rowkey也是有序的,必然会产生热点
必须将rowkey构建散列,常用的方式
推荐使用不连续的字段作为前缀
编码
:将连续的rowkey编码以后作为rowkey
1593570797:12qwert4 1593570798:asdfg789 读取数据时需要解码 MD5、CRC32 8位、16位、32位 反转
:读取时需要再反转回来
0080753951 1080793951 2080753951 3080753951 4080753951 5080753951 …… 9080753951 0180753951 1180753951 加随机数
不推荐,给定一个固定的随机范围0-9 0_1593570797_dffjklfksdss_002 9_1593570797_dffjklfksdss_003 牺牲很大的读取的代价
34.描述 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 ⽅法添加过滤器,这也是分⻚、多条件查询的基础。
35.请描述 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 设置了服务器⼀次返回的列数。 ① Batch 参数决定了⼀⾏数据分为⼏个 Result,它只针对⼀⾏数据,Batch 再⼤,也只能将⼀⾏的数据放⼊⼀个 Result 中。所以当⼀⾏数据有 10列,⽽ Batch 为 100 时,也只能将⼀⾏的所有列都放⼊⼀个 Result,不会混合其他⾏; ② 缓存值决定⼀次 RPC 返回⼏个 Result,根据 Batch 划分的 Result 个数除以缓存个数可以得到 RPC 消息个数(之前定义缓存值决定⼀次返回的⾏数,这是不准确的,准确来说是决定⼀次 RPC 返回的 Result 个数,由于在引⼊ Batch 之前,⼀⾏封装为⼀个 Result,因此定义缓存值决定⼀次返回的⾏数,但引⼊ Batch 后,更准确的说法是缓存值决定了⼀次 RPC返回的 Result 个数); RPC 请求次数 = (⾏数 * 每⾏列数) / Min(每⾏的列数,批量⼤⼩) / 扫描器缓存
36.请详细描述 HBase 中⼀个 cell 的结构?
HBase 中通过 row 和 columns 确定的为⼀个存贮单元称为 cell。 Cell:由{row key, column(=<family> + <label>), version}
唯⼀确定的单元。cell
中的数据是没有类型
的,全部是字节码形式存贮
。
37.简述 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 执⾏合并操作,最终的结果是整理合并出⼀个⽂件。
38.每天百亿数据存⼊ HBase,如何保证数据的存储正确和在规定 的时间⾥全部录⼊完毕,不残留数据?
需求分析:
1)百亿数据:证明数据量⾮常⼤; 2)存⼊ HBase:证明是跟 HBase 的写⼊数据有关; 3)保证数据的正确:要设计正确的数据结构保证正确性; 4)在规定时间内完成:对存⼊速度是有要求的。 解决思路:
1)数据量百亿条,什么概念呢?假设⼀整天 60x60x24 = 86400 秒都在写⼊数据,那么每秒的写⼊条数⾼达 100万条,HBase 当然是⽀持不了每秒百万条数据的,所以这百亿条数据可能不是通过实时地写⼊,⽽是批量地导⼊。批量导⼊推荐使⽤ BulkLoad ⽅式(推荐阅读:Spark 之读写 HBase),性能是普通写⼊⽅式⼏倍以上; 2)存⼊ HBase:普通写⼊是⽤ JavaAPI put 来实现,批量导⼊推荐使⽤ BulkLoad
; 3)保证数据的正确:这⾥需要考虑 RowKey 的设计、预建分区和列族设计等问题; 4)在规定时间内完成也就是存⼊速度不能过慢,并且当然是越快越好,使⽤ BulkLoad。
39.HBase 如何给 web 前端提供接⼝来访问?
使⽤ JavaAPI 来编写 WEB 应⽤,使⽤ HBase 提供的 RESTFul 接⼝。
40.请列举⼏个 HBase 优化⽅法?
1)减少调整
减少调整这个如何理解呢?HBase 中有⼏个内容会动态调整,如 region(分区)、HFile,所以通过⼀些⽅法来减少这些会带来 I/O 开销的调整。 1.1Region
如果没有预建分区
的话,那么随着 region 中条数的增加,region 会进⾏分裂,这将增加I/O 开销,所以解决⽅法就是根据你的 RowKey 设计来进⾏预建分区,减少 region 的动态分裂
。 1.2HFile
HFile 是数据底层存储⽂件,在每个 memstore 进⾏刷新时会⽣成⼀个 HFile,当 HFile增加到⼀定程度时,会将属于⼀个 region 的 HFile 进⾏合并,这个步骤会带来开销但不可避免,但是合并后 HFile ⼤⼩如果⼤于设定的值,那么 HFile 会重新分裂。为了减少这样的⽆谓的 I/O 开销,建议估计项⽬数据量⼤⼩,给 HFile 设定⼀个合适的值。
2)减少启停
数据库事务机制就是为了更好地实现批量写⼊,较少数据库的开启关闭带来的开销,那么 HBase 中也存在频繁开启关闭带来的问题。 2.1关闭 Compaction,在闲时进⾏⼿动 Compaction
。
因为 HBase 中存在 Minor Compaction 和 Major Compaction,也就是对 HFile 进⾏合并,所谓合并就是 I/O 读写,⼤量的 HFile 进⾏肯定会带来 I/O 开销,甚⾄是 I/O ⻛暴,所以为了避免这种不受控制的意外发⽣,建议关闭⾃动 Compaction,在闲时进⾏ compaction。 2.2批量数据写⼊时采⽤ BulkLoad
。
如果通过 HBase-Shell 或者 JavaAPI 的 put 来实现⼤量数据的写⼊,那么性能差是肯定并且还可能带来⼀些意想不到的问题,所以当需要写⼊⼤量离线数据时建议使⽤ BulkLoad
3)减少数据量
虽然我们是在进⾏⼤数据开发,但是如果可以通过某些⽅式在保证数据准确性同时减少数据量,何乐⽽不为呢? 3.1开启过滤,提⾼查询速度
开启 BloomFilter,BloomFilter 是列族级别的过滤,在⽣成⼀个 StoreFile 同时会⽣成⼀个 MetaBlock,⽤于查询时过滤数据 3.2使⽤压缩
:⼀般推荐使⽤ Snappy 和 LZO 压缩
4)合理设计
在⼀张 HBase 表格中 RowKey 和 ColumnFamily 的设计是⾮常重要,好的设计能够提⾼性能和保证数据的准确性 4.1RowKey 设计:应该具备以下⼏个属性
散列性:散列性能够保证相同相似的 rowkey 聚合,相异的 rowkey 分散,有利于查询。 简短性:rowkey 作为 key 的⼀部分存储在 HFile 中,如果为了可读性将 rowKey 设计得过⻓,那么将会增加存储压⼒。 唯⼀性:rowKey 必须具备明显的区别性。 业务性:举例来说:
假如我的查询条件⽐较多,⽽且不是针对列的条件,那么 rowKey 的设计就应该⽀持多条件查询。 如果我的查询要求是最近插⼊的数据优先,那么 rowKey 则可以采⽤加上 Long.Max-时间戳的⽅式,这样 rowKey 就是递减排列。 4.2列族的设计
列族的设计需要看应⽤场景 多列族设计的优劣: 优势:HBase 中数据时按列进⾏存储的,那么查询某⼀列族的某⼀列时就不需要全盘扫描,只需要扫描某⼀列族,减少了读 I/O;其实多列族设计对减少的作⽤不是很明显,适⽤于读多写少
的场景 劣势:降低了写的 I/O 性能。原因如下:数据写到 store 以后是先缓存在 memstore 中,同⼀个region中存在多个列族则存在多个store,每个store都⼀个memstore,当memstore进⾏ flush 时,属于同⼀个 region 的 store 中的 memstore 都会进⾏ flush,增加 I/O 开销。
41.HBase 中 RowFilter 和 BloomFilter 原理?
1)RowFilter 原理简析
RowFilter 顾名思义就是对 rowkey 进⾏过滤,那么 rowkey 的过滤⽆⾮就是相等(EQUAL)、⼤于(GREATER)、⼩于(LESS),⼤于等于(GREATER_OR_EQUAL),⼩于等于(LESS_OR_EQUAL)和不等于(NOT_EQUAL)⼏种过滤⽅式。Hbase 中的 RowFilter 采⽤⽐较符结合⽐较器的⽅式来进⾏过滤。 ⽐较器的类型如下:
BinaryComparator BinaryPrefixComparator NullComparator BitComparator RegexStringComparator SubStringComparator 例如
Filter rowFilter = new RowFilter( CompareFilter. CompareOp. EQUAL, new BinaryComparator( Bytes. toBytes( rowKeyValue) ) ) ;
Scan scan = new Scan( ) ;
scan. setFilter( rowFilter)
在上⾯例⼦中,⽐较符为 EQUAL,⽐较器为 BinaryComparator
2)BloomFilter 原理简析
主要功能:提供随机读的性能 存储开销:BloomFilter 是列族级别的配置,⼀旦表格中开启 BloomFilter,那么在⽣成 StoreFile 时同时会⽣成⼀份包含 BloomFilter 结构的⽂件 MetaBlock,所以会增加⼀定的存储开销和内存开销 粒度控制:ROW 和 ROWCOL BloomFilter 的原理:
① 内部是⼀个 bit 数组,初始值均为 0 ② 插⼊元素时对元素进⾏ hash 并且映射到数组中的某⼀个 index,将其置为 1,再进⾏多次不同的 hash 算法,将映射到的 index 置为 1,同⼀个 index 只需要置 1 次。 ③ 查询时使⽤跟插⼊时相同的 hash 算法,如果在对应的 index 的值都为 1,那么就可以认为该元素可能存在,注意,只是可能存在 ④ 所以 BlomFilter 只能保证过滤掉不包含的元素,⽽不能保证误判包含 设置:在建表时对某⼀列设置 BloomFilter 即可
42.HBase 的导⼊导出⽅式?
1)导⼊:
bin/hbase org.apache.hadoop.hbase.mapreduce.Driver import
表名 路径 路径:来源 本地路径 file:///path HDFS hdfs://cluster1/path 2)导出:
bin/hbase org.apache.hadoop.hbase.mapreduce.Driver export
表名 路径 路径:⽬的地 本地路径 file:///path HDFS hdfs://cluster1/path
43.Region 如何预建分区?
预分区
的⽬的主要是在创建表的时候指定分区数,提前规划表有多个分区,以及每个分区的区间范围
,这样在存储的时候 rowkey 按照分区的区间存储,可以避免 region 热点
问题。 通常有两种⽅案:⽅案 1:shell ⽅法
create 'tb_splits' , {NAME = > 'cf' , VERSIONS= > 3 }, {SPLITS = > [ '10' , '20' , '30' ] }
⽅案 2: JAVA 程序控制
2.1取样,先随机⽣成⼀定数量的 rowkey,将取样数据按升序排序放到⼀个集合⾥; 2.2根据预分区的 region 个数,对整个集合平均分割,即是相关的 splitKeys; 2.3HBaseAdmin.createTable(HTableDescriptor tableDescriptor,byte[][]splitkeys)可以指定预分区的 splitKey,即是指定 region 间的 rowkey 临界值。
44.HRegionServer 宕机如何处理?
1)ZooKeeper 会监控 HRegionServer 的上下线情况,当 ZK 发现某个 HRegionServer 宕机之后会通知 HMaster 进⾏失效备援; 2)该 HRegionServer 会停⽌对外提供服务,就是它所负责的 region 暂时停⽌对外提供服务; 3)HMaster 会将该 HRegionServer 所负责的 region 转移到其他 HRegionServer 上,并且会对 HRegionServer 上存在 memstore 中还未持久化到磁盘中的数据进⾏恢复; 4) 这个恢复的⼯作是由 WAL 重播来完成,这个过程如下:
4.1wal 实际上就是⼀个⽂件,存在/hbase/WAL/对应 RegionServer 路径下。 4.2宕机发⽣时,读取该 RegionServer 所对应的路径下的 wal ⽂件,然后根据不同的region 切分成不同的临时⽂件 recover.edits。 4.3当 region 被分配到新的 RegionServer 中,RegionServer 读取 region 时会进⾏是否存在recover.edits,如果有则进⾏恢复。
45.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 ⼀分为⼆
。
46.HBase 内部机制是什么?
Hbase 是⼀个能适应联机业务的数据库系统 物理存储
:hbase 的持久化数据是将数据存储在 HDFS 上
。存储管理
:⼀个表是划分为很多 region 的,这些 region 分布式地存放在很多 regionserver上 Region 内部还可以划分为 store,store 内部有 memstore 和 storefile
。版本管理
:hbase 中的数据更新本质上是不断追加新的版本,通过 compact 操作来做版本间的⽂件合并 Region 的 split
。集群管理
:ZooKeeper + HMaster + HRegionServer
。
47.HTable API 有没有线程安全问题,在程序中是单例还是多例?
在单线程环境下使⽤ hbase 的 htable 是没有问题,但是突然⾼并发多线程情况下就可能出现问题。 HTable 不是线程安全的
。建议使⽤同⼀个HBaseConfiguration 实例来创建 HTable 实例,这样可以共享 ZooKeeper 和 socket 实例。
48.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 中。
49.如何提⾼ HBase 客户端的读写性能?请举例说明
1 开启 bloomfilter 过滤器
,开启 bloomfilter ⽐没开启要快 3、4倍 2 Hbase 对于内存有特别的需求,在硬件允许的情况下配⾜够多的内存给它
3 通过修改 hbase-env.sh 中的export HBASE_HEAPSIZE=3000 #这⾥默认为 1000m 4 增⼤ RPC 数量
通过修改 hbase-site.xml 中的 hbase.regionserver.handler.count 属性,可以适当的放⼤RPC 数量,默认值为 10 有点⼩。
50.HBase 集群安装注意事项?
1.HBase 需要 HDFS 的⽀持,因此安装 HBase 前确保 Hadoop 集群安装完成; 2.HBase 需要 ZooKeeper 集群的⽀持,因此安装 HBase 前确保 ZooKeeper 集群安装完成; 3.注意 HBase 与 Hadoop 的版本兼容性; 4.注意 hbase-env.sh 配置⽂件和 hbase-site.xml 配置⽂件的正确配置; 5.注意 regionservers 配置⽂件的修改; 6.注意集群中的各个节点的时间必须同步,否则启动 HBase 集群将会报错;
51.直接将时间戳作为⾏健,在写⼊单个 region 时候会发⽣热点问 题,为什么呢?
region 中的 rowkey 是有序存储
,若时间⽐较集中。就会存储到⼀个 region 中,这样⼀个 region 的数据变多,其它的 region 数据很少,加载数据就会很慢
,直到 region 分裂,此问题才会得到缓解。
52.请描述如何解决 HBase 中 region 太⼩和 region 太⼤带来的冲 突?
Region值过⼤
会发⽣多次 compaction
,将数据读⼀遍并重写⼀遍到 hdfs 上,占⽤ ioregion值过⼩
会造成多次 split
,region 会下线,影响访问服务最佳的解决⽅法是调整 hbase.hregion.max.filesize 为 256m。
53.解释⼀下布隆过滤器原理
Bloom Filter 是⼀种空间效率很⾼的随机数据结构,它利⽤位数组
很简洁地表示⼀个集合
,并能判断⼀个元素是否属于这个集合
。Bloom Filter 的这种⾼效是有⼀定代价的:在判断⼀个元素是否属于某个集合时,有可能会把不属于这个集合的元素误认为属于这个集合(false positive)。因此,Bloom Filter 不适合那些“零错误”的应⽤场合。⽽在能容忍低错误率的应⽤场合
下,Bloom Filter 通过极少的错误换取了存储空间的极⼤节省。