9.7 Region(部分)

Region是表的可用性和分布性的基本元素,每个列族包含在一个Store中,下面是这个主题的层次结构:

Table       (HBase table)
    Region       (Regions for the table)
         Store          (Store per ColumnFamily for each Region for the table)
              MemStore           (MemStore for each Store for each Region for the table)
              StoreFile          (StoreFiles for each Store for each Region for the table)
                    Block             (Blocks within a StoreFile within a Store for each Region for the table)
 

为了描述HBase文件存入HDFS时的样子,可参看Section 13.7.2, “Browsing HDFS for HBase Objects”。

总体来讲,HBase是为每个服务器上承载相对较少的region的使用场景设计的。5-20Gb vs. 20-200

9.7.1 为什么不能有太多region?

通常,很多原因使你想把region数降低。一般每个服务器承载100个左右的region是最好的,以下是一些希望保持region较少的原因:

  • MSLAB每个memstore需要2MB,即每个region的每个列族为2MB。1000个有两个列族的region需要使用3.9GB大小的堆,而且还不包括存储的数据。2MB这个值是可以配置的。
  • 如果你以同样的几率填充所有的region,全局内存使用量使得它在进行太多region合并时被迫进行小量刷新。重写多次数据是你最不想发生的事情。一个例子是,当写平均地写1000个region时,考虑全局内存的最低使用量为5GB。一旦达到5GB,它就被迫刷新成一个最大的region,从这点上看,几乎每个都有5MB的数据要刷新。之后插入5MB的数据,这将刷新另一个数据量稍微比5MB大的region。这是region数目的主要限制因子。
  • 主服务器对region数目非常敏感,它需要花费大量的时间分派或移动它们。这会加重ZK的负担。
  • 在HBase的旧版本中,一个RegionServer上的region过多会使store文件的索引增多,增加堆的使用量,带来潜在的OOM危险。
另一个问题是region数目对mapreduce作业的影响,通常一个region对应一个mapper。因此每个服务器上5个region可能无法满足mapreduce作业的需求,但1000个又太多。

9.7.2 Region-RegionServer分配

这个部分将描述region是如何分配到regionserver上的。

9.7.2.1 启动

当HBase开启region是会按如下步骤进行分配:

  1. Master在启动时调用AssignmentManager。
  2. AssignmentManager查看META表中已有的的region的分配信息。
  3. 如果region的分配仍然有效,那么保持原来的分配方案。
  4. 如果分配无效,则调用LoadBalancerFactory重新分配region。DefaultLoadBalancer将随机将region分配给RegionServer。
  5. META更新RegionServer的分配(如果需要)和RegionServer上启动region的起始码(RegionServer进程启动的时间)。

9.7.2.2 故障恢复

当RegionServer发生故障时:

  1. region由于RegionServer的关闭变的立即不可用了。
  2. Master将探测到RegionServer发生故障了。
  3. region的分配被视为无效的,并像启动时那样重新被分配。

9.7.2.3 Region负载均衡

Region会周期性地被LoadBalancer移动。

9.7.3 Region-RegionServer的本地性

随着时间的推移,Region-RegionServer的本地性会通过HDFS的块副本而达到。HDFS默认通过以下步骤选择写副本的位置:

  1. 第一个副本写在本地节点。
  2. 第二个副本随机写到令一个机架上的节点中。
  3. 第三副本写在同一个机架上上随机选择的另一个节点上。
  4. 其余副本会被随机写到集群上。
因此,HBase在一段时间的刷新和合并之后会最终达到本地化。在进行RegionServer进行故障恢复时,RegionServer可能回见region写在非本地的StoreFiles中,当新数据写入region时,或因为表被合并或StoreFiles被重写时,他们对于RegionServer而言将成为本地的。

更多信息,可以参考HDFS Architecture和HBase and HDFS locality。

9.7.4 Region分裂

当region大小达到配置的阀值时region就会分裂。下面将长话短说,详细信息可以参考 Apache HBase Region Splitting and Merging。

分裂是独立进行的,Master并不参与。RegionServer分裂一个region,会是原region下线,之后将region的两个子女region写入META,再在承载原region的RegionServer上开启子女region,并将分裂信息报告给Master。

9.7.4.1 自定义分裂策略

默认的分裂策略可通过RegionSplitPolicy(HBase 0.94+)重写,通常自定义的分裂策略会继承于默认的分裂策略ConstantSizeRegionSplitPolicy。

可以通过HBaseConfiguration设置全局的分裂策略,或针对某个表设置:

HTableDescriptor myHtd = ...;
myHtd.setValue(HTableDescriptor.SPLIT_POLICY, MyCustomSplitPolicy.class.getName());

9.7.5 在线region合并

Master和RegionServer都会参与在线region合并。客户端会向Master发送合并RPC,之后Master会将region移动到承载region较多的那个RegionServer,最后会发送合并指令给每个region服务器,并合并region。与region分裂的过程相似,region也是运行在RegionServer本地的,先将region下线,之后合并文件系统上的两个region,自动从META删除掉合并的region,再将合并后的region添加到META中,再开启这个region,最后将合并信息发送给Master。

使用HBase shell进行region合并的例子如下:

$ hbase> merge_region 'ENCODED_REGIONNAME', 'ENCODED_REGIONNAME'
          hbase> merge_region 'ENCODED_REGIONNAME', 'ENCODED_REGIONNAME', true

这是一个异步操作。

9.7.6 存储

一个存储包含了一个内存存储和若干个文件存储,一个存储可以定位到一个列族的一个region。

9.7.6.1 MemStore

MemStores是Store中的内存Store,可以进行修改操作。修改的内容是KeyValues。当请求flush时,现有的memstore会生成快照,然后清空。在执行快照的时候,HBase会继续接收修改操作,保存在memstore外面,直到快照完成。

9.7.6.2 StoreFile(HFile)

StoreFiles是数据存储的地方。

9.7.6.2.1 HFile的格式

hfile文件格式是基于BigTable [2006]论文中的SSTable。构建在Hadoop的tfile上面(直接使用了tfile的单元测试和压缩工具)。 Schubert Zhang 的博客HFile: A Block-Indexed File Format to Store Sorted Key-Value Pairs详细介绍了HBases的hfile。Matteo Bertozzi也做了详细的介绍HBase I/O: HFile

9.7.6.2.2 HFile工具

要想看到hfile内容的文本化版本,你可以使用org.apache.hadoop.hbase.io.hfile.HFile 工具。可以这样用:

$ ${HBASE_HOME}/bin/hbase org.apache.hadoop.hbase.io.hfile.HFile  

例如,你想看文件hdfs://10.81.47.41:9000/hbase/TEST/1418428042/DSMP/4759508618286845475的内容, 就执行如下的命令:

 $ ${HBASE_HOME}/bin/hbase org.apache.hadoop.hbase.io.hfile.HFile -v -f hdfs://10.81.47.41:9000/hbase/TEST/1418428042/DSMP/4759508618286845475  

如果你没有输入-v,就仅仅能看到一个hfile的汇总信息。其他功能的用法可以看HFile的文档。

9.7.6.2.3 StoreFiles在HDFS上的目录结构

参考Section 13.7.2, “Browsing HDFS for HBase Objects”。

9.7.6.3 块

StoreFiles是由块组成的,块大小以列族为单元进行配置。压缩是在StoreFiles中块级别上发生的。

9.7.6.4 键值

KeyValue类是HBase存储的核心。KeyValue包装着一个字节数组、位移、被译为KeyValue的内容已经过的数组的长度。

字节数组内KeyValue的格式为:

  • keylength
  • valuelength
  • key
  • value
键呗进一步分解为:

  • rowlength
  • row(如rowkey)
  • columnfamilylength
  • columnfamily
  • columnsqualifier
  • timestamp
  • keytype(如Put, Delete, DeleteColumn, DeleteFamily)
KeyValue实例不会跨块进行分割。例如,一个8MB的KeyValue,即使在块大小为65KB时,也会被读入一个连续的块中。

9.7.6.4.1 例子

为了强调上述观点,检验Puts同一行的两个不同的列时发生什么,举例如下:

  • #1: rowkey=row1, cf:attr1=value1
  • #2: rowkey=row1, cf:attr2=value2
虽然是同一行,但会为每个列生成一个KeyValue:

#1的键的组成 :

  • rowlength ------------> 4
  • row -----------------> row1
  • columnfamilylength ---> 2
  • columnfamily --------> cf
  • columnqualifier ------> attr1
  • timestamp -----------> server time of Put
  • keytype -------------> Put
#2 的键的组成

  • rowlength ------------> 4
  • row -----------------> row1
  • columnfamilylength ---> 2
  • columnfamily --------> cf
  • columnqualifier ------> attr1
  • timestamp -----------> server time of Put
  • keytype -------------> Put
了解行键、列族和列在KeyValue中的组成是非常关键的,这些修饰符越大,KeyValue就越大。

9.7.6.5 紧缩

有两种类型的紧缩:次紧缩和主紧缩。minor紧缩通常会将数个小的相邻的文件合并成一个大的。Minor不会删除打上删除标记的数据,也不会删除过期的数据,Major紧缩会删除过期的数据。有些时候minor紧缩就会将一个store中的全部文件紧缩,实际上这个时候他本身就是一个major压‹缩。对于一个minor紧缩是如何紧缩的,可以参见ascii diagram in the Store source code.

在执行一个major紧缩之后,一个store只会有一个sotrefile,通常情况下这样可以提供性能。注意:major紧缩将会将store中的数据全部重写,在一个负载很大的系统中,这个操作是很伤的。所以在大型系统中,通常会自己Section 2.8.2.8, “管理 Splitting”。

紧缩 不会 进行分区合并。参考 Section 14.2.2, “Merge” 获取更多合并的信息。

9.7.6.5.1 紧缩文件的选择

想了解StoreFiles选择算法需要了解一些ASCII的结构知识,示例如下:

/* normal skew:
 *
 *         older ----> newer
 *     _
 *    | |   _
 *    | |  | |   _
 *  --|-|- |-|- |-|---_-------_-------  minCompactSize
 *    | |  | |  | |  | |  _  | |
 *    | |  | |  | |  | | | | | |
 *    | |  | |  | |  | | | | | |
 */

要点:

  • hbase.store.compaction.ratio选择算法中使用的紧缩文件命中率(default 1.2f).
  • hbase.hstore.compaction.min (.90 hbase.hstore.compactionThreshold) (files) 发生紧缩时Store中的最小文件数(default 2).
  • hbase.hstore.compaction.max (files) 每次次紧缩包含的最大文件数 (default 10).
  • hbase.hstore.compaction.min.size (bytes) 任意大小小于这个值StoreFile会自动成为紧缩的候选文件,默认是hbase.hregion.memstore.flush.size (128 mb).
  • hbase.hstore.compaction.max.size (.92) (bytes) 任意大小大于该值的StoreFile都不做紧缩操作 (default Long.MAX_VALUE).
次紧缩StoreFiles选择的逻辑是基于大小的,它会选择文件大小<= sum(smaller_files) *hbase.hstore.compaction.ratio的。


http://hbase.apache.org/book/regions.arch.html


你可能感兴趣的:(9.7 Region(部分))