12
返回列表 发新帖
楼主: jieforest

HBase架构(中)

[复制链接]
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
11#
 楼主| 发表于 2013-10-9 12:24 | 只看该作者
为了与其他日志文件的split输出进行区分,该路径已经包含了日志文件名,因该过程可能是并发执行的。同时路径也包含了table名称,region名称(hash值),以及recovered.edits目录。最后,split文件的名称就是针对相应的region的第一个修改操作的序列号。

.corrupt目录包含那些无法被解析的日志文件。它会受hbase.hlog.split.skip.errors属性影响,如果设为true,意味着当无法从日志文件中读出任何修改操作时,会将该文件移入.corrupt目录。如果设为false,那么此时会抛出一个IOExpectation,同时会停止整个的log splitting过程。

一旦log被成功的splitting后,那么每个regions对应的文件就会被移入实际的region目录下。对于该region来说它的恢复工作现在才就绪。这也是为什么splitting必须要拦截那些受影响的regions的打开操作的原因,因为它必须要将那些pending的修改操作进行replay。

1.7.3 Edits Recovery

当一个region被打开,要么是因为集群启动,要么是因为它从一个region server移到了另一个。它会首先检查recovered.edits目录是否存在,如果该目录存在,那么它会打开目录下的文件,开始读取文件内的修改操作。文件会根据它们的名称(名称中含有序列号)排序,这样region就可以按顺序恢复这些修改操作。

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
12#
 楼主| 发表于 2013-10-9 12:24 | 只看该作者
那些序列号小于等于已经序列化到磁盘存储中的修改操作将会被忽略,因为该修改操作已经被apply了。其他的修改操作将会被apply到该region对应的memstore中以恢复之前的状态。最后,会将memstore的内容强制flush到磁盘。

一旦recovered.edits中的文件被读取并持久化到磁盘后,它们就会被删除。如果某个文件无法读取,那么会根据hbase.skip.errors来确定如何处理:默认值是false,会导致整个region恢复过程失败。如果设为true,那么该文件会被重命名为原始名称+” .<currentTimeMillis>”。不管是哪种情况,你都需要仔细检查你的log文件确认问题产生的原因及如何fix。

1.8 持久性

无论底层采用了什么稀奇古怪的算法,用户都希望可以依赖系统来存储他们所有的数据。目前HBase允许用户根据需要调低log flush的时间或者是每次修改操作都进行sync。但是当存储数据的stream被flush后,数据是否真的写入到磁盘了呢?我们会讨论下一些类似于fsync类型的问题。当前的HBase主要依赖于底层的HDFS进行持久化。

比较明确的一点是系统通过log来保证数据安全。一个log文件最好能在长时间内(比如1小时)一直处于打开状态。当数据到达时,一个新的key/value对会被写入到SequenceFile,同时间或地被flush到磁盘。但是Hadoop并不是这样工作的,它之前提供的API,通常都是打开一个文件,写入大量数据,立即关闭,然后产生出一个可供其它所有人读取的不可变文件。只有当文件关闭之后,对其他人来说它才是可见的可读的。如果在写入数据到文件的过程中进程死掉通常都会有数据丢失。为了能够让日志的读取可以读到服务器crash时刻最后写入的那个位置,或者是尽可能接近该位置,这就需要一个feature:append支持。

插曲:HDFS append,hflush,hsync,sync…

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
13#
 楼主| 发表于 2013-10-9 12:25 | 只看该作者
在HADOOP-1700就已经提出,在Hadoop 0.19.0中,用来解决该问题的代码就已提交。但是实际情况是这样的:Hadoop 0.19.0里的append实现比较糟糕,以至于hadoop fsck会对HBase打开的那些日志文件向HDFS报告一个数据损坏错误。

所以在该问题又在HADOOP-4379即HDFS-200被重新提出,之后实现了一个syncFs()函数让对于一个文件的变更更可靠。有段时间我们通过客户端代码来检查Hadoop版本是否包含了该API。后来就是HDFS-265,又重新回顾了append的实现思路。同时也引入了hsync()和hflush()两个syncable接口。

需要注意的是SequenceFile.Writer.sync()跟我们这里所说的sync方法不是一个概念:SequenceFile中sync是用来写入一个同步标记,用于帮助后面的读取操作或者数据恢复。

HBase目前会检测底层的Hadoop库是否支持syncFs()或者hflush()。如果在log writer中一个sync()调用被触发,它就会调用syncFs()或者hflush()中的一个方法—或者是不调用任何方法,如果HBase工作在一个non-durable setup上的话。Sync()将会使用流水式的write过程来保证日志文件中的修改操作的持久性。当服务器crash的时候,系统就能安全地读取被抛弃的日志文件更新到最后的修改操作。

大体上,在Hadoop 0.21.0版本之前,经常会碰到数据丢失。具体细节参见the section called “Hadoop”。

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
14#
 楼主| 发表于 2013-10-9 12:25 | 只看该作者
over.

使用道具 举报

回复
论坛徽章:
0
15#
发表于 2013-10-20 16:49 | 只看该作者
真不错啊

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表