1、 HBase的特点是什么?

大:一个表可以有数十亿行,上百万列;
无模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一张表中不同的行可以有截然不同的列;
面向列:面向列(族)的存储和权限控制,列(族)独立检索;
稀疏:空(null)列并不占用存储空间,表可以设计的非常稀疏;
数据多版本:每个单元中的数据可以有多个版本,默认情况下版本号自动分配,是单元格插入时的时间戳;
数据类型单一:Hbase中的数据都是字符串,没有类型。

2、HBase和Hive的区别?

Hive和HBase是两种基于Hadoop的不同技术–Hive是一种类SQL的引擎,并且运行MapReduce任务,Hbase是一种在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的设计原则?

Rowkey长度原则
Rowkey 是一个二进制码流,Rowkey 的长度被很多开发者建议说设计在10~100 个字节,不过建议是越短越好,不要超过16 个字节。

原因如下:
数据的持久化文件HFile 中是按照KeyValue 存储的,如果Rowkey 过长比如100 个字节,1000 万列数据光Rowkey 就要占用100*1000 万=10 亿个字节, 将近1G 数据,这会极大影响HFile 的存储效率;
MemStore 将缓存部分数据到内存,如果Rowkey 字段过长内存的有效利用率会降低,系统将无法缓存更多的数据,这会降低检索效率。 因此Rowkey 的字节长度越短越好。
目前操作系统是都是64 位系统,内存8 字节对齐。控制在16 个字节,8 字节的整数倍利用操作系统的最佳特性。

Rowkey散列原则
如果Rowkey是按时间戳的方式递增,不要将时间放在二进制码的前面,建议将Rowkey的高位作为散列字段,由程序循环生成,低位放时间字段, 这样将提高数据均衡分布在每个Regionserver 实现负载均衡的几率。如果没有散列字段,首字段直接是时间信息将产生所有新数据都在一个 RegionServer 上堆积的 热点现象,这样在做数据检索的时候负载将会集中在个别RegionServer,降低查询效率。

Rowkey唯一原则
必须在设计上保证其唯一性。

5、描述HBase中scan和get的功能以及实现的异同?

HBase的查询实现只提供两种方式:

按指定RowKey 获取唯一一条记录,get方法(org.apache.hadoop.hbase.client.Get) Get 的方法处理分两种 : 设置了ClosestRowBefore 和 没有设置ClosestRowBefore的rowlock。主要是用来保证行的事务性,即每个get 是以一个row 来标记的。一个row中可以有很多family 和column。
按指定的条件获取一批记录,scan方法(org.apache.Hadoop.hbase.client.Scan)实现条件查询功能使用的就是scan 方式。
scan 可以通过setCaching 与setBatch 方法提高速度(以空间换时间);
scan 可以通过setStartRow 与setEndRow 来限定范围([start,end)start 是闭区间,end 是开区间)。范围越小,性能越高。
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行数据的表,每行都包含一些列。使用了一个缓存为

7、请详细描述HBase中一个cell的结构?

HBase中通过row和columns确定的为一个存贮单元称为cell。
Cell:由{row key, column(= + ), version}唯一确定的单元。cell 中的数据是没有类型的,全部是字节码形式存贮。

8、简述HBase中compact用途是什么,什么时候触发,分为哪两种,有什么区别,有哪些相关配置参数?(☆☆☆☆☆)

  在hbase中每当有memstore数据flush到磁盘之后,就形成一个storefile,当storeFile的数量达到一定程度后,就需要将 storefile 文件来 进行 compaction 操作。
Compact 的作用:

  • 合并文件
  • 清除过期,多余版本的数据
  • 提高读写数据的效率

HBase 中实现了两种 compaction 的方式:minor and major. 这两种 compaction 方式的区别是:

  • Minor 操作只用来做部分文件的合并操作以及包括 minVersion=0 并且设置 ttl 的过期版本清理,不做任何删除数据、多版本数据的清理工作。
  • Major 操作是对 Region 下的HStore下的所有StoreFile执行合并操作,最终的结果是整理合并出一个文件。

9、每天百亿数据存入HBase,如何保证数据的存储正确和在规定的时间里全部录入完毕,不残留数据?(☆☆☆☆☆)

需求分析:
百亿数据:证明数据量非常大;
存入HBase:证明是跟HBase的写入数据有关;
保证数据的正确:要设计正确的数据结构保证正确性;
在规定时间内完成:对存入速度是有要求的。

解决思路:
数据量百亿条,什么概念呢?假设一整天60x60x24 = 86400秒都在写入数据,那么每秒的写入条数高达100万条,HBase当然是支持不了每秒百万条数据的, 所以这百亿条数据可能不是通过实时地写入,而是批量地导入。批量导入推荐使用BulkLoad方式(推荐阅读:Spark之读写HBase),性能是普通写入方式几倍以上;
存入HBase:普通写入是用JavaAPI put来实现,批量导入推荐使用BulkLoad;
保证数据的正确:这里需要考虑RowKey的设计、预建分区和列族设计等问题;
在规定时间内完成也就是存入速度不能过慢,并且当然是越快越好,使用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个数,对整个集合平均分割,即是相关的

splitKeysHBaseAdmin.createTable(HTableDescriptor tableDescriptor,byte[][]splitkeys)

可以指定预分区的splitKey, 即是指定region间的rowkey临界值。

12、HRegionServer宕机如何处理?(☆☆☆☆☆)

ZooKeeper会监控HRegionServer的上下线情况,当ZK发现某个HRegionServer宕机之后会通知HMaster进行失效备援;
该HRegionServer会停止对外提供服务,就是它所负责的region暂时停止对外提供服务;
HMaster会将该HRegionServer所负责的region转移到其他HRegionServer上,并且会对HRegionServer上存在memstore中还未持久化到磁盘中的数据进行恢复;
这个恢复的工作是由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一分为二。

写总结:
Client写入 -> 存入MemStore,一直到MemStore满 -> Flush成一个StoreFile,直至增长到一定阈值 -> 触发Compact合并操作 -> 多个StoreFile合并成一个StoreFile,同时进行版本合并和数据删除 -> 当StoreFiles Compact后,逐步形成越来越大的StoreFile -> 单个StoreFile大小超过一定阈值后(默认10G),触发Split操作,把当前Region Split成2个Region,Region会下线,新Split出的2个孩子Region会被HMaster分配到相应的HRegionServer 上,使得原先1个Region的压力得以分流到2个Region上
由此过程可知,HBase只是增加数据,没有更新和删除操作,用户的更新和删除都是逻辑层面的,在物理层面,更新只是追加操作,删除只是标记操作。
用户写操作只需要进入到内存即可立即返回,从而保证I/O高性能。

14、HBase内部机制是什么?

Hbase是一个能适应联机业务的数据库系统

物理存储:hbase的持久化数据是将数据存储在HDFS上。
存储管理:一个表是划分为很多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比没开启要快3、4倍
Hbase对于内存有特别的需求,在硬件允许的情况下配足够多的内存给它
通过修改hbase-env.sh中的 export HBASE_HEAPSIZE=3000 #这里默认为1000m
增大RPC数量:通过修改hbase-site.xml中的hbase.regionserver.handler.count属性,可以适当的放大RPC数量,默认值为10有点小。

18、HBase集群安装注意事项?

HBase需要HDFS的支持,因此安装HBase前确保Hadoop集群安装完成;
HBase需要ZooKeeper集群的支持,因此安装HBase前确保ZooKeeper集群安装完成;
注意HBase与Hadoop的版本兼容性;
注意hbase-env.sh配置文件和hbase-site.xml配置文件的正确配置;
注意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。

21、Hbase的存储结构

Hbase 中的每张表都通过行键(rowkey)按照一定的范围被分割成多个子表(HRegion),默认一个HRegion 超过256M 就要被分割成两个,由HRegionServer管理,管理哪些 HRegion 由 Hmaster 分配。HRegion 存取一个子表时,会创建一个 HRegion 对象,然后对表的每个列族(Column Family)创建一个 store 实例, 每个 store 都会有 0 个或多个 StoreFile 与之对应,每个 StoreFile 都会对应一个HFile,HFile 就是实际的存储文件,一个 HRegion 还拥有一个 MemStore实例。

22、HBase的列簇设计

• 原则:在合理范围内能尽量少的减少列簇就尽量减少列簇,因为列簇是共享region的,每个列簇数据相差太大导致查询效率低下。
• 最优:将所有相关性很强的 key-value 都放在同一个列簇下,这样既能做到查询效率最高,也能保持尽可能少的访问不同的磁盘文件。以用户信息为例,可以将必须的基本信息存放在一个列族,而一些附加的额外信息可以放在另一列族

23、Hbase架构

Hbase主要包含HMaster/HRegionServer/Zookeeper

  • Client:
  1. 访问数据的入口,包含访问hbase的API接口,维护着一些cache来加快对hbase的访问
  • Zookeeper:
  1. zookeeper的选举机制保证任何时候,集群中只有一个master
  2. 实时监控Region Server的状态,将Region server的上线和下线信息实时通知给Master
  3. 存储Hbase的schema
  4. 存贮所有Region的寻址入口
  • Master:
  1. 为Region server分配region
  2. 负责region server的负载均衡
  3. 发现失效的region server并重新分配其上的region
  4. 处理schema(元数据)更新请求
    说明:Hmaster短时间下线,hbase集群依然可用,长时间不行。
  • Region server:
  1. Region server维护Master分配给它的region,处理对这些region的IO请求
  2. Region server负责切分在运行过程中变得过大的region

24、 讲一下hbase的存储结构,这样的存储结构有什么优缺点

Hbase的优点及应用场景:

半结构化或非结构化数据: 对于数据结构字段不够确定或杂乱无章非常难按一个概念去进行抽取的数据适合用HBase,因为HBase支持动态添加列。

记录很稀疏:RDBMS的行有多少列是固定的。为null的列浪费了存储空间。HBase为null的Column不会被存储,这样既节省了空间又提高了读性能。

多版本号数据:依据Row key和Column key定位到的Value能够有随意数量的版本号值,因此对于须要存储变动历史记录的数据,用HBase是很方便的。比方某个用户的Address变更,用户的Address变更记录也许也是具有研究意义的。

仅要求最终一致性:对于数据存储事务的要求不像金融行业和财务系统这么高,只要保证最终一致性就行。(比如HBase+elasticsearch时,可能出现数据不一致)

高可用和海量数据以及很大的瞬间写入量:WAL解决高可用,支持PB级数据,put性能高 适用于插入比查询操作更频繁的情况。比如,对于历史记录表和日志文件。(HBase的写操作更加高效)

业务场景简单:不需要太多的关系型数据库特性,列入交叉列,交叉表,事务,连接等。

Hbase的缺点:
单一RowKey固有的局限性决定了它不可能有效地支持多条件查询
不适合于大范围扫描查询
不直接支持 SQL 的语句查询

25、flush机制

全局的memstore的flush机制默认为堆总大小(多个memstore 多个region)的40%,超过该大小会触发flush到磁盘的操作,会阻塞客户端读写,flush将所有的memstore全部flush。

单个的memstore默认为数据达到128M或1h或者数据为堆大小 0.95倍将会flush. memstore默认将会先提前flush 5M.(先flush一小部分,等后面数据达到阈值在flush后 面的数据) 这样会比一次flush效率高

hbase不建议配置过多列族:过多的列族会消耗大量的内存,同时数据在flush时消耗磁盘IO. 一个regionserver读写操作可用堆内存的80%,读取占用40% ,写入占用40%。这两个参数直接 影响hbase读写性能。

25、HMaster宕机的时候,哪些操作还能正常工作

对表内数据的增删查改是可以正常进行的,因为hbase client 访问数据只需要通过 zookeeper 来找到 rowkey 的具体 region 位置即可. 但是对于创建表/删除表等的操作就无法进行了,因为这时候是需要HMaster介入, 并且region的拆分,合并,迁移等操作也都无法进行了

26、讲一下hbase的写数据的流程

Client先访问zookeeper,从.META.表获取相应region信息,然后从meta表获取相应region信息

根据namespace、表名和rowkey根据meta表的数据找到写入数据对应的region信息

找到对应的regionserver 把数据先写到WAL中,即HLog,然后写到MemStore上

MemStore达到设置的阈值后则把数据刷成一个磁盘上的StoreFile文件。

当多个StoreFile文件达到一定的大小后(这个可以称之为小合并,合并数据可以进行设置,必须大于等于2,小于10——hbase.hstore.compaction.max和hbase.hstore.compactionThreshold,默认为10和3),会触发Compact合并操作,合并为一个StoreFile,(这里同时进行版本的合并和数据删除。)

当Storefile大小超过一定阈值后,会把当前的Region分割为两个(Split)【可称之为大合并,该阈值通过hbase.hregion.max.filesize设置,默认为10G】,并由Hmaster分配到相应的HRegionServer,实现负载均衡

27、讲一下hbase读数据的流程

meta表是hbase系统自带的一个表。里面存储了hbase用户表的元信息。

元信息为meta表内记录一行数据是用户表一个region的start key 到endkey的范围。

meta表存储在regionserver里。 具体存储在哪个regionserver里?zookeeper知道。

过程:

1.客户端到zookeeper询问meta表在哪

2.客户端到meta所在的节点(regionserver)读取meta表的数据

3.客户端找到region 获取region和regionserver的对应关系,直接到regionserver读取region数据

28、直接将时间戳作为行健,在写入单个 region 时候会发生热点问题,为什么呢?

region 中的 rowkey 是有序存储,若时间比较集中。就会存储到一个 region 中,这样一个 region 的数据变多,其它的 region 数据很少,加载数据就会很慢,直到 region 分裂,此问题才会得到缓解。

29、解释下 hbase 实时查询的原理

实时查询,可以认为是从内存中查询,一般响应时间在 1 秒内。HBase 的机制是数据先写入到内存中,当数据量达到一定的量(如 128M),再写入磁盘中, 在内存中,是不进行数据的更新或合并操作的,只增加数据,这使得用户的写操作只要进入内存中就可以立即返回,保证了 HBase I/O 的高性能。

30、Hbase的存储结构

Hbase 中的每张表都通过行键(rowkey)按照一定的范围被分割成多个子表(HRegion),默认一个HRegion 超过256M 就要被分割成两个,由HRegionServer管理,管理哪些 HRegion 由 Hmaster 分配。HRegion 存取一个子表时,会创建一个 HRegion 对象,然后对表的每个列族(Column Family)创建一个 store 实例, 每个 store 都会有 0 个或多个 StoreFile 与之对应,每个 StoreFile 都会对应一个HFile,HFile 就是实际的存储文件,一个 HRegion 还拥有一个 MemStore实例。

31、描述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 方法添加过滤器,这也是分页、多条件查询的基础。
复制代码

#32、详细描述 HBase 中一个 cell 的结构?
HBase 中通过 row 和 columns 确定的为一个存贮单元称为 cell。Cell:由{row key, column(= + ), version}是唯一确定的单元cell 中的数据是没有类型的,全部是字节码形式存贮

33、简述 Hbase filter 的实现原理是什么?结合实际项目经验,写出几个使用filter 的场景。

HBase 为筛选数据提供了一组过滤器,通过这个过滤器可以在 HBase 中的数据的多个维度(行,列,数据版本)上进行对数据的筛选操作,也就是说过滤器最终能够筛选的数据能够细化到具体的一个存储单元格上(由行键, 列名,时间戳定位)。
RowFilter、PrefixFilter。hbase 的 filter 是通过 scan 设置的,所以是基于 scan 的查询结果进行过滤. 过滤器的类型很多,但是可以分为两大类——比较过滤器,专用过滤器。过滤器的作用是在服务端判断数据是否满足条件,然后只将满足条件的数据返回给客户端;如在进行订单开发的时候,我们使用 rowkeyfilter 过滤出某个用户的所有订单。

34、Hbase 内部是什么机制?

Hbase 是一个能适应联机业务的数据库系统物理存储:hbase 的持久化数据是将数据存储在 HDFS 上。
存储管理:一个表是划分为很多 region 的,这些 region 分布式地存放在很多 regionserver上 Region 内部还可以划分为 store,store 内部有 memstore 和 storefile。
版本管理:hbase 中的数据更新本质上是不断追加新的版本,通过 compact 操作来做版本间的文件合并 Region 的 split。
集群管理:ZooKeeper + HMaster + HRegionServer。
在 HBase 中无论是增加新行还是修改已有的行,其内部流程都是相同的。HBase 接到命令后存下变化信息,或者写入失败抛出异常。默认情况下,执行写入时会写到两个地方:预写式日志(write-ahead log,也称 HLog)和 MemStore。HBase 的默认方式是把写入动作记录在这两个地方,以保证数据持久化。只有当这两个地方的变化信息都写入并确认后,才认为写动作完成。
MemStore 是内存里的写入缓冲区,HBase 中数据在永久写入硬盘之前在这里累积。当MemStore 填满后,其中的数据会刷写到硬盘,生成一个HFile。HFile 是HBase 使用的底层存储格式。HFile 对应于列族,一个列族可以有多个 HFile,但一个 HFile 不能存储多个列族的数据。在集群的每个节点上,每个列族有一个MemStore。大型分布式系统中硬件故障很常见,HBase 也不例外。
设想一下,如果MemStore 还没有刷写,服务器就崩溃了,内存中没有写入硬盘的数据就会丢失。HBase 的应对办法是在写动作完成之前先写入 WAL。HBase 集群中每台服务器维护一个 WAL 来记录发生的变化。WAL 是底层文件系统上的一个文件。直到WAL 新记录成功写入后,写动作才被认为成功完成。这可以保证 HBase 和支撑它的文件系统满足持久性。
大多数情况下,HBase 使用Hadoop分布式文件系统(HDFS)来作为底层文件系统。如果 HBase 服务器宕机,没有从 MemStore 里刷写到 HFile 的数据将可以通过回放 WAL 来恢复。你不需要手工执行。Hbase 的内部机制中有恢复流程部分来处理。每台 HBase 服务器有一个 WAL,这台服务器上的所有表(和它们的列族)共享这个 WAL。你可能想到,写入时跳过 WAL 应该会提升写性能。但我们不建议禁用 WAL, 除非你愿意在出问题时丢失数据。如果你想测试一下,如下代码可以禁用 WAL: 注意:不写入 WAL 会在 RegionServer 故障时增加丢失数据的风险。关闭 WAL, 出现故障时 HBase 可能无法恢复数据,没有刷写到硬盘的所有写入数据都会丢失。

35、HBase 宕机如何处理?

宕机分为 HMaster 宕机和 HRegisoner 宕机.
如果是 HRegisoner 宕机,HMaster 会将其所管理的 region 重新分布到其他活动的 RegionServer 上,由于数据和日志都持久在 HDFS 中,该操作不会导致数据丢失,所以数据的一致性和安全性是有保障的。
如果是 HMaster 宕机, HMaster 没有单点问题, HBase 中可以启动多个HMaster,通过 Zookeeper 的 Master Election 机制保证总有一个 Master 运行。即ZooKeeper 会保证总会有一个 HMaster 在对外提供服务。

37、HRegionServer宕机如何处理?

• ZooKeeper 会监控 HRegionServer 的上下线情况,当 ZK 发现某个 HRegionServer 宕机之后会通知 HMaster 进行失效备援
• HRegionServer 会停止对外提供服务,就是它所负责的 region 暂时停止对外提供服务
• HMaster 会将该 HRegionServer 所负责的 region 转移到其他 HRegionServer 上,并且会对 HRegionServer 上存在 memstore 中还未持久化到磁盘中的数据进行恢复
• 这个恢复的工作是由 WAL重播 来完成,这个过程如下:
• wal实际上就是一个文件,存在/hbase/WAL/对应RegionServer路径下
• 宕机发生时,读取该RegionServer所对应的路径下的wal文件,然后根据不同的region切分成不同的临时文件recover.edits
• 当region被分配到新的RegionServer中,RegionServer读取region时会进行是否存在recover.edits,如果有则进行恢复

38、hbase写数据 和 读数据过程

获取region存储位置信息
写数据和读数据一般都会获取hbase的region的位置信息。大概步骤为:

  1. 从zookeeper中获取.ROOT.表的位置信息,在zookeeper的存储位置为/hbase/root-region-server;
  2. 根据.ROOT.表中信息,获取.META.表的位置信息;
  3. META.表中存储的数据为每一个region存储位置;
    向hbase表中插入数据
    hbase中缓存分为两层:Memstore 和 BlockCache:
  4. 首先写入到 WAL文件 中,目的是为了数据不丢失;
  5. 再把数据插入到 Memstore缓存中,当 Memstore达到设置大小阈值时,会进行flush进程;
  6. flush过程中,需要获取每一个region存储的位置。
    从hbase中读取数据
    BlockCache 主要提供给读使用。读请求先到 Memtore中查数据,查不到就到 BlockCache 中查,再查不到就会到磁盘上读,并把读的结果放入 BlockCache 。
    BlockCache 采用的算法为 LRU(最近最少使用算法),因此当 BlockCache 达到上限后,会启动淘汰机制,淘汰掉最老的一批数据。
    一个 RegionServer 上有一个 BlockCache 和N个 Memstore,它们的大小之和不能大于等于 heapsize * 0.8,否则 hbase 不能启动。默认 BlockCache 为 0.2,而 Memstore 为 0.4。对于注重读响应时间的系统,应该将 BlockCache 设大些,比如设置BlockCache =0.4,Memstore=0.39。这会加大缓存命中率

39、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中也存在频繁开启关闭带来的问题。
1、关闭Compaction,在闲时进行手动Compaction
因为HBase中存在Minor Compaction和Major Compaction,也就是对HFile进行合并,所谓合并就是I/O读写,大量的HFile进行肯定会带来I/O开销,甚至是I/O风暴,所以为了避免这种不受控制的意外发生,建议关闭自动Compaction,在闲时进行compaction
2、批量数据写入时采用BulkLoad
如果通过HBase-Shell或者JavaAPI的put来实现大量数据的写入,那么性能差是肯定并且还可能带来一些意想不到的问题,所以当需要写入大量离线数据时建议使用BulkLoad
3)减少数据量
虽然我们是在进行大数据开发,但是如果可以通过某些方式在保证数据准确性同时减少数据量,何乐而不为呢?
1、开启过滤,提高查询速度
开启BloomFilter,BloomFilter是列族级别的过滤,在生成一个StoreFile同时会生成一个MetaBlock,用于查询时过滤数据
2、使用压缩:一般推荐使用Snappy和LZO压缩
4)合理设计
在一张HBase表格中RowKey和ColumnFamily的设计是非常重要,好的设计能够提高性能和保证数据的准确性
1、RowKey设计:应该具备以下几个属性
• 散列性:散列性能够保证相同相似的rowkey聚合,相异的rowkey分散,有利于查询
• 简短性:rowkey作为key的一部分存储在HFile中,如果为了可读性将rowKey设计得过长,那么将会增加存储压力
• 唯一性:rowKey必须具备明显的区别性
• 业务性:举些例子
假如我的查询条件比较多,而且不是针对列的条件,那么rowKey的设计就应该支持多条件查询
如果我的查询要求是最近插入的数据优先,那么rowKey则可以采用叫上Long.Max-时间戳的方式,这样rowKey就是递减排列
2、列族的设计
列族的设计需要看应用场景
多列族设计的优劣
优势:
HBase中数据时按列进行存储的,那么查询某一列族的某一列时就不需要全盘扫描,只需要扫描某一列族,减少了读I/O;
其实多列族设计对减少的作用不是很明显,适用于读多写少的场景。
劣势:
降低了写的I/O性能。原因如下:数据写到store以后是先缓存在memstore中,同一个region中存在多个列族则存在多个store,每个store都一个memstore,当其实memstore进行flush时,属于同一个region 的 store 中的 memstore 都会进行 flush,增加I/O开销。

40、为什么不建议在 HBase 中使用过多的列族

在 Hbase 的表中,每个列族对应 Region 中的一个Store,Region的大小达到阈值时会分裂,因此如果表中有多个列族,则可能出现以下现象:

  1. 一个Region中有多个Store,如果每个CF的数据量分布不均匀时,比如CF1为100万,CF2为1万,则Region分裂时导致CF2在每个Region中的数据量太少,查询CF2时会横跨多个Region导致效率降低。
  2. 如果每个CF的数据分布均匀,比如CF1有50万,CF2有50万,CF3有50万,则Region分裂时导致每个CF在Region的数据量偏少,查询某个CF时会导致横跨多个Region的概率增大。
  3. 多个CF代表有多个Store,也就是说有多个MemStore(2MB),也就导致内存的消耗量增大,使用效率下降。
  4. Region 中的 缓存刷新 和 压缩 是基本操作,即一个CF出现缓存刷新或压缩操作,其它CF也会同时做一样的操作,当列族太多时就会导致IO频繁的问题。

41、Region 如何预建分区?

预分区的目的主要是在创建表的时候指定分区数,提前规划表有多个分区,以及每个分区的区间范围,这样在存储的时候 rowkey 按照分区的区间存储,可以避免 region 热点问题。
通常有两种方案:
方案 1:shell 方法
create ‘tb_splits’, {NAME => ‘cf’,VERSIONS=> 3},{SPLITS => [‘10’,’20’,’30’]}
复制代码
方案 2: JAVA 程序控制
• 取样,先随机生成一定数量的 rowkey,将取样数据按升序排序放到一个集合里;
• 根据预分区的 region 个数,对整个集合平均分割,即是相关的 splitKeys;
• HBaseAdmin.createTable(HTableDescriptor tableDescriptor,byte[][]splitkeys)可以指定预分区的 splitKey,即是指定 region 间的 rowkey 临界值。

42、如何提高 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 有点小

43、直接将时间戳作为行健,在写入单个 region 时候会发生热点问题,为什么呢?(☆☆☆☆☆)

region 中的 rowkey 是有序存储,若时间比较集中。就会存储到一个 region 中,这样一个 region 的数据变多,其它的 region 数据很少,加载数据就会很慢,直到 region 分裂,此问题才会得到缓解。

44、请描述如何解决 HBase 中 region 太小和 region 太大带来的冲突?

Region 过大会发生多次compaction,将数据读一遍并重写一遍到 hdfs 上,占用io,region过小会造成多次 split,region 会下线,影响访问服务,最佳的解决方法是调整 hbase.hregion.max.filesize 为 256m。

45、知道spark怎么读hbase吗?

46、做过hbase的二级索引吗?

47、Hbase的PUT的一个过程

48、HBase 的特点是什么?

1)大:一个表可以有数十亿行,上百万列;
2)无模式:每行都有一个可排序的主键和任意多的列,列可以根据需要动态的增加,同一张表中不同的行可以有截然不同的列; 3)面向列:面向列(族)的存储和权限控制,列(族)独立检索;
4)稀疏:空(null)列并不占用存储空间,表可以设计的非常稀疏;
5)数据多版本:每个单元中的数据可以有多个版本,默认情况下版本号自动分配,是单元格插入时的时间戳;
6)数据类型单一:Hbase 中的数据都是字符串,没有类型

49、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)

50、Hbase合并怎么操作?合并的大小是多少?

compact的作用
flush操作会将memstore的数据落地为一个个StoreFile(HFile),那么随着时间的增长在HDFS上面就会有很多的HFile文件,这样对读操作会产生比较大的影响(读操作会对HFile进行归并查询),并且对DataNode的压力也会比较大。为了降低对读操作的影响,可以对这些HFile进行compact操作,但是compact操作会产生大量的IO,所以可以看出compact的本质就是用IO操作换取后续读性能的提升。
minor compaction (小合并)
选取部分小的、相邻的HFile文件,形成一个较大的HFile文件。
小合并并不会进行过期数据的清除工作。
major compaction(大合并)
合并所有的HFile文件为一个大的HFile文件
大合并会清理TTL过期数据、超出设定版本号的数据以及delete标记的数据
一般是手动进行,将参数hbase.hregion.majorcompaction的值设为0,表示禁用major compaction。其默认值为7天,允许上下浮动hbase.hregion.majorcompaction * hbase.hregion.majorcompaction.jitter的值,后者默认是0.5。即[7 - 70.5, 7 + 70.5]
触发条件
一、memstore flush之后
memstore flush之后,都需要对当前Store的文件数量进行判断,一旦大于hbase.hstore.compactionThreshold(现在的版本中这个参数的名字为hbase.hstore.compaction.min)的值(默认3),触发合并操作。该参数一般需要调大。一次minor cmpaction最多合并hbase.hstore.compaction.max个文件(默认值10)。
二、定期compaction
后台线程CompactionChecker定期触发检查是否需要执行compaction,检查周期为:hbase.server.thread.wakefrequency * hbase.server.compactchecker.interval.multiplier,默认值为10s和1000
当文件大小小于参数hbase.hstore.compaction.min.size指定的值的时候(默认128M,单位字节),该文件会被加入到合并队列中,当合并队列中的StoreFile数量超过参数hbase.hstore.compaction.min(更早的版本中这个的参数的名字为hbase.hstore.compactionThreshold)的值(默认3)时会触发compaction操作。一次minor cmpaction最多合并hbase.hstore.compaction.max个文件(默认值10)。
如果一个文件的大小超过hbase.hstore.compaction.max.size的值(默认值LONG.MAX_VALUE),则会被compaction操作排除。
通过hbase.hstore.compaction.ratio参数(默认值1.2)确定大小超过hbase.hstore.compaction.min.size的文件是否需要进行compaction。如果一个文件的大小小于它后面(按文件产生的先后顺序,总是从新产生的文件开始选择即“老文件”)的hbase.hstore.compaction.max个StoreFile的大小之和乘以hbase.hstore.compaction.ratio,则该StoreFile文件也会加入到合并队列中。
三、手动触发major compaction
使用命令major_compact

51、简述hbase的过滤器?

单个列过滤器
列过滤器
列族过滤器
前缀过滤器
键值过滤器

52、Hbase的查询效率如何进行提升?

1、使用bloomfilter和mapfile_index_interval
2、 hbase对于内存有特别的嗜好,在硬件允许的情况下配足够多的内存给它。
通过修改hbase-env.sh中的
export HBASE_HEAPSIZE=3000 #这里默认为1000m
3、修改java虚拟机属性
(1)、在环境允许的情况下换64位的
(2)、替换掉默认的垃圾回收器,因为默认的垃圾回收器在多线程环境下会有更多的wait 等待
export HBASE_OPTS=”-server -XX:NewSize=6m -XX:MaxNewSize=6m -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode”
4、增大RPC数量
通过修改hbase-site.xml中的
hbase.region.handler.count属性,可以适当的放大。默认值为10有点小
5、做程序开发是注意的地方
(1)、需要判断所求的数据行是否存在时,尽量不要用HTable.exists(final byte [] row) 而用 HTable.exists(final byte [] row, final byte[] column)等带列族的方法替代。
(2)、不要使用HTable.get(final byte [] row, final byte [] column) == null来判断所求的数据 存在,而是用HTable.exists(final byte [] row, final byte[] column)替代
(3)、HTable.close()方法少用.因为我遇到过一些很令人费解的错误
6、记住HBase是基于列模式的存储,如果一个列族能搞定就不要把它分开成两个,的那套 在这里很不实用.分成多个列来存储会浪费更多的空间,除非你认为现在的硬盘和白菜一个 价。
7、如果数据量没有达到TB级别或者没有上亿条记录,很难发挥HBase的优势,建议换关系 数据库或别的存储技术。

53、简述HMaster的作用

HBase中的每张表都通过键按照一定的范围被分割成多个子表(HRegion),默认一个 HRegion超过256M就要被分割成两个,这个过程由HRegionServer管理,而HRegion的分 配由HMaster管理
1.为HRegionServer分配HRegion
2.负责HRegionServer的负载均衡
3.发现失效的HRegionServer并重新分配
4.HDFS上的垃圾文件回收
5.处理Schema更新请求

54、简述HRegionServer的作用

1.维护HMaster分配给它的HRegion,处理对这些HRegion的IO请求
2.负责切分正在运行过程中变得过大的HRegion可以看到,Client访问HBase上的数据并不 需要HMaster参与,寻址访问ZooKeeper和HRegionServer,数据读写访问HRegionServer, HMaster仅仅维护Table和Region的元数据信息,Table的元数据信息保存在ZooKeeper 上,负载很低。HRegionServer存取一个子表时,会创建一个HRegion对象,然后对表的 每个列簇创建一个Store对象,每个Store都会有一个MemStore和0或多个StoreFile与 之对应,每个StoreFile都会对应一个HFile,HFile就是实际的存储文件。因此,一个HRegion 有多少列簇就有多少个Store。
3 一个HRegionServer会有多个HRegion和一个HLog。

55、简述HRegion的作用

Table在行的方向上分割为多个HRegion,HRegion是HBase中分布式存储和负载均衡 的最小单元,即不同的HRegion可以分别在不同的HRegionServer上,但同一个HRegion 是不会拆分到多个HRegionServer上的。HRegion按大小分割,每个表一般只有一个 HRegion,随着数据不断插入表,HRegion不断增大,当HRegion的某个列簇达到一个 阀值(默认256M)时就会分成两个新的HRegion。
1、<表名,StartRowKey, 创建时间>
2、由目录表(-ROOT-和.META.)记录该Region的EndRowKey
HRegion定位:HRegion被分配给哪个HRegionServer是完全动态的,所以需要机制 来定位HRegion具体在哪个HRegionServer,HBase使用三层结构来定位HRegion:

1、通过zk里的文件/hbase/rs得到-ROOT-表的位置。-ROOT-表只有一个region。

2、通过-ROOT-表查找.META.表的第一个表中相应的HRegion位置。其实-ROOT-表 是.META.表的第一个region;
.META.表中的每一个Region在-ROOT-表中都是一行记录。
3、通过.META.表找到所要的用户表HRegion的位置。用户表的每个HRegion在.META. 表中都是一行记录。
-ROOT-表永远不会被分隔为多个HRegion,保证了最多需要三次跳转,就能定位到任意 的region。Client会将查询的位置信息保存缓存起来,缓存不会主动失效,因此如果Client 上的缓存全部失效,则需要进行6次网络来回,才能定位到正确的HRegion,其中三次 用来发现缓存失效,另外三次用来获取位置信息。

56、简述你知道的Hbase优化?

hbase的优化
一、写入数据方面
1.Auto Flash
通过调用HTable.setAutoFlushTo(false)方法可以将HTable写客户端自动flush关 闭,这样可以批量写入数据到HBase,而不是有一条put就执行一次更新,只 有当put填满客户端写缓存的时候,才会向HBase服务端发起写请求。默认情 况下auto flush是开启的。
2.Write Buffer
通过调用HTable.setWriteBufferSize(writeBufferSize)方法可以设置HTable客户端 的写buffer大小,如果新设置的buffer小于当前写buffer中的数据时,buffer 将会被flush到服务端。其中,writeBufferSize的单位是byte字节数,可以根基 实际写入数据量的多少来设置该值。
3.WAL Flag
在HBase中,客户端向集群中的RegionServer提交数据时(Put/Delete操作), 首先会写到WAL(Write Ahead Log)日志,即HLog,一个RegionServer上的所 有Region共享一个HLog,只有当WAL日志写成功后,再接着写MemStore, 然后客户端被通知提交数据成功,如果写WAL日志失败,客户端被告知提交失 败,这样做的好处是可以做到RegionServer宕机后的数据恢复。
对于不太重要的数据,可以在Put/Delete操作时,通过调用Put.setWriteToWAL(false)或Delete.setWriteToWAL(false)函数,放弃写WAL日志,以提高数据写入的性能。
注:如果关闭WAL日志,一旦RegionServer宕机,Put/Delete的数据将会无法根 据WAL日志进行恢复。
4.Compression 压缩
数据量大,边压边写也会提升性能的,毕竟IO是大数据的最严重的瓶颈,哪 怕使用了SSD也是一样。众多的压缩方式中,推荐使用SNAPPY。从压缩率和 压缩速度来看,性价比最高。

      HColumnDescriptor hcd = new HColumnDescriptor(familyName);   
      hcd.setCompressionType(Algorithm.SNAPPY);  

5.批量写
通过调用HTable.put(Put)方法可以将一个指定的row key记录写入HBase,同样 HBase提供了另一个方法:通过调用

HTable.put(List<Put>)

方法可以将指定的row key列表,批量写入多行记录,这样做的好处是批量执行,只需要一次网络I/O 开销,这对于对数据实时性要求高,网络传输RTT高的情景下可能带来明显的 性能提升。
6.多线程并发写
在客户端开启多个 HTable 写线程,每个写线程负责一个 HTable 对象的 flush 操作,这样结合定时 flush 和写 buffer(writeBufferSize),可以既保证在数据 量小的时候,数据可以在较短时间内被 flush(如1秒内),同时又保证在数 据量大的时候,写 buffer 一满就及时进行 flush。
二、读数据方面
1.批量读
通过调用 HTable.get(Get) 方法可以根据一个指定的 row key 获取一行记录, 同样 HBase 提供了另一个方法:通过调用 HTable.get(List) 方法可以根据一个 指定的 row key 列表,批量获取多行记录,这样做的好处是批量执行,只需要 一次网络 I/O 开销,这对于对数据实时性要求高而且网络传输 RTT 高的情景 下可能带来明显的性能提升。
2.缓存查询结果
对于频繁查询 HBase 的应用场景,可以考虑在应用程序中做缓存,当有新的 查询请求时,首先在缓存中查找,如果存在则直接返回,不再查询 HBase;否 则对 HBase 发起读请求查询,然后在应用程序中将查询结果缓存起来。至于 缓存的替换策略,可以考虑 LRU 等常用的策略。
三、数据及集群管理
1.预分区
默认情况下,在创建HBase表的时候会自动创建一个Region分区,当导入数据 的时候,所有的HBase客户端都向Region写数据,知道这个Region足够大才 进行切分,一种可以加快批量写入速度的方法是通过预先创建一些空的 Regions,这样当数据写入HBase的时候,会按照Region分区情况,在进群内 做数据的负载均衡。
2.Rowkey优化
rowkey是按照字典存储,因此设置rowkey时,要充分利用排序特点,将经常 一起读取的数据存储到一块,将最近可能会被访问的数据放到一块。
rowkey若是递增生成的,建议不要使用正序直接写入,可以使用字符串反转 方式写入,使得rowkey大致均衡分布,这样设计的好处是能将RegionServer 的负载均衡,否则容易产生所有新数据都在集中在一个RegionServer上堆积的 现象,这一点还可以结合table的与分区设计。
减少Column Family数量
不要在一张表中定义太多的column family。目前HBase并不能很好的处理超过 2-3个column family的表,因为某个column family在flush的时候,它临近的c olumn family也会因关联效应被触发flush,最终导致系统产生更过的I/O;
3.设置最大版本数
创建表的时候,可以通过 HColumnDescriptor.setMaxVersions(int maxVersions) 设置表中数据的最大版本,如果只需要保存最新版本的数据,那么可以设置 setMaxVersions(1)。
4.缓存策略(setCaching)
创建表的时候,可以通过HColumnDEscriptor.setInMemory(true)将表放到 RegionServer的缓存中,保证在读取的时候被cache命中。
5.设置存储生命期
创建表的时候,可以通过HColumnDescriptor.setTimeToLive(int timeToLive)设置 表中数据的存储生命周期,过期数据将自动被删除
6.磁盘配置
每台RegionServer管理10-1000个Regions。每个Region在1-2G,则每台server 最少要10G,最大要1000*2G=2TB,考虑3备份,需要6TB。方案1是3块2TB 磁盘,2是12块500G磁盘,带宽足够时,后者能提供更大的吞吐率,更细力 度的冗余备份,更快速的单盘故障恢复。
分配何时的内存给RegionServer
在不影响其他服务的情况下,越大越好。在HBase的conf目录下的hbase-env.sh 的最后添加export HBASE_REGIONSERVER_OPTS=”- Xmx16000m $HBASE_REGIONSERVER_OPTS”
其中16000m为分配给REgionServer的内存大小。
7.写数据的备份数
备份数与读性能是成正比,与写性能成反比,且备份数影响高可用性。有两 种配置方式,一种是将hdfs-site.xml拷贝到hbase的conf目录下,然后在其 中添加或修改配置项dfs.replication的值为要设置的备份数,这种修改所有的 HBase用户都生效。另一种方式是改写HBase代码,让HBase支持针对列族设 置备份数,在创建表时,设置列族备份数,默认为3,此种备份数支队设置的 列族生效。
客户端一次从服务器拉取的数量
通过配置一次拉取较大的数据量可以减少客户端获取数据的时间,但是他会占 用客户端的内存,有三个地方可以进行配置
在HBase的conf配置文件中进行配置hbase.client.scanner.caching;
通过调用HTble.setScannerCaching(int scannerCaching)进行配置;
通过调用Sacn.setCaching(int caching)进行配置,三者的优先级越来越高。
8.客户端拉取的时候指定列族
scan是指定需要column family,可以减少网络传输数据量,否则默认scan操作 会返回整行所有column family的数据
拉取完数据之后关闭ResultScanner
通过 scan 取完数据后,记得要关闭 ResultScanner,否则 RegionServer 可能 会出现问题(对应的 Server 资源无法释放)。
9.RegionServer的请求处理IO线程数
较少的IO线程适用于处理单次请求内存消耗较高的Big Put场景(大容量单词 Put或设置了较大cache的scan,均数据Big Put)或RegionServer的内存比较 紧张的场景。
较多的IO线程,适用于单次请求内存消耗低,TPS要求(每次事务处理量)非 常高的场景。这只该值的时候,以监控内存为主要参考
在hbase-site.xml配置文件中配置项为hbase.regionserver.handle.count
10.Region大小设置
配置项hbase.hregion.max.filesize,所属配置文件为hbase-site.xml,默认大小是 256m。
在当前RegionServer上单个Region的最大存储空间,单个Region超过该 值时,这个Region会被自动split成更小的Region。小Region对split和compaction 友好,因为拆分Region或compact小Region里的StoreFile速度非常快,内存 占用低。缺点是split和compaction会很频繁,特别是数量较多的小Region不 同的split,compaction,会导致集群响应时间波动很大,Region数量太多不仅 给管理上带来麻烦,设置会引起一些HBase个bug。一般 512M 以下的都算小 Region。大 Region 则不太适合经常 split 和 compaction,因为做一次 compact 和 split 会产生较长时间的停顿,对应用的读写性能冲击非常大。
此外,大 Region 意味着较大的 StoreFile,compaction 时对内存也是一个 挑战。如果你的应用场景中,某个时间点的访问量较低,那么在此时做 compact 和split,既能顺利完成 split 和 compaction,又能保证绝大多数时间平稳的读 写性能。compaction 是无法避免的,split 可以从自动调整为手动。只要通过 将这个参数值调大到某个很难达到的值,比如 100G,就可以间接禁用自动 split(RegionServer 不会对未到达 100G 的 Region 做 split)。再配合 RegionSplitter 这个工具,在需要 split 时,手动 split。手动 split 在灵活性和 稳定性上比起自动 split 要高很多,而且管理成本增加不多,比较推荐 online 实时系统使用。内存方面,小 Region 在设置 memstore 的大小值上比较灵活, 大 Region 则过大过小都不行,过大会导致 flush 时 app 的 IO wait 增高,过 小则因 StoreFile 过多影响读性能。

57、如果让你管理hbase你有什么看法

运维任务
regionserver添加/删除节点 master备份
1 添加新节点
复制hbase目录并进行配置文件修改(regionserver增加新节点)并保持配置文件在 全集群一致,在新节点上启动相关进程如hbase-daemon.sh start regionserver命令
2 删除节点
停止相关进程(例如regionserver hbase-daemon.sh stop regionserver),下线节点需 注意
(2-1) 如果负载均衡进程正在执行,请先停止,因为其可能会和master转移region 产生竞争
(2-2) 如果该节点上的数据量很大,移动region的过程可能很漫长
3 master备份
(3-1) 修改配置文件conf/backup-master文件
(3-2) 启动相关进程 hbase-daemon.sh start master
数据迁移
(1) 导入导出
HBase的jar包中包含了两个以MapReduce作业形式来导入导出数据的工具,如 hadoop jar ${hbase.jar} export ${tablename} ${outputdir
该工具其余的参数可以做到增量导出、控制导出的数据版本等功能.
32.说一下Hbase行健列族的概念,物理模型,表的设计原则?
1.行健:是hbase表自带的,每个行健对应一条数据。
2.列族:是创建表时指定的,为列的集合,每个列族作为一个文件单独存储,存储的数据都是字节数组,其中的数据可以有很多,通过时间戳来区分。
3.物理模型:整个hbase表会拆分为多个region,每个region记录着行健的起始点保存在不同的节点上,查询时就是对各个节点的并行查询,当region很大时使用.META表存储各个region的起始点,-ROOT又可以存储.META的起始点。
4.rowkey的设计原则:各个列簇数据平衡,长度原则、相邻原则,创建表的时候设置表放入regionserver缓存中,避免自动增长和时间,使用字节数组代替string,最大长度64kb,最好16字节以内,按天分表,两个字节散列,四个字节存储时分毫秒。
5.列族的设计原则:尽可能少(按照列族进行存储,按照region进行读取,不必要的io操作),经常和不经常使用的两类数据放入不同列族中,列族名字尽可能短。
33.为什么用HBase存储?
HBase(Hadoop DataBase)是一个高可靠性、高性能、可伸缩、面向列的分布式数据库(分布式存储系统)。
HBase与Hadoop的关系非常紧密,Hadoop的HDFS提供了高可靠的底层存储支持,Hadoop MapReduce为HBase提供了高性能的计算能力,Zookeeper为HBase提供了稳定性及Failover机制的保障。同时其他周边产品诸如Hive可以与HBase相结合,使得对HBase中的数据进行数据统计变得简单,Sqoop为HBase提供了方便的RDBMS数据导入功能,使传统数据库的数据向HBase中迁移变得容易,Spark等高性能的分布式内存计算引擎也可以帮助我们更加快速的对HBase中的数据进行处理分析。

58、HBase的读写流程?

.元数据存储
HBase中有一个系统表hbase:meta,存储元数据信息,可以在HBase Web UI查看到相关信息。
该表记录保存了每个表的Region地址,还有一些其他信息,例如Region的名字,对应表的名字,开始Rowkey(STARTKEY)、结束Rowkey(ENDKEY)、服务器的信息。hbase:meta表中每一行对应一个单一的Region。
hbase:meta表单个数据含义:
•RowKey(行键)- TableName(表名),table produce epoch(表创建的时间戳)。
•ColumnFamily(列族) - info (信息)
•ColumnQualifier(列)- regioninfo;server;serverstartcode;seqnumDuringOpen
•value - NAME:表名 STARTKEY:表行键开始值 ENDKEY:表行键结束值 ENCODED:Region编码后的名字;服务器地址:端口;服务开始的时间戳;Region在线时长的一个二进制串
Zookeeper中存储了hbase:meta表的位置,客户端可以通过Zookeeper查找到hbase:meta表的位置,hbase:meta是HBase当中的一张表,肯定由一个HRegionServer来管理,其实主要就是要通过Zookeeper的”/hbase/meta-region-server”获取存储”hbase:meta”表的HRegionServer的地址。
附:ZK的作用
•作用一:HMaster、RegionServer容错
当HBase集群启动成功后,会在ZK注册如下znode:
./hbase/master,其中包含当前活动(Active)的HMaster信息;
./hbase/backup-masters/[host-name],每个子znode包含当前作为热备的HMaster信息;
./hbase/rs/[host-name],每个子znode包含各个RegionServer的信息。
所有znode都是临时(ephemeral)节点,HMaster和RegionServer通过心跳维护这些znode。

作用二:Log Split管理
Log Split的信息需要有一个中心组件来统一协调。HMaster会在ZK上注册 /hbase/splitlog临时节点,其中存放有存活RegionServer与其应该处理的Region HLog的映射关系。各个RegionServer从该节点得到分配的Region,重放HLog,并将结果写回该节点,以通知HMaster进行后续操作。


作用三:.META.表位置维护
ZK通过永久(persistent)节点/hbase/meta-region-server来记录.META.表保存在哪个RegionServer上。


作用四:Replication管理
HBase的Replication是比较高级的功能,用于主集群和从集群之间的数据同步,从而支持容灾和备份。开启Replication之后,主集群会将数据实时地推送给各个从集群(可以是异步、同步或串行的),且保证数据的最终一致性。整个Replication的状态信息都储存在ZK的 /hbase/replication这个znode下。

多个HBase集群是可以共用一个ZK集群的。只需要修改HBase的zookeeper.znode.parent参数,对不同集群指定不同的ZK根路径即可,例如/hbase-cluster1、/hbase-cluster2。
.读数据流程

.HBaseClient先访问Zookeeper,从meta表读取Region的位置,然后读取meta表中的数据。meta中又存储了用户表的Region信息;

.根据Rowkey在meta表中找到对应的Region信息;

.找到这个Region对应的RegionServer;

.查找对应的Region;

.先从MetaStore找数据,如果没有,再到BlockCache里面读;

.BlockCache还没有,再到StoreFile上读(为了读取的效率);

.如果是从StoreFile里面读取的数据,不是直接返回给客户端,而是先写入BlockCache,再返回给客户端。
.写数据流程

.HBaseClient访问Zookeeper,获取meta表所处位置(IP地址);

.访问meta表,然后读取meta表中的数据;

.根据namespace(类似于关系数据库中的数据库)、表名和Rowkey在meta表中找到该Rowkey应该写入到哪个Region;

.找到这个Region对应的RegionServer,并发送写数据请求;

.HRegionServer将数据先写到HLog(Write Ahead Log)。为了数据的持久化和恢复;

.HRegionServer将数据写到内存(MemStore);

.反馈给HBaseClient写入成功。
HBase将数据写入内存中后,就返回给客户端写入成功,响应非常快。这也是为什么HBase写数据速度快的原因。
.数据flush过程
HBase写数据是写入到MemStore内存就会返回客户端了,并没有直接落磁盘。磁盘IO非常小。那么什么时候数据会落到磁盘呢?其实MemStore空间是有限的,当MemStore数据达到阈值(默认是128MB),RegionServer将数据刷到HDFS上,生成HFile,然后将内存中的数据删除,同时删除HLog中的历史数据。该操作是由RegionServer自己完成

59、1. 为什么HBase查询比较快

HBase查询快,主要原因是由其架构和底层的数据结构决定的,即LSM(Log-Structured Merge Tree)+HTable(region分区)+Cache。
客户端可以直接定位到要查数据所在的HRegion Server服务器,然后直接在服务器的一个Region上查找要匹配的数据,并且这些数据部分是经过Cache缓存的。
HBase会将数据保存到内存中,在内存中的数据是有序的,如果内存空间满了,会刷写到HFile中,而在HFile中保存的内容也是有序的。当数据写入HFile后,内存中的数据会被丢弃。HFile文件为磁盘顺序读取做了优化。
HBase的写入速度快是因为它其实并不是真的立即写入到文件中,而是先写入内存,随后异步刷入HFile。所以在客户端看来,写入速度很快。另外,写入时候将随机写入转换成顺序写,数据写入速度也很稳定。读取速度快是因为它使用了LSM树形结构,而不是B或B+树。磁盘的顺序读取速度很快,但是相比而言,寻找磁道的速度就要慢很多。HBase的存储结构导致它需要磁盘寻道时间在可预测范围内,并且读取与所要查询的Rowkey连续的任意数据的记录都不会引发额外的寻道开销。比如有5个存储文件,那么最多需要5次磁盘寻道就可以。而关系数据库,即时使用索引,也无法确定磁盘寻道次数。而且,HBase读取首先会在缓存(BlockCache)中查找,它采用了LRU(最近最少使用算法),如果缓存中没找到,会从内存中的MemStore中查找,只有这两个地方都找不到时,才会加载HFile中的内容。

60、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

61、Hbase的查询方式有哪些?

1、全表查询:scan tableName
2、基于rowkey的单行查询:get tableName,’1’
3、基于rowkey的范围扫描:scan tableName, {STARTROW=>’1’,STOPROW=>’2’}
4、get和scan方法:
(1)、按指定的rowkey获取唯一一条数据,get方法:分为两种,分别是设置了closestRowBefore和没有设置的rowlock,只要保证行的事务性,即每一个get是以一个row来标记的,一个row中可以有多个family和column。
(2)、按指定的条件获取一批记录,条件查询。1、scan可以通过setCaching和setBatch方法来提高速度;2、scan也可以通过setStartRow和setEndRow来限定范围(左闭右开),3、scan还可以通过setFileter方法来添加过滤器。
ps:setCache和setBatch方法:
setCache方法:这个方法设置即一次RPC请求放回的行数,对于缓存操作来说,如果返回行数太多了,就可能内存溢出,那么这个时候就需要setBatch方法,。
setBatch:设置这个之后客户端可以选择取回的列数,如果一行包括的列数超过了设置的值,那么就可以将这个列分片。例如:如果一行17列,如果batch设置为5的话,就会返回四组,分别是5,5,5,2。、
※:Cache设置了服务器一次返回的行数,而Batch设置了服务器一次返回的列数。
ps:Batch参数决定了一行数据分为几个result,它只针对一行数据,Cache决定了一次RPC返回的result个数。
RPC请求次数 = (行数 * 每行列数) / Min(每行的列数,批量大小) / 扫描器缓存

#62、以 start-hbase.sh 为起点,Hbase 启动的流程是什么?

start-hbase.sh 的流程如下:
1.运行 hbase-config.sh
hbase-config.sh的作用:
1>.装载相关配置,如HBASE_HOME目录,conf目录,regionserver机器列表,JAVA_HOME 目录等,它会调用$HBASE_HOME/conf/hbase-env.sh .
2>.解析参数(0.96 版本及以后才可以带唯一参数 autorestart,作用就是重启)
3>.调用 hbase-daemon.sh 来启动 master.
4>.调用 hbase-daemons.sh 来启动 regionserver zookeeper master-backup.
2.hbase-env.sh 的作用:
主要是配置 JVM 及其 GC 参数,还可以配置 log 目录及参数,配置是否需要 hbase 管
理 ZK,配置进程 id 目录等.
3.hbase-daemons.sh 的作用:根据需要启动的进程,
如 zookeeper,则调用 zookeepers.sh
如 regionserver,则调用 regionservers.sh
如 master-backup,则调用 master-backup.sh
4.zookeepers.sh 的作用:
如果 hbase-env.sh 中的 HBASE_MANAGES_ZK”=”true”,那么通过ZKServerTool这个类解析xml配置文件,获取 ZK 节点列表,然后通过 SSH 向这些节点发送远程命令执行。
5.regionservers.sh 的作用:
与 zookeepers.sh 类似,通过配置文件,获取 regionserver 机器列表,然后 SSH 向这些机器发送远程命令:
6.master-backup.sh 的作用:
通过 backup-masters 这个配置文件,获取 backup-masters 机器列表,然后 SSH 向这些机器发送远程命令。

#63、简述 Hbase filter 的实现原理是什么?结合实际项目经验,写出几个使用filter 的场景?
HBase 为筛选数据提供了一组过滤器,通过这个过滤器可以在 HBase 中的数据的多个维度(行,列,数据版本)上进行对数据的筛选操作,也就是说过滤器最终能够筛选的数据能够细化到具体的一个存储单元格上(由行键, 列名,时间戳定位)。
比较过滤器:1.行过滤器(RowFilter)
      2.列族过滤器(FamilyFilter)
      3.列名过滤器(QualifierFilter)
      4.值过滤器(ValueFilter)
      5.参考列过滤器(DependentColumnFilter)
专用过滤器:1.单列值过滤器(SingleColumnValueFilter)
      2.单列排除过滤器(SingleColumnValueExcludeFilter)
      3.前缀过滤器(PrefixFilter)
      4.分页过滤器(PageFilter)
      5.行健过滤器(KeyOnlyFilter)
      6.首次行健过滤器(FirstKeyOnlyFilter)
      7.包含结束的过滤器(InclusiveStopFilter)
      8.时间戳过滤器(TimestampsFilter)
      9.列计数过滤器(ColumnCountGetFilter)
      10.列分页过滤器(ColumnPaginationFilter)
      11.列前缀过滤器(ColumnPrefixFilter)
      12.随机行过滤器(RadomRowFilter)
附加过滤器:1.跳转过滤器(SkipFilter)
      2.全匹配过滤器(WhileMatchFilter)
  hbase的filter是通过 scan 设置的,所以是基于 scan 的查询结果进行过滤。过滤器的类型很多,但是可以分为两大类——比较过滤器,专用过滤器。过滤器的作用是在服务端判断数据是否满足条件,然后只将满足条件的数据返回给客户端。如在进行订单开发的时候,我们使用 rowkeyfilter 过滤出某个用户的所有订单

#64、导致Hbase挂掉的场景有哪些?
导致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

#65、#### HBase的使用场景?

HBase可以说是一个数据库,也可以说是一个存储。拥有双重属性的HBase天生就具备广阔的应用场景。
在最近的一些版本中,引入了OffHeap降低gc影响,优化链路延迟,提供Replica等可以满足在线的需求。
引入MOB,可以存储10M左右的对象,完全适应了对象存储。另外由于自身的并发能力、存储能力,可以说是具有最为竞争力的引擎

经典的八大使用场景如下图**:**

总的来说:HBase适用以下场景:

1. 半结构化或非结构化数据
对于数据结构字段不够确定或杂乱无章很难按一个概念去进行抽取的数据适合用HBase。以上面的例子为例,当业务发展需要存储author的email,phone,address信息时RDBMS需要停机维护,而HBase支持动态增加。
2.记录非常稀疏
RDBMS的行有多少列是固定的,为null的列浪费了存储空间。而如上文提到的,HBase为null的Column不会被存储,这样既节省了空间又提高了读性能。
3. 多版本数据
如上文提到的根据Row key和Column key定位到的Value可以有任意数量的版本值,因此对于需要存储变动历史记录的数据,用HBase就非常方便了。比如上例中的author的Address是会变动的,业务上一般只需要最新的值,但有时可能需要查询到历史值。
4. 超大数据量
当数据量越来越大,RDBMS数据库撑不住了,就出现了读写分离策略,通过一个Master专门负责写操作,多个Slave负责读操作,服务器成本倍增。
随着压力增加,Master撑不住了,这时就要分库了,把关联不大的数据分开部署,一些join查询不能用了,需要借助中间层。随着数据量的进一步增加,一个表的记录越来越大,查询就变得很慢,于是又得搞分表,比如按ID取模分成多个表以减少单个表的记录数。
经历过这些事的人都知道过程是多么的折腾。采用HBase就简单了,只需要加机器即可,HBase会自动水平切分扩展,跟Hadoop的无缝集成保障了其数据可靠性(HDFS)和海量数据分析的高性能(MapReduce)。

#66、 HBase相关组件?

HBase是由Client、Zookeeper、Master、HRegionServer、HDFS等几个组件组成

HMaster

1. 管理用户对表的增删改查操作
2. 管理Hregion服务器的负载均衡,调整HRegion服务器的分布
3. Hregion分裂后,负责新的HRegion的分配
4. HRegion服务器停机后,负责失效Hregion服务器上的HRegion迁移过程

HRegionServer

1.负责存储HBase的实际数据
2.处理分配给它的Region
3.刷新缓存到HDFS
4.维护Hlog
5.执行压缩
6.负责处理Region分片

Client

Client包含了访问Hbase的接口,另外Client还维护了对应的cache来加速Hbase的访问,比如cache的.META.元数据的信息。

Zookeeper

1.Master**的高可用,HRegionServer的监控**
当HBase集群启动成功后,会在ZK注册如下znode:
/hbase/master,其中包含当前活动(即赢得选举)的HMaster信息;
/hbase/backup-masters/[host-name],每个子znode包含当前作为热备的HMaster信息;
/hbase/rs/[host-name],每个子znode包含各RegionServer的信息。

2. LOG_SPLIT**管理**
HMaster会在ZK上注册/hbase/splitlog临时节点,其中存放有存活RegionServer与其应该处理的Region HLog的映射关系。各个RegionServer从该节点得到分配的Region,重放HLog,并将结果写回该节点,以通知HMaster进行后续操作。
所有znode都是临时(ephemeral)节点,HMaster和RegionServer通过心跳维护这些znode。
活动HMaster对/hbase/rs路径下的znode注册监听,当有RegionServer失败时,心跳信号消失,超时过后其对应的znode被删除,HMaster即可感知到RegionServer下线,并将该RegionServer持有的Region重新路由到其他服务器上去。
同理,所有热备HMaster都对/hbase/master节点注册监听,当前HMaster挂掉后,该znode被删除,即可触发重新选举HMaster。
3. .META.**表位置维护**

HDFS

HDFS为HBase提供最终的底层数据存储服务,同时为HBase提供高可用(Hlog存储在HDFS)的支持,具体功能概括如下:
提供元数据和表数据的底层分布式存储服务
数据多副本,保证的高可靠和高可用性

其它组件
Write-Ahead logs

HBase的修改记录,当对HBase读写数据的时候,数据不是直接写进磁盘,它会在内存中保留一段时间(时间以及数据量阈值可以设定)。但把数据保存在内存中可能有更高的概率引起数据丢失.
为了解决这个问题,数据会先写在一个叫做Write-Ahead logfile的文件中,然后再写入内存中。所以在系统出现故障的时候,数据可以通过这个日志文件重建。

Region

Hbase表的分片,HBase表会根据RowKey值被切分成不同的region存储在RegionServer中,在一个RegionServer中可以有多个不同的region。

Store

HFile存储在Store中,一个Store对应HBase表中的一个列族(列簇, Column Family)。

MemStore

顾名思义,就是内存存储,位于内存中,用来保存当前的数据操作,所以当数据保存在WAL中之后,RegsionServer会在内存中存储键值对。

HFile

这是在磁盘上保存原始数据的实际的物理文件,是实际的存储文件。StoreFile是以Hfile的形式存储在HDFS的。

67、HBase Shell操作

基本shell操作

进入HBase客户端命令行
bin/hbase shell
·       1
查看帮助命令
help
·       1
查看当前数据库中有那些表
list
·       1
创建表
create 'student','info' # 创建表,表名student,列簇名info
·       1
插入数据
put 'student','1001','info:sex','male'
put 'student','1001','info:age','18'
put 'student','1002','info:name','Janna'
put 'student','1002','info:sex','female'
put 'student','1002','info:age','20'
·       1
·       2
·       3
·       4
·       5
扫描数据
scan 'student' #全表扫描
scan 'student',{STARTROW => '1001', STOPROW  => '1001'} #设置起始行键和终止行键扫描

·       1
·       2
·       3
查看表结构
describe 'student'
·       1
更新指定字段的数据
put 'student','1001','info:name','Nick'
put 'student','1001','info:age','100'
·       1
·       2
查看“指定行”或“指定列族:列”的数据
get 'student','1001'
get 'student','1001','info:name'
·       1
·       2
统计表数据行数
count 'student'
·       1
删除数据
 deleteall 'student','1001' # 删除某rowkey的全部数据
delete 'student','1002','info:sex' # 删除某rowkey的某一列数据
·       1
·       2
清空表数据
# 提示:清空表的操作顺序为先disable,然后再truncate。
truncate 'student'
·       1
·       2
删除表
# 首先需要先让该表为disable状态
 disable 'student'
# 然后才能drop这个表
 drop 'student'
# 提示:如果直接drop表,会报错:ERROR: Table student is enabled. Disable it first. 
·       1
·       2
·       3
·       4
·       5
变更表信息
# 将info列族中的数据存放3个版本
alter 'student',{NAME=>'info',VERSIONS=>3}

68、HBase原理

HBase架构

HBase架构图如下所示:

用我自己的语言解释该图:

每个HBase集群包含一个HMaster节点和多个HRegionServer节点(其中HMaster和HRegionServer的注册信息保存在Zookeeper上),同时Client进行读写操作时,也要通过Zookeeper访问.META.表的元信息
每个HRegionServer对应一个HLog日志文件(主要用于数据恢复),HLog日志文件的LOG_SPLIT信息,存储在Zookeeper中
每个HRegionServer包含多个HRegion,每个HRegion对应多个store,每个store存储的是一个列簇的数据
每个store包含一个Memstore和多个StoreFile,其中
StoreFile的数据以HFile的形式存储在HDFS上

HBase读数据流程

读操作如下图所示:

1)Client先访问zookeeper,从meta表读取region的位置,然后读取meta表中的数据。meta中又存储了用户表的region信息;
2)根据namespace、表名和rowkey在meta表中找到对应的region信息;
3)找到这个region对应的regionserver;
4)查找对应的region;
5)先从MemStore找数据,如果没有,再到BlockCache里面读;
6)BlockCache还没有,再到StoreFile上读(为了读取的效率);
7)如果是从StoreFile里面读取的数据,不是直接返回给客户端,而是先写入BlockCache,再返回给客户端。

HBase写数据流程

HBase写数据流程如下图:


① 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一分为二。

https://github.com/GTyingzi/BigDATA/blob/main/%E5%A4%A7%E6%95%B0%E6%8D%AE%E6%A1%86%E6%9E%B6/HBase.md

作者:admin  创建时间:2023-06-27 22:47
最后编辑:admin  更新时间:2024-04-07 15:40