一、Hbase存储框架

图1  Hbase存储架构图

1、结构

HBase中的每张表都通过行键按照一定的范围被分割成多个子表(HRegion),默认一个HRegion超过256M就要被分割成两个,由HRegionServer管理,管理哪些HRegion由HMaster分配。

HRegionServer存取一个子表时,会创建一个HRegion对象,然后对表的每个列族(Column Family)创建一个Store实例,每个Store都会有0个或多个StoreFile与之对应,每个StoreFile都会对应一个HFile, HFile就是实际的存储文件。因此,一个HRegion有多少个列族就有多少个Store。

另外,每个HRegion还拥有一个MemStore实例。

(发现上图中一个错误,一个HRegionServer只对应一个HLog,也就是说同个HRegionServer中的HRegion共享一个HLog)

2、流程

a)Client发起了一个HTable.put(Put)请求给HRegionServer

b)HRegionServer会将请求匹配到某个具体的HRegion上面

c)决定是否写WAL log。WAL log文件是一个标准的Hadoop SequenceFile,文件中存储了HLogKey,这些Keys包含了和实际数据对应的序列号,主要用于崩溃恢复。

d)Put数据保存到MemStore中,同时检查MemStore状态,如果满了,则触发Flush to Disk请求。

e)HRegionServer处理Flush to Disk的请求,将数据写成HFile文件并存到HDFS上,并且存储最后写入的数据序列号,这样就可以知道哪些数据已经存入了永久存储的HDFS中。

二、Hbase存储格式

HBase是基于BigTable的面向列的分布式存储系统,其存储设计是基于Memtable / SSTable设计的,主要分为两部分,一部分为内存中的MemStore (Memtable),另外一部分为磁盘(这里是HDFS)上的HFile (SSTable)。还有就是存储WAL的log,主要实现类为HLog.

MemStore

MemStore源码:private final ConcurrentNavigableMap delegatee;

本质上MemStore就是一个内存里放着一个保存KEY/VALUE的MAP,当MemStore(默认64MB)写满之后,会开始刷磁盘操作。

HFile结构

图2  HFile结构图

HFile是基于HADOOP TFile的,如图2,文件长度为变长,仅FILE INFO/Trailer定长,Trailer中有指针指向其他数据块的起始点。Index数据块记录了每个Data块和Meta块的起始点。Data块和Meta块都是可有可无的,但对于大多数HFile,你都可以看到Data块。

Data块中,除了头部的MAGIC之外,就是一对对KEY/VALUE对,结构如下:

图3  Data块KEY/VALUE对结构

关于文件块的大小:

默认块大小64KB,在创建表时可以通过HColumnDescriptor设定每个Family的块大小。

大数据块:适合顺序查找,不适合随机查找。

小数据块,适合随机查找,需要更多内存保存Data Index,创建文件慢,更多的flush操作

图4  HFile总体结构图

当key的value大小超过BLOCK SIZE时,那么查找这些value就无法通过索引去快速查找,而是需要通过遍历进行。

另外,针对目前针对现有HFile的两个主要缺陷:

a)暂用过多内存

b)启动加载时间缓慢

提出了HFile Version2设计:

HLog

HLog是HBase的日志类,在写入时进行write-ahead-log(WAL),主要为数据恢复。每个HRegionServer会对应一个HLog实例,HRegion在初始化的时候HRegionServer会将该HLog的实例作为构造函数传入其中。HLog的核心函数是其append()函数。

HLog File 是一个Sequence File,只能在文件的末尾添加内容。除了文件头以外,HLog File 由一条条HLog.Entry构成。Entry是HLog的基本组成部分,也是Read /Write的基本单位。

Entry由两个部分组成:HLogKey和WALEdit。

HLogKey主要包含以下几个变量:

private byte [] encodedRegionName;

private byte [] tablename;

private long logSeqNum;// Time at which this edit was written.private long writeTime;

private byte clusterId;

logSeqNum是HLog 类的一个属性,AtomicLong类型。每写一个Entry就自动加1. 由于RS和HLog是一一对应的,所以logSeqNum是在RegionServer范围内的自增量。

WALEdit的主体是一个KeyValue的List。在旧的版本中WALEdit只包含一个KeyValue,然而新的版本可以包含多个KeyValue,而且这些KeyValue可以拥有不同的RowKey。

图5  HLog文件结构图

三、HBase预写日志(WAL)

WAL最重要的作用是灾难恢复,一旦服务器崩溃,通过重放log,我们可以恢复崩溃之前的数据。如果写入WAL失败,整个操作也将认为失败。

图6  WAL

基本流程:首先,客户端初始化一个可能对数据改动的操作,如put(Put),delete(Delete) 和 incrementColumnValue()。这些操作将被封装在一个KeyValue对象实例中,发送给HRegionServer。 一旦达到一定大小,HRegionServer 将其发送给HRegion。这个过程中,数据会首先会被写入WAL,之后将被写到实际存放数据的MemStore中。

HLog是实现WAL的类。一个HRegionServer对应一个HLog实例。当HRegion初始化时,HLog将作为一个参数传给HRegion的构造函数。

WAL中几个重要的类:

1.HLog

HLog最核心的是调用doWrite的append() 方法,任何对数据改动的操作都就将首先调用这个方法。

出于性能考虑,put(), delete() 和incrementColumnValue()可通过开关函数setWriteToWAL (boolean) 禁用WAL。运行MapReduce Job时,可通过关闭WAL获得性能提升。

HLog另一个重要特性是将通过sequence number追踪数据改变。它内部使用AtomicLong保证线程安全。

2.HLogKey

上一部分的存储格式中有提到,HLogKey包含的一些主要变量,主要用于记录Key/Value对的归属信息。

3.LogFlusher

数据以KeyValue形式到达HRegionServer,将写入WAL,之后写入一个SequenceFile。由于数据流在写入文件时经常会缓存以提高性能,因此,有时数据实际保存在内存中。

LogFlusher调用HLog.optionalSync(),后者根据hbase. regionserver. optionallogflushinterval (默认10秒)定期调用Hlog.sync()。HLog.doWrite()也根据hbase.regionserver.flushlogentries  (默认100秒)定期调用Hlog.sync()。Sync() 本身调用HLog.Writer.sync(),它由SequenceFileLogWriter实现。

4.LogRoller

Log的大小通过$HBASE_HOME/conf/hbase-site.xml 的hbase.regionserver.logroll.period限制,默认是一个小时。所以每60分钟,会打开一个新的log文件。久而久之,会有一大堆的文件需要维护。LogRoller主要完成日志的清理。

首先,LogRoller调用HLog.rollWriter(),定时滚动日志,之后,利用HLog.cleanOldLogs()可以清除旧的日志。它首先取得存储文件中的最大的sequence number,之后检查是否存在一个log所有的条目的”sequence number”均低于这个值,如果存在,将删除这个log。

5.Replay

旧日志往往由RegionServer崩溃产生。当HMaster启动或者检测到RegionServer崩溃,它将日志文件拆分为多份文件,存储在region所属的文件夹。之后,将日志重放。

重放过程:HRegionServer启动,打开所管辖的Region,检查是否存在剩余的log文件,如果存在,调用Store.doReconstructionLog()。重放一个日志只是简单地读入一个日志,将日志中的条目加入到Memstore中。最后,flush操作将Memstore中数据flush到硬盘中。

四、HBase索引

目前的HBase新版本没有实现二级索引,以前hbase的版本有过二级索引,实现时也是写写数据再写索引,索引放到后台队列中异步地写。实现最终一致。

HBase移走这块代码的一个原因就是索引到底落后数据多少时间是不确定的,特别是在异常的情况下。这样就导致在清理HLog时无法确定一个HLog是否真正全部写入数据了。

问题:为什么一个RegionServer对应一个HLog,而不是一个region对应于一个log file?

BigTable论文答:如果每一个”tablet”(对应于HBase的region)都提交一个日志文件,会需要并发写入大量的文件到GFS(对应HDFS),这样,根据每个GFS server所依赖的文件系统,写入不同的日志文件会造成大量的磁盘操作。

HBase依照这样的原则。在日志被回滚和安全删除之前,将会有大量的文件。如果改成一个region对应于一个文件,将会不好扩展,会引发问题。

hbase 预写日志_HBase存储结构相关推荐

  1. hbase 预写日志_HDInsight HBase 加速写入现已正式发布

    HDInsight HBase 加速写入现已正式发布. 要点 Apache HBase 和 Phoenix 的写入性能提升多达 9 倍. 非常适合 Azure Data Lake Storage Ge ...

  2. HBase预写日志WAL机制

    预写日志(Write-ahead log,WAL) 最重要的作用是灾难恢复,一旦服务器崩溃,通过重放log,我们可以恢复崩溃之前的数据.如果写入WAL失败,整个操作也将认为失败. 从上图看: 1 客户 ...

  3. Hbase 预写日志WAL处理源码分析之 LogCleaner

    Hlog WALs和oldWALs 这里先介绍一下Hlog失效和Hlog删除的规则 HLog失效:写入数据一旦从MemStore中刷新到磁盘,HLog(默认存储目录在/hbase/WALs下)就会自动 ...

  4. Hbase 预写日志WAL处理源码分析之 LogCleaner

    目录 Hlog  WALs和oldWALs 整体流程 HMaster 初始化 定时执行 LogCleaner 日志清理类 ReplicationLogCleaner 日志清理类 总结 Hlog  WA ...

  5. hbase记录日志wal_SQL Server事务日志–第1部分–日志结构和预写日志记录(WAL)算法

    hbase记录日志wal SQL Server transaction log is one of the most critical and in the same time one of the ...

  6. 数仓知识12:PostgreSQL预写日志(WAL)和逻辑解码方案

    目录 PostgreSQL预写日志(WAL) PostgreSQL逻辑解码(Logical Decoding) 逻辑解码方案研究分析 PostgreSQL预写日志(WAL) 从PostgreSQL 9 ...

  7. mysql的预写日志_编写数据库:第2部分-预写日志

    所以,您的数据不是很耐用... 在第1部分中,我使用gRPC和Go编写了一个非常简单的服务器,该服务器用于服务Get和Put请求内存中的映射.如果服务器退出,它将丢失所有数据,对于数据库,我必须承认这 ...

  8. hbase获取表信息_HBase的读写和javaAPI的使用

    一.hbase系统管理表 hbase:namespace,记录了hbase中所有namespace的信息 ,当前系统下有哪些namespace信息 scan 'hbase:namespace' hba ...

  9. 时序数据库的存储结构

    按series存储. 哈希取余 倒排索引:方便查询多条series. 符号表:存储将label排序,然后按序号索引获取,降低了存储开销,并且可以进行正则匹配. 正则匹配 block合并,主要是合并索引 ...

最新文章

  1. 喜欢绘画学的计算机,为什么有的人画画非常好却对计算机一窍不通
  2. Hibernate的increment主键生成机制带来的问题
  3. AbstractQueuedSynchronizer理解之一(ReentrantLock)
  4. hdu5184 给出(和)前半段问后面有多少种加括号方法使合法:类似卡特兰数+逆元模板...
  5. orcal 数据库 maven架构 ssh框架 的全xml环境模版 及常见异常解决
  6. AccuREST Stub Runner发布
  7. 《Python Cookbook 3rd》笔记(1.17):从字典中提取子集
  8. Debian7桌面屏蔽图标和右键菜单的解决方法。
  9. html加了文档声明之后页面错乱,为登陆页面扩展和配置设计导入程序
  10. [转]:xmake工程描述编写之选择性编译
  11. C#:设置CefSharp的一些参数,比如忽略安全证书
  12. 解决vscode卡顿,CPU占用过高的问题
  13. PIC单片机应用开发实践教程(五): 烧录器简介
  14. 收藏这16个顶级思维模型
  15. 利用python核算工资_年薪10w用Python,年薪50w利用Python
  16. 第62次上IM课(IMO71:How to use Adverb)
  17. cad管线交叉怎么画_CAD角度怎么画?我来告诉你!
  18. 不允许指针指向不完整的类类型
  19. UFPS入门: Unity FPS 教程
  20. 【本科生科研入门】如何整理个人大学生涯的成果?

热门文章

  1. 没有事情,错误1503_为什么依靠用户报告错误是您做过的最愚蠢的事情
  2. “ create-react-app”和创建React应用程序的未来
  3. Android获取通讯录速度,在android中获取联系人非常慢
  4. 单链表的增、删、查、改、python实现,超详细讲解
  5. 分布式系统架构以及 CAP 原理
  6. 怎样把输入的文本转换成html代码存入数据库啊
  7. 漫步数理统计十七——条件分布与期望
  8. web.config文件访问物理路径_计算机操作系统学习笔记(五):文件管理
  9. leetcode —— 938. 二叉搜索树的范围和
  10. Python 上下文管理器与with语句