标签:hbase hadoop
8.1 数据查找和传输
B+树:B+树比B树的改进为叶子节点也是顺序排放的
LSM(log-structured merge-tree)树
存储
系统概述
HBase主要处理两种文件: WAL (Write-Ahead Log)预写日志 和 实际的数据文件
基本流程
- 客户端联zookeeper查找行健
- 通过zookeeper获取含有 -ROOT- 的 region服务器名来完成的
- 通过含有 -ROOT- 的region服务器可以查询到含有 .META. 表中对应的region服务器名,其中包含请求的行键信息。这两处的主要内容都被缓存下来,并且都只查询一次
- 最终,通过查询 .META. 服务器来获取客户端的行键数据所在的region的服务器名
HregionServer
- HRegionServer负责打开region,并创建对应的HRegion实例,当HRegion被打开后,它会为每个表的HColumnFamily创建一个Store实例
- 每个Store实例包含一个或多个StoreFile实例,他们是实际数据文件HFile的轻量级封装
- 每个store还有其对应的一个memstore
- 一个HRegionServer分享一个HLog实例
写路径
写请求到的路径:
- WAL(HDFS)
- memstore
- HFile
网上有一幅特别好的图,虽然不是权威手册里面的,所以加到这篇文章里面。从图上可以明显看出 WAL是在hdfs上的
文件
- 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
版权声明:本文为博主原创文章,未经博主允许不得转载。
《HBase权威指南》读书笔记8:第八章 架构
标签:hbase hadoop
原文地址:http://blog.csdn.net/nsrainbow/article/details/49363053