当前位置:   article > 正文

Hadoop之HBase基本简介_hadoop hbase

hadoop hbase

目录

1.HBase的基本概念

2.HBase的工作流程

3.HBase的高可用

4.HBase的快照机制


1.HBase的基本概念


1.1基本概念

  • HBase运行在HDFS上,所以HBase中的数据以多副本形式存放,数据也服从分布式存放,数据的恢复也可以得到保障。
  • HBase支持横向扩展,这就意味着如果现有服务器硬件性能出现瓶颈只需要在现有的正在运行的集群中添加新的机器节点即可。
  • HBase是面向列存储非关系型数据库,所以存储是键值对的形式也不用单独去创建列直接当成一个列标识符去使用即可,,关系型数据库按行存储,每列数据都要进行存储。
  • HBase不支持事务,适合结构化数据和非结构化数据,只需要建立表表的列簇即可,不需要单独的在创建列
  • HBase的文件将随机读写转化为顺序读写,适合快速写入。

1.2基本结构组成

1.2.1HMaster

  • 从Zookepper上获取RegionServer的信息,可以对RegionServer进行故障转移,如果一定时间内未出现心跳,Master将该RegionServer上的Region重新分配到其他RegionServer上;
  • 负责Region server负载均衡,可以进行Region分区
  • HMaster维护Hbase的元数据,由于会给Zookeeper同步元数据如果失效仅会导致所有元数据无法被修改,建表,删表,region切分、负载均衡等无法进行,表的数据读写还是可以正常进行

1.2.2RegionServer

  • 负责存储HBase的实际数据,处理分配给它的Region,
  • 刷新缓存到HDFS,可以维护HLog,可以执行压缩,负责处理Region分片
  • 内含组件:
  • Write-Ahead logs
  • HBase的修改记录,当对HBase读写数据的时候,数据不是直接写进磁盘,它会在内存中保留一段时间(时间以及数据量阈值可以设定)。如果机器突然原地爆炸,把数据保存在内存中会引起数据丢失,为了解决这个问题,数据会先写在一个叫做Write-Ahead logfile的文件中,然后再写入内存中。所以在系统出现故障的时候,数据可以通过这个日志文件重建丢失的内存数据

  • HFile 和 Store
  • 一个Region由多个Store组成,一个Store对应HBase表中的一个列族,一个Store可对应多个StoreFile--HFile(存放于HDFS的DataNode中),这个File文件跟列簇里的列没有对应关系(查询的时候使用布隆过滤器根绝key和列名来定位对应的file)
  • 一个HFile含有多个Block,Block默认大小为64KB;
  • MemStore
  • 内存存储,位于内存中,用来保存当前的数据操作,所以当数据保存在WAL中之后,RegsionServer会在内存中存储键值对。
  • Region
  • Hbase表的分片,HBase表会根据RowKey值被切分成不同的region存储在RegionServer中,在一个RegionServer中可以有多个不同的region

1.2.3Zookeeper

  • HMaster与HRegionServer 启动时会向ZooKeeper注册,存储所有HRegion的寻址入口,
  • 实时监控HRegionserver的上线和下线信息,并实时通知给HMaster
  • 存储HBase的schema和table元数据;
  • Zookeeper的引入使得HMaster不再是单点故障。一般情况下会启动两个HMaster,非Active的HMaster会定期的和Active HMaster通信以获取其最新状态,从而保证它是实时更新的

1.3HBase在HDFS的目录分析

  • /hbase/.tmp :      临时目录,当对表做创建和删除的时候,会将表move到该目录下,然后进行操作
  • /hbase/data :    核心目录namespace,代表不同的数据库可以类比mysql可以创建多个数据库,存储HBase表的数据 默认情况下该目录下有两个目录: /hbase/data/default 和 /hbase/data/hbase
  • /hbase/data/default :             在用户创建表的时候,没有指定namespace时,表就创建在此目录下         
  • /hbase/data/hbase :           系统内部创建的表
  • /hbase/hbase.id :    存储的是集群的唯一的cluster id(uuid)     
  • /hbase/hbase.version :  集群版本号     
  • /hbase/oldWALs :        对应的0.94.x版本中.oldlogs目录         当/hbase/WALs目录中的logs没有用之后,会将这些logs移动到此目录下,HMaster会定期的进行清理

1.4HBase Shell操作 — 基本操作

1.5Block Encoder和Compressor

  • 如果rowkey很长的话或者这个column family含有很多的column的话,则使用Block Encoder推荐使用Fast Diff,可以节省空间
  • 如果value很大的话,则需要使用Block Compressors,可以节省空间


2.HBase的工作流程


2.1读数据流程

  • 例如:get <table>,<rowkey>,[<family:column>,....]
  • 首先Client先去访问zookeeper,从zookeeper的root表里面获取meta表所在的位置信息,即找到这个meta表对应的RegionServer,
  • 接着访问RegionServer,根据RowKey与RegionServer的meta表中所属table表的startkey和endkey对比,以此来找到rowkey所在的具体regionserver上;
  • 扩展:在HBase 0.96以后去掉了-ROOT- Table,只剩下Meta Table(hbase:meta),zookeeper直接是存储集群中所有用户HRegion的位置信息;
  • 然后扫描所在RegionServer的Memstore和Storefile来查询数据,
  • 注意:优化点在查询Memstore之后Storefile之前的时候,会有一个BlockCache用于缓解并发读的操作;
  • 详见2.1.1:
  • 最后HRegionServer把查询到的数据响应给Client。
  • 只要,涉及到客户端到服务端的通信都会使用HBase RPC机制与HMaster和HRegionserver通信;

2.1.1Bloom Filter

  • HRegionServer上会先根据各个文件的布隆过滤器扫描,看row/col在那个文件上;
  • 确定了某个文件然后在根据file的blockindex使用二分查找进行具体的查询;

2.2写数据流程

  • 例如:put <table>,<rowkey>,<family:column>,<value>
  • Client也是先访问zookeeper找到Root表,访问HRegionServer,找到Meta表,并获取Meta表元数据。
  • 确定当前将要写入的数据所对应HRegion的HRegionServer服务器。
  • 扩展:在HBase 0.96以后去掉了-ROOT- Table,只剩下Meta Table(hbase:meta),zookeeper直接是存储集群中所有用户HRegion的位置信息;
  • Client先把数据写入到HLog,以防止Memstore在掉电的时候数据丢失
  • 然后将数据写入到Memstore
  • 如果HLog和Memstore均写入成功,则这条数据写入成功。
  • 如果Memstore达到阈值(默认为128MB),会把Memstore中的数据flush到Storefile中。
  • 当Storefile越来越多,会触发Compact合并操作,把过多的Storefile合并成一个大的Storefile(对HDFS友好)。
  • 当Storefile越来越大,Region也会越来越大,达到阈值后,会触发Split操作,将Region一分为二。
  • 只要,涉及到客户端到服务端的通信都会使用HBase RPC机制与HMaster和HRegionserver通信;

2.3进行分区

  • 当数据写入HBase时,会按照region的RowKey分区情况去写入,对region进行负载均衡防止数据访问倾斜
  • 每一个region维护着startRow与endRowKey,如果加入的数据符合某个region维护的rowKey范围,则该数据交给这个region维护;
  • 预分区:create 'staff','info',SPLITS => ['1000','2000','3000','4000']
  • 自动分区:比如当一个Region达到一定的大小的时候,这个Region会自动切分成两个Region
  • 还可以对创建好的表直接进行手动分区;

2.4删除和修改数据

  • HBase 的删除操作并不会立即将数据从磁盘上删除,删除操作主要是对要被删除的数据打上标记。
  • 由于HBase底层依赖HDFS,对于HBase删除操作来说,HBase无法在查询到之前的数据并进行修改,只能顺序读写,追加记录
  • 当执行删除操作时,HBase 新插入一条相同的 KeyValue 数据,但是使 keytype=Delete,这便意味着数据被删除了,直到发生 Major compaction 操作时,数据才会被真正的从磁盘上删除,删除标记也会从StoreFile删除。
  • Minor Compaction:指选取一些小的、相邻的HFile将他们合并成一个更大的HFile。默认情况下,minor compaction会删除选取HFile中的TTL过期数据。
  • Major Compaction:指将一个Store中所有的HFile合并成一个HFile,这个过程会清理三类没有意义的数据:被删除的数据(打了Delete标记的数据)、TTL过期数据、版本号超过设定版本号的数据。另外,一般情况下,
  • Major Compaction时间会持续比较长,整个过程会消耗大量系统资源,对上层业务有比较大的影响。因此,生产环境下通常关闭自动触发Major Compaction功能,改为手动在业务低峰期触发
  • HBase的更新操作,实际会生成一个新的版本号,而不是直接删除,对于不同时间戳的多条数据,根据其保存的最大版本数据,在Major Compaction的时候删除过期的数据
  • 当数据在内存Memory Store里时,会直接进行删除。

3.HBase的高可用


3.1Master容错

  • HBase内置了Zookeeper负责重新选择一个新的Master,是通过创建临时顺序节点+watch监听来进行选举的;
  • 无Master过程中,数据读取仍照常进行﹔
  • 无Master过程中,建表,删表,region切分、负载均衡等无法进行

3.2RegionServer容错

  • RegionServer定时向Zookeeper汇报心跳,如果一旦时间内未出现心跳,Master将该RegionServer上的Region重新分配到其他RegionServer
  • 宕机导致服务器上的Memstore内存数据丢失,可以通过失效服务器上“预写”的log日志由主服务器进行分割并派送给新的RegionServer进行恢复

4.HBase的快照机制


4.1快照的详细介绍

  • 我们知道在HBase中,数据是先写入到Memstore中,当Memstore中的数据达到一定条件,就会flush到HDFS中,形成HFile后面就不允许原地修改或者删除了。如果要更新或者删除的话,只能追加写入新文件(生成多个版本或者打上标记)。既然数据写入以后就不会在发生原地修改或者删除,这就是snapshot做文章的地方。
  • 其实就是因为会存在多个版本的数据,所以可以支持不同的元数据索引到对应版本的数据,就能实现将表的数据回滚到snapshot那个时刻的数据。;

4.2snapshot的流程

  • 对该表添加全局锁,不允许任何数据的写入、更新和删除
  • 将该表内存中的数据(memstore)flush到HFile文件中
  • 为该表涉及的各个region中所有HFile文件创建引用指针,并记录到snapshot文件中
  • Hmaster将所有的region的snapshot文件进行汇总形成总体的snapshot文件

4.3多个region如何保证原子性

  • 利用zookeeper使用类似两阶段提交的策略,
  • prepare阶段先生成快照然后保存在临时目录然后给/acquired-snapshot节点写入表示该节点写入成功,全部成功之后,
  • commit阶段将临时目录的文件移动到刚创建的/reached-snapshotname,
  • 如果在这两个阶段中,出现问题,一定时间内,/reached-snapshotname下的子节点没有满足条件   或者   prepare阶段中/acquired-snapshot下的子节点不满足条件,那么会进行回滚
  • 回滚阶段Hmaster会在ZK上创建/abort-snapshotname节点,所有regionserver监听到会清理临时snapshot在临时文件夹中的生成结果。

玩转HBase快照 - 简书


5.阿里HBase

  • 二级索引:
    • 在功能上,lindorm中的表支持设置多个二级索引,每一个二级索引在存储上映射为一个新的物理表,我们称之为(二级)索引表。每一个二级索引均可以设置一个或者多个主键列组合,并且允许将部分非索引列冗余到存储到索引表中,从而减少主表回查
    • 在查询执行时,服务端会根据查询条件和可用的索引表,生成最优的物理执行计划,用户也可以在请求中主动设置索引使用的Hint,从而显示地优化查询。
  • 轻量级客户端:
    • 无状态访问的设计可以使得客户端非常轻量,大幅减少依赖(比如不再需要依赖zookeeper,避免出现应用Bug造成ZK连接泄露,导致服务端Crash的问题;不再需要直接访问元数据,避免客户端规模过大造成的元数据负载瓶颈),
    • 但也会给请求带来额外跳转一次的开销,为了仍然保持最短路径的性能,我们在lindorm的客户端中引入一种基于双端通信的弱路由缓存,客户端在本地堆内会持有一份路由信息,但其内容的维护由服务端控制
    • 客户端可以在启动时主动预热路由,当路由空白或者有误时,收到请求的服务器会进行转发代理,并将正确的路由地址回馈给客户端。除了路由,Lindorm客户端在黑名单同步、Zone间流量切换、集群切换等方面也使用了类似的设计。此外,lindorm客户端提供基于netty框架的全功能接口的异步API,大幅提高系统访问吞吐

6.HBase最佳实践

  • 主键索引:rowkey就好比数据库的里的主键,他唯一确定了一条记录,它可以是一个字段也可以是多个字段拼接起来:
    • 每个用户只有一条记录: [userid]
    • 每个用户有多条交易记录:[userid][orderid]
  • 查询场景:
    • 1. 根据完整的rowkey查询(get)select * from table where rowkey = ‘abcde’,
    • 2. 根据rowkey的范围查询(scan):select * from table where ‘abc’ < rowkey <’abcx’这种查询方式需要知道数据rowkey左边的值
  • Hbase入门(五)——客户端(Java,Shell,Thrift,Rest,MR,WebUI)-CSDN博客
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/繁依Fanyi0/article/detail/504583
推荐阅读
相关标签
  

闽ICP备14008679号