HBase source code. HRegion

配置:

hbase.hregion.memstore.flush.size: 134217728

当Region的所有的memstore(意思是所有HStore的memstore的size的加总)的size超过参数设定的字节数时, 就会引发flush to disk的这个操作. 其中监听这个value是有另外一条线程在做.
hbase.hregion.percolumnfamilyflush.size.lower.bound: 16777216

当使用了FlushLargeStoresPolicy的时候, 这个参数才会起效. 意思是当Region的memstore的limit被达到的时候. 我们会找到这个Region中所有HStore中的memstore超过这个值的. 然后这些超过值的将会被flush. 其它小于这个值的不会被flush. 如果没有任何HStore的memstore超过这个值的话, 那么所有memstore都将会被flush(更默认的行为一致). 这个值的设定应该小于总memstore值的一半.

hbase.hregion.preclose.flush.size: 5242880

当要将一个region关闭的时候, 如果此时region中总memstore的size大于等于这个设定时, region会运行一个pre-flush的操作. 完成后再进行region的关闭. 这个flush会在region的close的flag下执行, 这个时间不再接受任何写操作. 如果memstore的内容比较大的话, 会花费相当的时间.

hbase.hregion.memstore.block.multiplier: 4

如果region的memstore的字节数超过这个参数乘以hbase.hregion.memstore.flush.size的字节数, 更新会被阻塞. 这个参数在写入非常繁忙的时候非常有用, 相当于确定了了一个上界. 可以防止OOME或者compaction的时间过长或者split的时间过长.

hbase.hregion.memstore.mslab.enabled: true

mslab的全称是MemStore-Local Allocation Buffer. 这是一个用来防止堆内存过于零散碎片从而导致频繁调用gc的class. 这种情况特别容易发生在重写下. 默认情况是enable.

hbase.hregion.max.filesize: 10737418240

一个region拥有的最大HFile的size. 超过这个值的region将会被split成两半.

hbase.hregion.majorcompaction: 604800000

两个major compaction的间隔的时间, 单位毫秒. 0表示关闭到达时间就自动进行major compaction的这个行为. 可以通过用户请求或者size满足这两个方面触发major compaction. 默认值是7天进行一次major compaction. 如果major compaction对程序运行有什么阻碍的话, 可以将major compaction的时间设定在非高峰时间. 或者关了时间触发, 改为人为触发或者size触发等其他触发机制. 这个参数乘以hbase.hregion.majorcompaction.jitter会导致在默认的间隔时间(7天)内随机的发生major compaction

hbase.hregion.majorcompaction.jitter: 0.50

这个参数配合上面的那个参数使用. 数字设置得越小, 就会越接近默认的major compaction时间. 意思就是major compaction发生的时间不一定是7天, 反正就是一定会发生在7天中的某一个随机时间, 这个时间的随机性由这个数字来决定.

相关:

hbase:meta table存放了系统中所有的regions的信息. hbase:meta现在存放在ZooKeeper中

hbase:meta table的结构如下:

Key
Region key of the format ([table],[region start key],[region id])

Values
info:regioninfo (serialized HRegionInfo instance for this region / 将HRegionInfo序列化之后的实体, region info包含table name start key, region id, replica id, region name的MD5编码, end key, 是否split生成的, 是否offline了)

info:server (server:port of the RegionServer containing this region / 此Region的服务器的端口)

info:serverstartcode (start-time of the RegionServer process containing this region / 此Region被Region Server开始执行的时间)

Region-RegionServer Assignment

Startup

1. master先唤醒AssignmentManager

2. AssignmentManager查看hbase:meta中存在的region

3. 如果region是有效的(例如掌控这个region的region server是活着的), 然后这个region的assignment维持不变

4. 如果region是无效的(例如offline了), LoadBalancerFactory会被唤醒去assign这个region. 然后这个region回被分配到某个region server上

5. 此时hbase:meta table对应的原来的region的信息会被更新例如(region server的port, 被开始的时间)

Failover

1. regions在region server挂掉的时候就变得不可用了

2. master会监测到region server挂掉

3. region assignment被视为无效, 然后会重新执行一次assign操作如上面startup所述

4. 正在执行中的请求处于重复请求的操作, 但请求不会丢失

5. 操作回被转移到一个新的region server上, 所需要的时间 = ZooKeeper session timeout + split time + assignment/replay time

Region State Transition

如图所示, region state总共有13种:

1.  OFFLINE: region处于离线状态并未被开启

2.  OPENING: region处于正在被开启的过程中

3.  OPEN: region已经开启成功, 并且其所属region server也已经通知master表示region已开启成功

4.  FAILED_OPEN: region无法被region server打开

5.  CLOSING: region正在被关闭中

6.  CLOSED: region已经被关闭了, 并且其所属region server也已经通知master表示region已关闭成功

7.  FAILED_CLOSE: region无法被region server关闭

8.  SPLITTING: region server通知master表示这个region正在split的过程中

9.  SPLIT: region server通知master表示region的split操作已经完成

10. SPLITTING_NEW: 这个region是被split产生的, 而且还在split的过程中

11. MERGING: region server通知master表示这个region正在和其它region进行merge的操作过程中

12. MERGED: region server通知master表示此region的merge操作已经完成.

13. MERGING_NEW: 这个region是通过merge生成出来的新region

HBase source code. HRegion_第1张图片

上图也是表示region state之间的转换: (序号对应图片)

1.   master要将region的状态从OFFLINE改到OPENING状态, 需要将region分配到其中一个region server上. region server可能会也许可能不会接收到open region的请求. master会一直尝试发送open region的请求直到rpc完成了或者master已经将有限的机会尝试完. 如果region server收到open region的请求, region server就会将region开启

2.   如果master确实将有限的机会尝试完, 而region尚未被开启. master会将region的从OPENING改为CLOSING. 哪怕就算region server因为网络延迟而想开启region也不行.

3.   region server开启region后. region server会通知master这个情况, 直到master确实将region的state改为OPEN并告知region server已经修改好state了. 此时region正式为OPEN

4.   如果region server无法开启这个region, 它会通知master. master然后将这个region的state改为CLOSED. 并且尝试将这个region分配给其它region server开启.

5.   如果master无论尝试过多少个region server都无法将这个region打开. 会将这个region state改为FAILED_OPEN. 然而不会采取任何后续行动, 除非HBase shell进行干预或者服务器挂掉.

6.   master要将region的状态从OPEN改到CLOSING状态, 该region的region server有可能不会马上接收到关闭region的请求. master会一直尝试发送关闭region请求直到尝试次数用完或者RPC完成通过.

7.   如果region server不在线上. 或者抛出了NotServingRegionException异常. master将region的state改为OFFLINE, 并重新分配个其它region server

8.   如果region server在线上, 但是master尝试完所有机会仍然无法接触到region server使其关闭region, 此时master将region的状态改为FAILED_CLOSE. 并且不会再采取任何行动, 直到HBase shell干预或者服务器死了.

9.   如果region server确切收到了关闭region的请求. 它就会把region关闭并且通知master. master收到通知后会将region状态改为CLOSED. 然后会将此region重新分配个不同的region server.

10. 在将region进行分配之前, 如果此时region处于CLOSED状态, master会将state改为OFFLINE. 这是个短暂的状态转换,

11. 当一个region server将要split一个region的时候, 它会通知master. master会将region的state从OPEN改为SPLITTING. split生成的两个regions会在这个region server上. 这个两个regions的state初始化为SPLITING_NEW.

12. 通知master后, region server开始split region. 一旦region server通知说master split完成. splitting region的state将从SPLITTING改为SPLIT. 两个新的regions从SPLITTING_NEW改为OPEN

13. 如果split失败的话. splitting region从SPLITTING改回OPEN state. 而被split出来的两个regions从SPLITTING变为OFFLINE

14. 当一个region server将要merge两个个regions的时候, 它会通知master. master会将两个regions的state从OPEN改为MERGING. merge生成的regions会在这个region server上. 这个merge生出的regions的state初始化为MERGING_NEW.

15. 通知master后, region server开始merge regions. 一旦region server通知说master merge完成. merging region的state将从MERGING改为MERGED. 新的region从MERGING_NEW改为OPEN

16. 如果merge失败的话. merging region从MERGING改回OPEN state. 而被merge出来的region从MERGING_NEW变为OFFLINE

17. 对于那些处于FAILED_OPEN或者FAILED_CLOSE状态的regions. 当他们通过HBase shell的操作被重分配时, master会尝试去关掉他们.

最后, region的状态情况可以通过master的web ui来观察

Region Load Balancing

balancer的线程跑在master上, 会周期性地检查regions的分布情况, 并且会重分布region, 使cluster的各datanode之间负载平衡. 默认周期为5mins. 重分布之前, 会检查是否有region正在处于state的转变过程中, 有的话不会马上进行重分布. 无的话则进行重分布.


关于region的split和merge的议题, 以后代码看后再说.


最后附上. HRegion.class的开头说明:

/**
 * HRegion stores data for a certain region of a table.  It stores all columns
 * for each row. A given table consists of one or more HRegions.
 *
 * 

We maintain multiple HStores for a single HRegion. * *

An Store is a set of rows with some column data; together, * they make up all the data for the rows. * *

Each HRegion has a 'startKey' and 'endKey'. *

The first is inclusive, the second is exclusive (except for * the final region) The endKey of region 0 is the same as * startKey for region 1 (if it exists). The startKey for the * first region is null. The endKey for the final region is null. * *

Locking at the HRegion level serves only one purpose: preventing the * region from being closed (and consequently split) while other operations * are ongoing. Each row level operation obtains both a row lock and a region * read lock for the duration of the operation. While a scanner is being * constructed, getScanner holds a read lock. If the scanner is successfully * constructed, it holds a read lock until it is closed. A close takes out a * write lock and consequently will block for ongoing operations and will block * new operations from starting while the close is in progress. * *

An HRegion is defined by its table and its key extent. * *

It consists of at least one Store. The number of Stores should be * configurable, so that data which is accessed together is stored in the same * Store. Right now, we approximate that by building a single Store for * each column family. (This config info will be communicated via the * tabledesc.) * *

The HTableDescriptor contains metainfo about the HRegion's table. * regionName is a unique identifier for this HRegion. (startKey, endKey] * defines the keyspace for this HRegion. */



你可能感兴趣的:(HBase)