大数据组件之HBase的核心内容掌握

HBase的详细解读

1.HBase是以hdfs为数据存储的,一种分布式、可扩展的NoSQL数据库
2.HBase的物理存储结构
Row KeyColumn FamilyColumn QualifierTimestampTypeValue
row_key1personal_infonamet1put张三
row_key2personal_infocityt2put北京
row_key3personal_infonamet3put李四
3.数据模型
  1. name space(命名空间) 与数据库中的database概念一致

  2. table 类似于关系型数据库的表概念,不同的是,HBase定义表时只需要声明列族即可,字段可以动态、按需指定。(与关系型数据库相比,HBase能够轻松应对字段变更的场景)

  3. row HBase表中的每行数据都由一个RowKey和多个Column(列)组成,数据是按照RowKey的字典顺序存储的

  4. Column HBase中的每个列都由Column Family(列族)和Column Qualifier(列限定符)进行限定。

  5. time stamp 用于标识数据的不同版本,,每条数据写入时,系统会自动为其加上该字段

  6. cell 由{rowkey,column Family: column Qualifier, timestamp}唯一确定的单元。(cell中的数据全部是字节码形存储)

4.HBase基本架构
  • Master

    主要进程,具体实现类为HMaster,通常部署在namenode上

    功能:负责通过ZK监控RegionServer进程的状态,同时是所有元数据变化的接口。内部启动监控执行regiond的故障转移和拆分的线程

  • RegionServer

主要进程,具体实现类为HRegionServer,部署在datanode上

功能:主要负责数据cell的处理,同时在执行区域的拆分和合并 的时候,由RegionServer来实际执行

4.1 架构角色分析
1)Master主要作用:
  • 管理源数据表格hbase:meta,接收用户对表格创建修改删除的命令并执行
  • 监控region是否需要进行负载均衡,故障转移和region的拆分
通过启动多个后台线程监控实现上述功能:
  • LoadBalancer负载均衡器
    周期性监控region分布在regionServer上面是否均衡,由参数hbase.balancer.period控制周期时间,默认5分钟。
  • CatalogJanitor元数据管理器
    定期检查和清理hbase:meta中的数据。meta表内容在进阶中介绍
  • MasterProcWAL master预写日志处理器
    把master需要执行的任务记录到预写日志WAL中,如果master宕机,让backupMaster读取日志继续干
2)Region Server主要作用:
(1)负责数据cell的处理,例如写入数据put,查询数据get等
(2)拆分合并region的实际执行者,由master监控,由regionServer执行
3)Zookeeper
HBase通过Zookeeper来做master的高可用、记录RegionServer的部署信息、并且存储有meta表的位置信息。
4)HDFS
HDFS为HBase提供最终的底层数据存储服务,同时为HBase提供高容错的支持
4.2 写流程
写流程顺序正如API编写顺序,首先创建HBase的重量级连接
(1)首先访问zookeeper,获取hbase:meta表位于那个RegionServer;
(2)访问对应的Region Server,获取hbase:meta表,将其缓存到连接中,作为连接属性MetaCache,由于Meta表格具有一定的数据量,导致了创建连接比较慢;(之后使用创建的连接获取Tbale,这是一个轻量级的连接,只有在第一次创建的时候会检查表格是否存在访问RegionServer,之后在获取Table是不会访问RegionServer)
(3)调用Table的put方法写入数据,此时还需要解析RowKey,对照缓存的MetaCache,查看具体写入的位置在哪个RegionServer;
(4)将数据顺序写入(追加)到WAL,此处写入是直接落盘的,并设置专门的线程控制WAL预写日志的滚动
(5)根据写入命令的RowKey和ColumnFamily查看具体写入到哪个MemStory,并且在MemStory中排序;
(6)向客户端发送ack;
(7)等达到MemStore的刷写时机后,将数据刷写到对应的story中
4.3 MemStore Flush
Memstore刷写由多个线程控制,条件相互独立:

主要的刷写规则是控制刷写文件的大小,在每一个刷写线程中都会进行监控

(1)当memstore的大小达到了

hbase.hregion.memstore.flush.size(默认值128M)

hbase.hregion.memstore.block.multiplier(默认值4)

时,会刷写同时阻止继续往该mnmstore写数据(由于线程监控时周期性的,所有有可能面对数据洪峰,尽管可能性比较小)

(2)由HRegionServer中的属性MemStoreFlusher内部线程FlushHandler控制。标准为LOWER_MARK(低水位线)和HIGH_MARK(高水位线),意义在于避免写缓存使用过多,造成内存OOM(内存溢出)

当regionserver中memstore的总大小达到低水位线

hbase.regionserver.global.memstore.size(默认值0.4)

region会按照其所有memstore的大小顺序(由大到小)依次进行刷写。直到regionserver中所有memstore的总大小件小到上述值以下

当regionserver中memstore的总大小达到高水位线

hbase.regionserver.global.memstore.size.lower.limit(默认值0.95)

时,会同时阻止继续往所有的memstore写数据。

(3)为了避免数据长时间处于内存中,达到自动刷写时间,也会触发memstore flush。由HRegionServer的属性PeriodicMemStoreFlusher控制进行,由于重要性比较低,5min才会执行一次。自动刷新的时间间隔由该属性进行配置hbase.regionserver.optionalcacheflushinterval(默认1小时)

4.4 读流程
4.4.1 HFile结构
HFile是存储在HDFS上面每一个store文件夹下实际存储数据的文件。里面存储多种内容。包括数据本身(keyValue键值对)、元数据记录、文件信息、数据索引、元数据索引和一个固定长度的尾部信息(记录文件的修改情况)
键值对按照块大小(默认64k)保存在文件中,数据索引按照块创建,块越多,索引越大。每个HFile还会维护一个布隆过滤其(就像是一个很大的地图,没文件中每有一中key,就在对应的位置标记,读取时可以大致判断要get的可以是否存在HFile中)
(HFile存储经过序列化,所以无法直接查看)
4.4.2 读流程
创建连接童鞋流程
(1)创建Table对象发送get请求
(2)优先访问Block Cache,查找是否之前读取过,并且可以读取HFile的索引信息和布隆过滤器
(3)不管读缓存中是否已经有数据了(可能已经过期了),都需要再次读取写缓存和store中的文件。
(4)最终将所有读取的数据合并版本,按照get的要求返回即可。
4.4.3 合并读取数据优化
每次读取数据都需要读取三个位置,最后进行版本的合并。效率非常低,所有系统需要对此优化。
(1)HFile带有索引文件,读取对应RowKey数据会比较块
(2)Block Cache会缓存之前读取的内容和元数据信息,如果HFile没有发生变化(记录在HFile为信息中),则不需要再次读取。
(3)使用布隆过滤器能够快速过滤当前HFile不存在需要读取的RowKey,从而避免读取文件。(布隆过滤器使用HASH算法,不是绝对准确的,出错会照成多扫描一个文件,对读取结果没有影响)
4.5 StoreFile Compaction
  1. 过小合并,过大不合并
  2. 文件大小/hbase.hstore.compaction.ratio<(剩余文件大小和)则参与压缩。所有把比值设值过大,如10会最终合并为一个特别大的文件,相反设置为0.4,会最终产生4哥storeFile。不建议修改默认值
  3. 满足压缩条件的文件个数达不到个数要求(3<=count<=10)则不压缩。
4.6 Region Split

region切分分为两种,一种是自定义分区,一种是系统分区。(为了避免Region种的数据量太大)。

4.6.1 预分区(自定义分区)

每一个region维护者startRow与endRowKey,如果加入的数据符合某一个region维护的rowKey范围,则该数据交给这个region维护。那么按照这个原则,我们可以将数据所要投放的分区提前大致的规划好,以提高HBase性能。

4.6.2 系统拆分

Region的拆分是由HRegionServer完成的,在操作之前需要通过ZK汇报master,修改对应的Meta表信息添加量列info:splitA和info:splitB信息。之后需要操作HDFS上面对应的文件,按照拆分后的Region范围进行标记区分,实际操作为创建文件引用,不会挪动数据。刚完成拆分的时候,两个Region都由原先的RegionServer管理。之后汇报个欸Master,由Master将修改后的信息写入到Meta表种。等待下一次触发负载均衡机制,才会修改iRegion的管理服务者,二数据要等到下一次压缩值,才会实际进行移动。

2.0版本之后 =》 SteppingSplitPolicy

HBase2.0引入了新的split策略:如果当前RegionServer上该表只有一个Region,按照2*hbase.hregion.memstore.flush.size(128M默认)分裂,否则按照hbase.hregion.max.filesize(10G默认)分裂。

4.7 二级索引
4.7.1 二级索引配置文件

添加如下配置到HBase的HRegionserver节点的hbase-site。xml

<property>
    <name>hbase.regionserver.wal.codec</name>
    <vaule>org.apache.hadoop.hbase.regionserver.wal.IndexedWALEditCodec</value>
</property>
4.7.2 全局索引(global index)

Global Index 是默认的索引格式,创建全局索引时,会在HBase种建立一张新表,也就是说索引数据和数据表存放在不同的表种的。因此全局索引适用于多读少写的业务场景。

写数据的时候会消耗大量开销,因为索引表也要更新,二索引表是分布在不同的数据节点上的,跨节点的数据传输带来较大的性能消耗。

创建单个字段的全局索引:

create index my_index on my_table (my_col);

查看二级索引是否有效,可使用explainPlan执行计划来查看:

explain select id,name,add from student1 where age=10;

若结果中含有RANGE SCAN OVER说明二级索引有效;

若结果中含有FULL SCAN说明二级索引无效;

切记:如果想查询的字段不是索引字段的话,索引表不会被使用,也就是说不会带来查询速度的提升。
4.7.3 包含索引(covered index)

创建携带其他字段的全局索引(本质还是全局索引):

create index my_index on my_table (v1) include (v2);
4.7.4 本地索引(local index)

Local index 适用于写操作频繁的场景。

索引数据和数据表的数据时存放在同一张表中(且是同一个Region),避免了在写操作的时候往不同服务器的索引表中写索引带来的二外开销。

本地索引的创建(my_column可以是多个):

create local index my_index on my_table (my_column);
优劣:本地索引会将所有的信息存放在一个影子列族中,虽然读取的时候也是范围扫描,但是没有全局索引快,优点在于不用写多个表了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值