《HBase权威指南》读书笔记八:第八章 架构

《HBase权威指南》读书笔记8:第八章 架构

8.1 数据查找和传输

B+树:B+树比B树的改进为叶子节点也是顺序排放的
《HBase权威指南》读书笔记八:第八章 架构
LSM(log-structured merge-tree)树
《HBase权威指南》读书笔记八:第八章 架构

存储

系统概述
《HBase权威指南》读书笔记八:第八章 架构

HBase主要处理两种文件: WAL (Write-Ahead Log)预写日志   和   实际的数据文件

基本流程

  1. 客户端联zookeeper查找行健
  2. 通过zookeeper获取含有 -ROOT- 的 region服务器名来完成的
  3. 通过含有 -ROOT- 的region服务器可以查询到含有 .META. 表中对应的region服务器名,其中包含请求的行键信息。这两处的主要内容都被缓存下来,并且都只查询一次
  4. 最终,通过查询 .META. 服务器来获取客户端的行键数据所在的region的服务器名
HregionServer
  • HRegionServer负责打开region,并创建对应的HRegion实例,当HRegion被打开后,它会为每个表的HColumnFamily创建一个Store实例
  • 每个Store实例包含一个或多个StoreFile实例,他们是实际数据文件HFile的轻量级封装
  • 每个store还有其对应的一个memstore
  • 一个HRegionServer分享一个HLog实例

写路径

写请求到的路径:
  1. WAL(HDFS)
  2. memstore
  3. HFile
网上有一幅特别好的图,虽然不是权威手册里面的,所以加到这篇文章里面。从图上可以明显看出 WAL是在hdfs上的
《HBase权威指南》读书笔记八:第八章 架构

文件

  • WAL被存储在HDFS 里面 /hbase 目录下的 .log 文件夹里面
  • 由于WAL文件刚刚被创建所以显示大小是0。这是因为在hdfs里面用append来写入此文件,只有等到文件达到一个完整的块时,文件对用户才是可见的。
  • WAL 文件会等到 hbase.regionserver.logroll.period (默认是60分钟)时间之后被滚动,紧接着它的下一个新日志文件大小又从0开始了
  • 滚动之后旧日志被放到 .oldlogs 下,并等到 hbase.master.logcleaner.ttl (默认是10分钟) 后被删除。检测间隔是 hbase.master.cleaner.interval 属性设置的。

表级文件

  • 在HBase中,每张表都有自己的目录,位于HBase根目录下。每张表目录包括一个名为 .tableinfo 的顶层文件
  • 该文件对应序列化后的HTableDescription

Region级文件

  • .regioninfo 对应HRegionInfo实例
  • hbck  就是用 .regioninfo 来检查并生成元数据表中丢失的条目
  • region 如果超过了配置的最大值 hbase.hregion.max.filesize,会拆分,并创建一个 splits 目录

合并

  • 当文件的数量达到阀值,会触发合并操作。该过程会持续到这些文件中最大的一个超过最大存储大小,然后触发一次region  split
  • 合并分为 minor 和  major 
  • minor 合并负责重写最后生成的几个文件到一个更大的文件中
  • minor 合并负责重写最后生成的几个文件到一个更大的文件中,具体合并几个文件靠 hbase.hstore.compaction.min 定义
  • minor 合并可以处理的最大文件数量默认为10,用户可通过 hbase.hstore.compaction.max 定义
  • major 合并把所有文件压缩成一个单独的文件
合并的触发:
  • CompactionChecker 类实现,它以一个固定的周期触发检查,这个周期由 hbase.server.thread.wakefrequency 参数控制(乘以 hbase.server.thread.wakefrequency.multiplier,设为 1000 ,这样它的执行频率不会像其他基于线程的任务这么频繁)
  • 除非使用 majorCompact() ,否则服务器将首先检查上次运行到现在是否达到 hbase.hregion.majorcompaction (默认为24小时)指定的时限。
  • 如果没有到 major 合并的执行周期,系统会选择 minor 合并执行

WAL

HLog类

  • 实现了WAL的类叫做HLog
  • WAL是可选的,如果用户在执行一个离线的大批量导入数据的MapReduce作业的时候可以获得额外的性能,但是需要注意导入的时候有可能数据丢失(强烈建议不要关闭)
  • HLog被这台机器上的所有region共享

HLogKey类

WAL使用的是 Hadoop  的 SequenceFile。这种文件格式按照 key value存储数据,HLogKey 类作为key存储了,数据的归属,region和表名,写入时间,集群ID

LogSyncer类

管道写与多路写
sync()实现的是管道写,当写入的时候修改被发送到第一个datanode,处理完成后在被发送到下一个datanode,直到3个datanode都已经确认了写操作,客户端才被允许继续进行
多路写是写入同时被发送到3台主机上,当所有主机确认了写操作之后,客户端才可以继续
区别: 管道写延迟很高,但是可以更好的利用带宽。多路写有比较低的延迟,因为客户端只需要等待最慢的Datanode确认。

延迟日志刷写

deferred log flush ,默认是false,如果为true,修改会先被缓存在region服务器中,然后服务器上有一个 logSyncer类,每隔1秒来写入一次数据(hbase.regionserver.optionallogflushinterval 设定)

LogRoller

当日志出现 
2011-06-15 01:45:33,323 INFO org.apache.hadoop.hbase.region server.HLog: Too many hlogs: logs=130,maxlog=96;forcing flush of 8 region(s):.....
是因为需要保留的日志文件数超过了设置的最大日志文件数,但是仍有一些数据么有被更新。服务器会进入到一个特殊的模式来强制刷写内容中的更新数据,以减少需要保存的日志量。
其他控制日志滚动的参数有 
  • hbase.regionserver.hlog.blocksize(设置为文件系统默认的块大小或者 fs.local.block.size 默认为32M)
  • hbase.regionserver.logroll.multiplier (设为0.95) 表示当日志达到块大小的95%就会滚动日志

回放

单日志

使用单日志的原因是减少磁盘寻址,提高性能,但是会为恢复带来麻烦,要先日志拆分

日志拆分

两种日志需要被回放的情况:
  • 集群启动时
  • 服务失效时

数据恢复

  • region启动的时候会先检查 recovered.edits 目录是否存在,如果存在就开始读取并恢复数据。
  • 当序列ID小于硬盘上的序列ID就会被忽略

读路径

其实Get的内部实现也是Scan

Region生命周期

region的所有可能状态
状态 描述
Offline region下线
Pending Open 打开region的请求已经发送到了服务器
Opening 服务器开始打开region
Open region已经打开,可以使用
Pending Close 关闭region的请求已经被发送到了服务端
Closing 正在关
Closed 已关
Splitting 服务器开始拆分region
Split region 已经被切分了

zookeeper

zookeeper 中存储的信息
  • /hbase/hbaseid :可以使用 get /hbase/hbaseid 查看,其他命令类似,包含clusterID
  • /hbase/master   包含服务器名
  • /hbase/replication   包含副本信息
  • /hbase/root-region-server   包含 -ROOT- region 所在region服务器的机器名,这个经常在 region 定位中使用
  • /hbase/rs   这个znode是作为所有region服务器的根节点,集群用来跟踪服务器异常,每个znode都是临时节点,并且node名是region服务器的名称
  • /hbase/shutdown  这个节点用来跟踪集群状态信息,包括集群启动的时间,以及当集群被关闭时的空状态
  • /hbase/splitlog   协调日志拆分相关的的父节点
  • /hbase/table   当表被禁用,信息会被添加到这个znode下。表名是新建的的node名,内容是 DISABLED 

版权声明:本文为博主原创文章,未经博主允许不得转载。

1楼u01002886944分钟前
楼主不来个总结吗?