123
返回列表 发新帖
楼主: 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
21#
 楼主| 发表于 2013-10-5 21:55 | 只看该作者
可以通过设置hbase.hstore.compaction.min.size(设定为该region的对应的memstore的flush size)和hbase.hstore.compaction.max.size(默认是Long.MAX_VALUE)来减少需要进行minor compaction的文件列表。任何大于最大的compaction size的文件都会被排除在外。最小的compaction size是作为一个阈值而不是一个限制,也就是说在达到单次compaction允许的文件数上限之前,那些小于该阈值的文件都会被包含在内。

图8.4展示了一个存储文件集合的实例。所有那些小于最小的compaction阈值的文件都被包含进了compaction中。

Figure 8.4. A set of store files showing the minimum compaction threshold



该算法会使用hbase.hstore.compaction.ratio (defaults to 1.2, or 120%)来确保总是能够选出足够的文件来进行compaction。根据该ratio,那些大小大于所有新于它的文件大小之和的文件也能够被选入。计算时,总是根据文件年龄从老到新进行选择,以保证老文件会先被compacted。通过上述一系列compaction相关的参数可以用来控制一次minor compaction到底选入多少个文件。

HBase支持的另外一种compaction是major compaction:它会将所有的文件compact成一个。该过程的运行是通过执行compaction检查自动确定的。当memstore被flush到磁盘,执行了compact或者major_compact命令或者产生了相关API调用时,或者后台线程的运行,就会触发该检查。Region server会通过CompactionChecker类实现来运行该线程。

使用道具 举报

回复
论坛徽章:
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
22#
 楼主| 发表于 2013-10-5 21:55 | 只看该作者
HBase支持的另外一种compaction是major compaction:它会将所有的文件compact成一个。该过程的运行是通过执行compaction检查自动确定的。当memstore被flush到磁盘,执行了compact或者major_compact命令或者产生了相关API调用时,或者后台线程的运行,就会触发该检查。Region server会通过CompactionChecker类实现来运行该线程。

如果用户调用了major_compact命令或者majorCompact()API调用,都会强制major compaction运行。否则,服务端会首先检查是否该进行major compaction,通过查看距离上次运行是否满足一定时间,比如是否达到24小时。

3.6 HFile格式

实际的文件存储是通过HFile类实现的,它的产生只有一个目的:高效存储HBase数据。它基于Hadoop的TFile类,模仿了Google的Bigtable架构中使用的SSTable格式。之前HBase采用的是Hadoop MapFile类,实践证明性能不够高。图8展示了具体的文件格式:

Figure 8.5. The HFile structure

使用道具 举报

回复
论坛徽章:
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
23#
 楼主| 发表于 2013-10-5 21:56 | 只看该作者
文件是变长的,定长的块只有file info和trailer这两部分。如图所示,trailer中包含指向其他blocks的指针。Trailer会被写入到文件的末尾。Index blocks记录了data和meta blocks的偏移。data和meta blocks实际上都是可选部分。但是考虑到HBase使用数据文件的方式,通常至少可以在文件中找到data blocks。

Block 大小是通过HColumnDescriptor配置的,而它是在table创建时由用户指定的,或者是采用了默认的标准值。实例如下:
  1. {NAME => 'testtable', FAMILIES => [{NAME => 'colfam1',
  2. BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '3',
  3. COMPRESSION \=> 'NONE', TTL => '2147483647', BLOCKSIZE => '65536',
  4. IN_MEMORY => 'false', BLOCKCACHE => 'true'}]}
复制代码
Block大小默认是64KB(or 65535 bytes)。下面是HFile JavaDoc中的注释:

“Minimum block size。通常的使用情况下,我们推荐将最小的block大小设为8KB到1MB。如果文件主要用于顺序访问,应该用大一点的block大小。但是,这会导致低效的随机访问(因为有更多的数据需要进行解压)。对于随机访问来说,小一点的block大小会好些,但是这可能需要更多的内存来保存block index,同时可能在创建文件时会变慢(因为我们必须针对每个data block进行压缩器的flush)。另外,由于压缩编码器的内部缓存机制的影响,最小可能的block大小大概是20KB-30KB”。

使用道具 举报

回复
论坛徽章:
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
24#
 楼主| 发表于 2013-10-6 11:29 | 只看该作者
每个block包含一个magic头,一系列序列化的KeyValue实例(具体格式参见 the section called “KeyValue Format”)。在没有使用压缩算法的情况下,每个block的大小大概就等于配置的block size。并不是严格等于,因为writer需要放下用户给的任何大小数据{!如配置的block size可能是64KB,但是用户给了一条1MB的记录,writer也得接受它}。即使是对于比较小的值,对于block size大小的检查也是在最后一个value写入后才进行的{!不是写入前检查,而是写入后检查},所以实际上大部分blocks大小都会比配置的大一些。另一方面,这样做也没什么坏处。

在使用压缩算法的时候,对block大小就更没法控制了。如果压缩编码器可以自行选择压缩的数据大小,它可能能获取更好的压缩率。比如将block size设为256KB,使用LZO压缩,为了适应于LZO内部buffer大小,它仍然可能写出比较小的blocks。

Writer并不知道用户是否选择了一个压缩算法:它只是对原始数据按照设定的block大小限制控制写出。如果使用了压缩,那么实际存储的数据会更小。这意味着对于最终的存储文件来说与不进行压缩时的block数量是相同的,但是总大小要小,因为每个block都变小了。

你可能还注意到一个问题:默认的HDFS block大小是64MB,是HFile默认的block大小的1000倍。这样,HBase存储文件块与Hadoop的块并不匹配。实际上,两者之间根本没有关系。HBase是将它的文件透明地存储到文件系统中的,只是HDFS也恰巧有一个blocks。HDFS本身并不知道HBase存储了什么,它看到的只是二进制文件。图8.6展示了HFile内容如何散布在HDFS blocks上。

Figure 8.6. The many smaller HFile blocks are transparently stored in two much larger HDFS blocks

使用道具 举报

回复
论坛徽章:
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
25#
 楼主| 发表于 2013-10-6 11:30 | 只看该作者
有时候需要绕过HBase直接访问HFile,比如健康检查,dump文件内容。HFile.main()提供了一些工具来完成这些事情:
  1. $
  2. ./bin/hbase org.apache.hadoop.hbase.io.hfile.HFile
  3. usage: HFile  [-a] [-b] [-e] [-f <arg>] [-k] [-m] [-p] [-r <arg>] [-v]
  4. -a,--checkfamily    Enable family check
  5. -b,--printblocks    Print block index meta data
  6. -e,--printkey       Print keys
  7. -f,--file <arg>     File to scan. Pass full-path; e.g.
  8.                      hdfs://a:9000/hbase/.META./12/34
  9. -k,--checkrow       Enable row order check; looks for out-of-order keys
  10. -m,--printmeta      Print meta data of file
  11. -p,--printkv        Print key/value pairs
  12. -r,--region <arg>   Region to scan. Pass region name; e.g. '.META.,,1'
  13. -v,--verbose        Verbose output; emits file and meta data delimiters
复制代码
Here is an example of what the output will look like (shortened):
  1. $
  2. ./bin/hbase org.apache.hadoop.hbase.io.hfile.HFile -f \
  3. /hbase/testtable/de27e14ffc1f3fff65ce424fcf14ae42/colfam1/2518469459313898451 \

  4. -v -m -p
  5. Scanning -> /hbase/testtable/de27e14ffc1f3fff65ce424fcf14ae42/colfam1/2518469459313898451
  6. K: row-550/colfam1:50/1309813948188/Put/vlen=2 V: 50
  7. K: row-550/colfam1:50/1309812287166/Put/vlen=2 V: 50
  8. K: row-551/colfam1:51/1309813948222/Put/vlen=2 V: 51
  9. K: row-551/colfam1:51/1309812287200/Put/vlen=2 V: 51
  10. K: row-552/colfam1:52/1309813948256/Put/vlen=2 V: 52
  11. ...
  12. K: row-698/colfam1:98/1309813953680/Put/vlen=2 V: 98
  13. K: row-698/colfam1:98/1309812292594/Put/vlen=2 V: 98
  14. K: row-699/colfam1:99/1309813953720/Put/vlen=2 V: 99
  15. K: row-699/colfam1:99/1309812292635/Put/vlen=2 V: 99
  16. Scanned kv count -> 300
  17. Block index size as per heapsize: 208
  18. reader=/hbase/testtable/de27e14ffc1f3fff65ce424fcf14ae42/colfam1/ \
  19. 2518469459313898451, compression=none, inMemory=false, \
  20. firstKey=row-550/colfam1:50/1309813948188/Put, \
  21. lastKey=row-699/colfam1:99/1309812292635/Put, avgKeyLen=28, avgValueLen=2, \
  22. entries=300, length=11773
  23. fileinfoOffset=11408, dataIndexOffset=11664, dataIndexCount=1, \
  24. metaIndexOffset=0, metaIndexCount=0, totalBytes=11408, entryCount=300, \
  25. version=1
  26. Fileinfo:
  27. MAJOR_COMPACTION_KEY = \xFF
  28. MAX_SEQ_ID_KEY = 2020
  29. TIMERANGE = 1309812287166....1309813953720
  30. hfile.AVG_KEY_LEN = 28
  31. hfile.AVG_VALUE_LEN = 2
  32. hfile.COMPARATOR = org.apache.hadoop.hbase.KeyValue$KeyComparator
  33. hfile.LASTKEY = \x00\x07row-699\x07colfam199\x00\x00\x010\xF6\xE5|\x1B\x04
  34. Could not get bloom data from meta block
复制代码

使用道具 举报

回复
论坛徽章:
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
26#
 楼主| 发表于 2013-10-6 11:31 | 只看该作者
第一部分是序列化的KeyValue实例的实际数据。第二部分除了trailer block的细节信息外,还dump出了内部的HFile.Reader属性。最后一部分,以”FileInfo”开头的,是file info block的值。

提供的这些信息是很有价值的,比如可以确定一个文件是否进行了压缩,采用的压缩方式。它也能告诉用户存储了多少个cell,key和value的平均大小是多少。在上面的例子中,key的长度比value的长度大很多。这是由于KeyValue类存储了很多额外数据,下面会进行解释。

3.7 KeyValue格式

实际上HFile中的每个KeyValue就是一个简单的允许对内部数据进行zero-copy访问的底层字节数组,包含部分必要的解析。图8.7展示了内部的数据格式。
Figure 8.7. The KeyValue format

使用道具 举报

回复
论坛徽章:
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
27#
 楼主| 发表于 2013-10-6 11:31 | 只看该作者
该结构以两个标识了key和value部分的大小的定长整数开始。通过该信息就可以在数组内进行一些操作,比如忽略key而直接访问value。如果要访问key部分就需要进一步的信息。一旦解析成一个KeyValue Java实例,用户就可以对内部细节信息进行访问,参见the section called “The KeyValue Class”。

在上面的例子中key之所以比value长,就是由于key所包含的这些fields造成的:它包含一个cell的完整的各个维度上的信息:row key,column family name,column qualifier等等。在处理小的value值时,要尽量让key很小。选择一个短的row和column key(1字节family name,同时qualifier也要短)来控制二者的大小比例。

另一方面,压缩也有助于缓解这种问题。因为在有限的数据窗口内,如果包含的都是很多重复性的数据那么压缩率会比较高。同时因为存储文件中的KeyValue都是排好序的,这样就可以让类似的key靠在一起(在使用多版本的情况下,value也是这样的,多个版本的value也会是比较类似的)。

使用道具 举报

回复
论坛徽章:
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
28#
 楼主| 发表于 2013-10-6 11:31 | 只看该作者
over.

使用道具 举报

回复
论坛徽章:
5
2013年新春福章
日期:2013-02-25 14:51:24优秀写手
日期:2013-12-20 06:00:11技术图书徽章
日期:2014-01-26 14:31:292014年新春福章
日期:2014-02-18 16:43:09马上有钱
日期:2014-02-18 16:43:09
29#
发表于 2013-10-8 22:03 | 只看该作者
nice~

使用道具 举报

回复
论坛徽章:
3
2014年新春福章
日期:2014-02-18 16:50:09马上有车
日期:2014-02-18 16:50:09优秀写手
日期:2014-03-12 06:00:13
30#
发表于 2013-10-20 14:54 | 只看该作者
厉害厉害,等对hbase再熟点之后再自己看

使用道具 举报

回复

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

本版积分规则 发表回复

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