楼主: 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-3 20:42 | 只看该作者
下面是上述操作完成之后,HBase根目录下的内容:

  1. $
  2. $HADOOP_HOME/bin/hadoop dfs -lsr /hbase
  3.        ...
  4.        0 /hbase/.logs
  5.        0 /hbase/.logs/foo.internal,60020,1309812147645
  6.        0 /hbase/.logs/foo.internal,60020,1309812147645/ \
  7. foo.internal%2C60020%2C1309812147645.1309812151180
  8.        0 /hbase/.oldlogs
  9.       38 /hbase/hbase.id
  10.        3 /hbase/hbase.version
  11.        0 /hbase/testtable
  12.      487 /hbase/testtable/.tableinfo
  13.        0 /hbase/testtable/.tmp
  14.        0 /hbase/testtable/1d562c9c4d3b8810b3dbeb21f5746855
  15.        0 /hbase/testtable/1d562c9c4d3b8810b3dbeb21f5746855/.oldlogs
  16.      124 /hbase/testtable/1d562c9c4d3b8810b3dbeb21f5746855/.oldlogs/ \
  17. hlog.1309812163957
  18.      282 /hbase/testtable/1d562c9c4d3b8810b3dbeb21f5746855/.regioninfo
  19.        0 /hbase/testtable/1d562c9c4d3b8810b3dbeb21f5746855/.tmp
  20.        0 /hbase/testtable/1d562c9c4d3b8810b3dbeb21f5746855/colfam1
  21.    11773 /hbase/testtable/1d562c9c4d3b8810b3dbeb21f5746855/colfam1/ \
  22. 646297264540129145
  23.        0 /hbase/testtable/66b4d2adcc25f1643da5e6260c7f7b26
  24.      311 /hbase/testtable/66b4d2adcc25f1643da5e6260c7f7b26/.regioninfo
  25.        0 /hbase/testtable/66b4d2adcc25f1643da5e6260c7f7b26/.tmp
  26.        0 /hbase/testtable/66b4d2adcc25f1643da5e6260c7f7b26/colfam1
  27.     7973 /hbase/testtable/66b4d2adcc25f1643da5e6260c7f7b26/colfam1/ \
  28. 3673316899703710654
  29.        0 /hbase/testtable/99c0716d66e536d927b479af4502bc91
  30.      297 /hbase/testtable/99c0716d66e536d927b479af4502bc91/.regioninfo
  31.        0 /hbase/testtable/99c0716d66e536d927b479af4502bc91/.tmp
  32.        0 /hbase/testtable/99c0716d66e536d927b479af4502bc91/colfam1
  33.     4173 /hbase/testtable/99c0716d66e536d927b479af4502bc91/colfam1/ \
  34. 1337830525545548148
  35.        0 /hbase/testtable/d240e0e57dcf4a7e11f4c0b106a33827
  36.      311 /hbase/testtable/d240e0e57dcf4a7e11f4c0b106a33827/.regioninfo
  37.        0 /hbase/testtable/d240e0e57dcf4a7e11f4c0b106a33827/.tmp
  38.        0 /hbase/testtable/d240e0e57dcf4a7e11f4c0b106a33827/colfam1
  39.     7973 /hbase/testtable/d240e0e57dcf4a7e11f4c0b106a33827/colfam1/ \
  40. 316417188262456922
  41.        0 /hbase/testtable/d9ffc3a5cd016ae58e23d7a6cb937949
  42.      311 /hbase/testtable/d9ffc3a5cd016ae58e23d7a6cb937949/.regioninfo
  43.        0 /hbase/testtable/d9ffc3a5cd016ae58e23d7a6cb937949/.tmp
  44.        0 /hbase/testtable/d9ffc3a5cd016ae58e23d7a6cb937949/colfam1
  45.     7973 /hbase/testtable/d9ffc3a5cd016ae58e23d7a6cb937949/colfam1/ \
  46. 4238940159225512178

复制代码
注:由于空间的限制,我们对输出内容进行了删减,只留下了文件大小和名称部分。你自己在集群上运行命令时可以看到更多的细节信息。
文件可以分成两类:一是直接位于HBase根目录下面的那些,还有就是位于table目录下面的那些。

使用道具 举报

回复
论坛徽章:
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-3 20:43 | 只看该作者
3.3.1 Root Level Files

第一类文件是由HLog实例处理的write-ahead log文件,这些文件创建在HBase根目录下一个称为.logs的目录。Logs目录下包含针对每个HRegionServer的子目录。在每个子目录下,通常有几个HLog文件(因为log的切换而产生)。来自相同region server的regions共享同一系列的HLog文件。

一个有趣的现象是log file大小被报告为0。对于最近创建的文件通常都是这样的,因为HDFS正使用一个内建的append支持来对文件进行写入,同时只有那些完整的blocks对于读取者来说才是可用的—包括hadoop dfs -lsr命令。尽管put操作的数据被安全地持久化,但是当前被写入的log文件大小信息有些轻微的脱节。

等一个小时log文件切换后,这个时间是由配置项:hbase.regionserver.logroll.period控制的(默认设置是60分钟),你就能看到现有的log文件的正确大小了,因为它已经被关闭了,而且HDFS可以拿到正确的状态了。而在它之后的那个新log文件大小又变成0了:
  1. 249962 /hbase/.logs/foo.internal,60020,1309812147645/ \
  2. foo.internal%2C60020%2C1309812147645.1309812151180
  3.        0 /hbase/.logs/foo.internal,60020,1309812147645/ \
  4. foo.internal%2C60020%2C1309812147645.1309815751223
复制代码

使用道具 举报

回复
论坛徽章:
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-3 20:44 | 只看该作者
当日志文件不再需要时,因为现有的变更已经持久化到存储文件中了,它们就会被移到HBase根目录下的.oldlogs目录下。这是在log文件达到上面的切换阈值时触发的。老的日志文件默认会在十分钟后被master删除,通过hbase.master.logcleaner.ttl设定。Master默认每分钟会对这些文件进行检查,可以通过hbase.master.cleaner.interval设定。

hbase.id和hbase.version文件包含集群的唯一ID和文件格式版本号:
  1. $
  2. hadoop dfs -cat /hbase/hbase.id
  3. $e627e130-0ae2-448d-8bb5-117a8af06e97
  4. $
  5. hadoop dfs -cat /hbase/hbase.version
  6. 7
复制代码
它们通常是在内部使用因此通常不用关心这两个值。此外,随着时间的推进还会产生一些root级的目录。splitlog和.corrupt目录分别是log split进程用来存储中间split文件的和损坏的日志文件的。比如:
  1. 0 /hbase/.corrupt
  2.       0 /hbase/splitlog/foo.internal,60020,1309851880898_hdfs%3A%2F%2F \
  3. localhost%2Fhbase%2F.logs%2Ffoo.internal%2C60020%2C1309850971208%2F \
  4. foo.internal%252C60020%252C1309850971208.1309851641956/testtable/ \
  5. d9ffc3a5cd016ae58e23d7a6cb937949/recovered.edits/0000000000000002352
复制代码

使用道具 举报

回复
论坛徽章:
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-4 10:16 | 只看该作者
上面的例子中没有损坏的日志文件,只有一个分阶段的split文件。关于log splitting过程参见the section called “Replay”。

3.3.2 Table Level Files

HBase中的每个table都有它自己的目录,位于HBase根目录之下。每个table目录包含一个名为.tableinfo的顶层文件,该文件保存了针对该table的HTableDescriptor(具体细节参见the section called “Tables”)的序列化后的内容。包含了table和column family schema信息,同时可以被读取,比如通过使用工具可以查看表的定义。.tmp目录包含一些中间数据,比如当.tableinfo被更新时该目录就会被用到。

3.3.3 Region Level Files

在每个table目录内,针对表的schema中的每个column family会有一个单独的目录。目录名称还包含region name的MD5 hash部分。比如通过master的web UI,点击testtable链接后,其中User Tables片段的内容如下:
  1. testtable,row-500,1309812163930.d9ffc3a5cd016ae58e23d7a6cb937949.
复制代码

使用道具 举报

回复
论坛徽章:
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
15#
 楼主| 发表于 2013-10-4 10:16 | 只看该作者
MD5 hash部分是”d9ffc3a5cd016ae58e23d7a6cb937949”,它是通过对region name的剩余部分进行编码生成的。比如”testtable,row-500,1309812163930”。尾部的点是整个region name的一部分:它表示这是一种包含hash的新风格的名称。在HBase之前的版本中,region name中并不包含hash。

注:需要注意的是-ROOT-和.META.元数据表仍然采用老风格的格式,比如它们的region name不包含hash,因此结尾就没有那个点。

.META.,,1.1028785192

对于存储在磁盘上的目录中的region names编码方式也是不同的:它们使用Jenkins hash来对region name编码。

Hash是用来保证region name总是合法的,根据文件系统的规则:它们不能包含任何特殊字符,比如”/”,它是用来分隔路径的。这样整个的region文件路径就是如下形式:
  1. /<hbase-root-dir>/<tablename>/<encoded-regionname>/<column-family>/<filename>
复制代码
在每个column-family下可以看到实际的数据文件。文件的名字是基于Java内建的随机数生成器产生的任意数字。代码会保证不会产生碰撞,比如当发现新生成的数字已经存在时,它会继续寻找一个未被使用的数字。

使用道具 举报

回复
论坛徽章:
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
16#
 楼主| 发表于 2013-10-4 10:17 | 只看该作者
Region目录也包含一个.regioninfo文件,包含了对应的region的HRegionInfo的序列化信息。类似于.tableinfo,它也可以通过外部工具来查看关于region的相关信息。hbase hbck工具可以用它来生成丢失的table条目元数据。

可选的.tmp目录是按需创建地,用来存放临时文件,比如某个compaction产生的重新写回的文件。一旦该过程结束,它们会被立即移入region目录。在极端情况下,你可能能看到一些残留文件,在region重新打开时它们会被清除。

在write-ahead log replay期间,任何尚未提交的修改会写入到每个region各自对应的文件中。这是阶段1(看下the section called “Root Level Files”中的splitlog目录),之后假设log splitting过程成功完成-然后会将这些文件原子性地move到recovered.edits目录下。当该region被打开时,region server能够看到这些recovery文件然后replay相应的记录。

Split vs. Split

在write-ahead log的splitting和regions的splitting之间有明显的区别。有时候,在文件系统中很难区分文件和目录的不同,因为它们两个都涉及到了splits这个名词。为避免错误和混淆,确保你已经理解了二者的不同。

使用道具 举报

回复
论坛徽章:
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
17#
 楼主| 发表于 2013-10-4 10:17 | 只看该作者
一旦一个region因为大小原因而需要split,一个与之对应的splits目录就会创建出来,用来筹划产生两个子regions。如果这个过程成功了—通常只需要几秒钟或更少—之后它们会被移入table目录下用来形成两个新的regions,每个代表原始region的一半。

换句话说,当你发现一个region目录下没有.tmp目录,那么说明目前它上面没有compaction在执行。如果也没有recovered.edits目录,那么说明目前没有针对它的write-ahead log replay。

注:在HBase 0.90.x版本之前,还有一些额外的文件,目前已被废弃了。其中一个是oldlogfile.log,该文件包含了对于相应的region已经replay过的write-ahead log edits。oldlogfile.log.old(加上一个.old扩展名)表明在将新的log文件放到该位置时,已经存在一个oldlogfile.log。另一个值得注意的是在老版HBase中的compaction.dir,现在已经被.tmp目录替换。

本节总结了下HBase根目录下的各种目录所包含的一系列内容。有很多是由region split过程产生的中间文件。在下一节里我们会分别讨论。

3.4 Region Splits

当一个region内的存储文件大于hbase.hregion.max.filesize(也可能是在column family级别上配置的)的大小时,该region就需要split为两个。起始过程很快就完成了,因为系统只是简单地为新regions(也称为daughters)创建两个引用文件,每个只持有原始region的一半内容。

Region server通过在parent region内创建splits目录来完成。之后,它会关闭该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
18#
 楼主| 发表于 2013-10-4 10:18 | 只看该作者
Region server然后开始准备生成新的子regions(使用多线程),通过在splits目录内设置必要的文件结构。里面包括新的region目录及引用文件。如果该过程成功完成,它就会把两个新的region目录移到table目录下。.META.table会进行更新,指明该region已经被split,以及子regions分别是谁。这就避免了它被意外的重新打开。实例如下:
  1. ow: testtable,row-500,1309812163930.d9ffc3a5cd016ae58e23d7a6cb937949.
  2.   column=info:regioninfo, timestamp=1309872211559, value=REGION => {NAME => \
  3.     'testtable,row-500,1309812163930.d9ffc3a5cd016ae58e23d7a6cb937949. \
  4.      TableName => 'testtable', STARTKEY => 'row-500', ENDKEY => 'row-700', \
  5.      ENCODED => d9ffc3a5cd016ae58e23d7a6cb937949, OFFLINE => true,
  6.      SPLIT => true,}
  7.                                                                                    
  8.   column=info:splitA, timestamp=1309872211559, value=REGION => {NAME => \
  9.     'testtable,row-500,1309872211320.d5a127167c6e2dc5106f066cc84506f8. \
  10.     TableName => 'testtable', STARTKEY => 'row-500', ENDKEY => 'row-550', \
  11.     ENCODED => d5a127167c6e2dc5106f066cc84506f8,}                                                                                                                       
  12.   column=info:splitB, timestamp=1309872211559, value=REGION => {NAME => \
  13.     'testtable,row-550,1309872211320.de27e14ffc1f3fff65ce424fcf14ae42. \
  14.     TableName => [B@62892cc5', STARTKEY => 'row-550', ENDKEY => 'row-700', \
  15.     ENCODED => de27e14ffc1f3fff65ce424fcf14ae42,}
复制代码
可以看到原始的region在”row-550”处被分成了两个regions。在info:regioninfo中的”SPLIT=>true”表面该region目前已经分成了两个regions:splitA和splitB。

使用道具 举报

回复
论坛徽章:
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
19#
 楼主| 发表于 2013-10-5 21:53 | 只看该作者
引用文件的名称是另一个随机数,但是会使用它所引用的region的hash作为后缀,比如:
  1. /hbase/testtable/d5a127167c6e2dc5106f066cc84506f8/colfam1/ \
  2. 6630747383202842155.d9ffc3a5cd016ae58e23d7a6cb937949
复制代码
该引用文件代表了hash值为” d9ffc3a5cd016ae58e23d7a6cb937949”的原始region的一半内容。引用文件仅仅有很少量的信息:原始region split点的key,引用的是前半还是后半部分。这些引用文件会通过HalfHFileReader类来读取原始region的数据文件。

现在两个子regions已经就绪,同时将会被同一个服务器并行打开。现在需要更新.META.table,将这两个regions作为可用region对待—看起来就像是完全独立的一样。同时会启动对这两个regions的compaction—此时会异步地将存储文件从原始region真正地写成两半,来取代引用文件。这些都发生在子regions的.tmp目录下。一旦文件生成完毕,它们就会原子性地替换掉之前的引用文件。

原始region最终会被清除,意味着它会从.META.table中删除,它的所有磁盘上的文件也会被删除。最后,master会收到关于该split的通知,它可以因负载平衡等原因将这些新的regions移动到其他服务器上。

使用道具 举报

回复
论坛徽章:
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
20#
 楼主| 发表于 2013-10-5 21:54 | 只看该作者
ZooKeeper支持

Split中的所有相关步骤都会通过Zookeeper进行追踪。这就允许在服务器出错时,其他进程可以知晓该region的状态。

3.5 Compactions

存储文件处于严密的监控之下,这样后台进程就可以保证它们完全处于控制之中。Memstores的flush操作会逐步的增加磁盘上的文件数目。当数目足够多的时候,compaction进程会将它们合并成更少但是更大的一些文件。当这些文件中的最大的那个超过设置的最大存储文件大小时会触发一个region split过程。(see the section called “Region Splits”).

有两种类型的Compactions:minor和major。Minor compaction负责将一些小文件合并成更大的一个文件。合并的文件数通过hbase.hstore.compaction.min属性进行设置(以前该参数叫做hbase.hstore.compactionThreshold,尽管被弃用了但是目前还支持该参数)。默认该参数设为3,同时该参数必须>=2。如果设得更大点,会延迟minor compaction的发生,但是一旦它启动也会需要更多的资源和更长的时间。一个minor compaction所包含的最大的文件数被设定为10,可以通过hbase.hstore.compaction.max进行配置。

使用道具 举报

回复

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

本版积分规则 发表回复

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