答:1)hbase是一个分布式的,基于列式存储的数据库,基于hadoop的hdfs存储,zookeeper进行管理。
2)hbase 适合存储半结构化或非结构化的数据,对于数据结构字段不够确定或者杂乱无章很难按照一个概念去抽取的数据。
3)hbase为null的数据不会被存储
4)基于的表包含rowKey,时间戳和列族,新写入数据时,时间戳更新,同时可以查询到以前的版本
5)hbase是主从结构,hmaster作为主节点,hregionServer作为从节点
使用 MapReduce Job 方式,根据 Hbase API 编写 java 脚本,将文本文件用文件流的方式截取,然后存储到多个字符串数组中,在 put 方法下,通过对表中的列族进行 for 循环遍历列名,用 if 判断列名后进行 for 循环调用 put.add 的方法对列族下每一个列进行设值,每个列族下有几个了就赋值几次!没有表先对先创建表。
答: Hbase 中的每张表都通过行键(rowkey)按照一定的范围被分割成多个子表(HRegion),默认一个 HRegion 超过 256M 就要被分割成两个,由 HRegionServer 管理,管理哪些 HRegion由 Hmaster 分配。 HRegion 存取一个子表时,会创建一个 HRegion 对象,然后对表的每个列族(Column Family)创建一个 store 实例,每个 store 都会有 0 个或多个 StoreFile 与之对应,每个 StoreFile 都会对应一个 HFile, HFile 就是实际的存储文件,因此,一个 HRegion 还拥有一个 MemStore 实例。
答案:共同点:1.hbase与hive都是架构在hadoop之上的。都是用hadoop作为底层存储
区别:2.Hive是建立在Hadoop之上为了减少MapReducejobs编写工作的批处理系统,HBase是为了支持弥补Hadoop对实时操作的缺陷的项目 。
3.想象你在操作RMDB数据库,如果是全表扫描,就用Hive+Hadoop,如果是索引访问,就用HBase+Hadoop 。
4.Hive query就是MapReduce jobs可以从5分钟到数小时不止,HBase是非常高效的,肯定比Hive高效的多。
5.Hive本身不存储和计算数据,它完全依赖于HDFS和MapReduce,Hive中的表纯逻辑。
6.hive借用hadoop的MapReduce来完成一些hive中的命令的执行
7.hbase是物理表,不是逻辑表,提供一个超大的内存hash表,搜索引擎通过它来存储索引,方便查询操作。
8.hbase是列存储。
9.hdfs作为底层存储,hdfs是存放文件的系统,而Hbase负责组织文件。
10.hive需要用到hdfs存储文件,需要用到MapReduce计算框架。
答:实时查询,可以认为是从内存中查询,一般响应时间在 1 秒内。 HBase 的机制是数据先写入到内存中,当数据量达到一定的量(如 128M),再写入磁盘中, 在内存中,是不进行数据的更新或合并操作的,只增加数据,这使得用户的写操作只要进入内存中就可以立即返回,保证了 HBase I/O 的高性能。
答: rowKey 最好要创建有规则的 rowKey,即最好是有序的。 HBase 中一张表最好只创建一到两个列族比较好,因为 HBase 不能很好的处理多个列族。
1.按指定RowKey 获取唯一一条记录, get方法(org.apache.hadoop.hbase.client.Get)Get 的方法处理分两种 : 设置了 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 方法添加过滤器,这也是分页、多条件查询的基础。
3.全表扫描,即直接扫描整张表中所有行记录
HBase 中通过 row 和 columns 确定的为一个存贮单元称为 cell。Cell:由{row key, column(=
在默认情况下,如果你需要从hbase中查询数据,在获取结果ResultScanner时,hbase会在你每次调用ResultScanner.next()操作时对返回的每个Row执行一次RPC操作。即使你使用ResultScanner.next(int nbRows)时也只是在客户端循环调用RsultScanner.next()操作,你可以理解为hbase将执行查询请求以迭代器的模式设计,在执行next()操作时才会真正的执行查询操作,而对每个Row都会执行一次RPC操作。
caching | batch | Results | RPCs | Notes |
1 | 1 | 200 | 201 | 额外的一个RPC是用来判断scan是否完成 |
200 | 1 | 200 | 2 | |
2000 | 100 | 10 | 1 | 超过的部分没有用处,但是判断scan也在那一个RPC 中完成 |
2 | 100 | 10 | 6 | 10/2 +1 (额外的判断开销) |
2 | 10 | 20 | 11 | |
5 | 100 | 10 | 3 | |
5 | 20 | 10 | 3 | |
10 | 10 | 20 | 3 |
在 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 执行合并操作,最终的结果是整理合并出一个文件。简述 Hbase filter 的实现原理是什么?结合实际项目经验,写出几个使用 filter 的场景HBase 为筛选数据提供了一组过滤器,通过这个过滤器可以在 HBase 中的数据的多个维度(行,列,数据版本)上进行对数据的筛选操作,也就是说过滤器最终能够筛选的数据能够细化到具体的一个存储单元格上(由行键,列名,时间戳定位)。 RowFilter、 PrefixFilter。。。hbase的filter是通过scan设置的,所以是基于scan的查询结果进行过滤.过滤器的类型很多,但是可以分为两大类——比较过滤器,专用过滤器过滤器的作用是在服务端判断数据是否满足条件,然后只将满足条件的数据返回给客户端;如在进行订单开发的时候,我们使用rowkeyfilter过滤出某个用户的所有订单
答:宕机分为 HMaster 宕机和 HRegisoner 宕机,如果是 HRegisoner 宕机, HMaster 会将其所管理的 region 重新分布到其他活动的 RegionServer 上,由于数据和日志都持久在 HDFS中,该操作不会导致数据丢失。所以数据的一致性和安全性是有保障的。如果是 HMaster 宕机, HMaster 没有单点问题, HBase 中可以启动多个 HMaster,通过Zookeeper 的 Master Election 机制保证总有一个 Master 运行。即 ZooKeeper 会保证总会有一个 HMaster 在对外提供服务。
导致Hbase挂掉的场景
HMaster
HMaster会出现异常(执行abort())停止的场景如下:
1.zk异常导致的master停止服务是最常见的场景,涉及操作包含但不限于以下:
a)Zk链接超时,超时时间通过zookeeper.session.timeout配置,默认为3分钟, 如果fail.fast.expired.active.master配置的值为false(默认为false),则不会立即abort,而是会尝试恢复zk的过期session;
b)在打开region后,需要从zk中删除opened节点,如果zk有该节点,但是删除失败;
c)在split region过程中,从zk删除split节点时;
d)Master节点改变时;
e)从zk中创建unassigned节点时;
f)在下线disabled的regoin时,从zk中删除disabled的region如果发生zk异常;
g)还有很多操作zk的节点时如果出现异常。
2.在assign时,如果设置region为offlined状态,但是region之前的状态不是closed或者offlined;
3.在assign时,如果无法从.META.表中读取region信息;
4.把新的hbase集群加入到正在运行的hbase集群时,如果zk的/hbase/unassigned节点没有数据;
5.使用线程池批量分配region时,如果出现未被捕获的异常,实现方式如下:
6.在启动master的服务线程时,出现了异常;
7.在hdfs中检查hbase日志路径时,发现了dead的server时,需从hdfs中读出log,如果出现io异常需要检查hdfs文件系统,如果fsOk状态为true,但是通过FSUtils工具类进行检查时出现io异常;
8.在校验并且分配-ROOT-的region时,如果zk异常,或者其它异常(其它异常会重试10次),比如:“-ROOT- is onlined on the dead server”。
HRegionServer
HRegionServer会出现异常停止(执行abort())服务的场景如下:
1.在读写hdfs时如果出现IOException异常,此时会发起hdfs的文件系统检查(checkFileSystem)1.
2.Regionserver的服务线程出现了未捕获异常;
3.在启动HRegionServer时出现异常;
4.在进行HLog回滚时,出现异常;
5.在flush memstore时,如果持久化失败,会重启RS,在重启中把hlog的内容重新加载到memstore;
6.出现zk异常,包括但不限于以下场景:
a)Zk链接超时,超时时间通过zookeeper.session.timeout配置,默认为3分钟,与master不同,如果zk操作不会重试;
b)启动HRegionServer时出现KeeperException异常;
c)在进行split操作时,如果出现异常会进行回滚操作,在回滚过程中需要从zk中删除region的spliting状态,如果删除时出现KeeperException或者回滚的其它操作出现异常;
d)在打开region时,出现了KeeperException异常;
e)在进行hbase集群复制时,很多与zk交互的操作出现KeeperException异常时均会导致abort;
7.在close region时,如果出现异常,比如:不能成功的flush memstore;
8.Flush memstore时,如果HLog发现该region已经在flush则会强制终止JVM,采用的是Runtime.getRuntime().halt(1)方法,该方法不会执行正常退出的关闭钩子,从而不会flush RS的所有region,也不会迁移region,只有等待ZK的session超时后master才会发现该RS不可用,做迁移工作。
总结
Hbase挂掉的可能性有很多,主要由zk或者hdfs的问题导致,因此zk、hdfs的可用对于hbase极其重要,关于zk:
1.zk如果停止了服务则在很多时候会导致master、rs挂掉,hbase集群基本上就失去了服务的能力,因此zk一定要是稳定可靠的,当client已经于rs建立了链接,这时zk挂掉,如果不进行split等小数与zk交互失败会导致触发rs的abort()的操作时rs还是可以提供服务的;
2.如果rs/master进行了长时间的gc或者改动了服务器时间,导致出现zk的session超时会导致rs/master停止服务,目前已经出现了2次因为服务器时间变化导致hbase停止服务的事故;
3.别轻易人为改变zk的hbase节点数据,master/rs在进行很多操作时会比较依赖zk的数据,如果发现不符合预期可能会导致master/rs停止服务,尤其是master。
Master通过ZK知道RS是否可用,一般情况下RS在停止服务时均会正常退出,在正常退出时会从ZK中删除/hbase/rs/$regionserver的节点,Master会监听该节点的被删除,从而较快的(速度取决于所有region关闭时间)对该RS负责的region进行重新分配,如果是强制退出,比如 kill -9或者出现HRegionServer挂掉的第8条时则只有等待ZK的session超时时才会删除RS在ZK的节点(RS在ZK中添加节点时采用的是CreateMode.EPHEMERAL模式,该模式创建的节点会在session关闭时自动删除),那时Master才会进行重新assign。
Kill RS的进程也是正常退出(不能使用kill -9强制退出),RS使用Runtime的addShutdownHook方法注册了jvm关闭钩子,在关闭钩子中会执行RS的退出逻辑,实际上hbase-daemon.sh的停止RS就是采用kill。