前提说明:本文章研究的hbase版本是0.94.12。.
-ROOT-表和.META.表是hbase的元数据表,在-ROOT-表中保存有.META.表的相关信息,在.META.表中保存有业务表的region相关信息,在client端访问具体的业务表的region时需要先通过-ROOT-表找到.META.表,再通过.META.表找到region的位置,即这两个表主要解决了region的快速路由问题。
通过scan命令查看-ROOT-表的数据:
通过上图可以看出-ROOT-表的1行记录共有1个列簇4个列:regioninfo、server、serverstartcode、v,分别介绍如下:
1、regioninfo列
该列包含了.META.表的region信息:region名称、开始rowkey、结束rowkey、encode值:
a)region名称的组成规则:表名称+”,”+startKey+”,”+regionId,regionId的组成规则是:创建region时的时间戳+”.”+encode值(旧版hbase的regionId只有时间戳)+“.”,region名称会被作为-ROOT-表的rowkey,.META.表的rowkey也如此,这种设计可以充分利用hbase的rowkey机制快速定位region。
-ROOT-表中.META. region的regionId比较特殊,.META.表的第一个region没有采用encode码,而是直接指定1,.META.表中业务表的region则完全遵循该规则,如图:
b)startKey,region的开始key,第一个region的startKey是空字符串;
c)endKey,region的结束key,最后一个region的endKey是空字符串;
d)encode值,该值会作为hdfs文件系统的一个目录,如图:
-ROOT-表和.META.表的encode值是固定值,hbase源码如下:
public static String prettyPrint(final String encodedRegionName) { if (encodedRegionName.equals("70236052")) { return encodedRegionName + "/-ROOT-"; } else if (encodedRegionName.equals("1028785192")) { return encodedRegionName + "/.META."; } return encodedRegionName; } |
在hbase的管理界面可以看到-ROOT-表和.META.表的信息:
2、server列:所在regionserver的服务器域名(或者ip)和端口;
3、serverstartcode列:以创建regionserver时的时间戳作为regionserver的startcode,同一个regionserver下的所有region该列值相同,该值作为regionserver的名称的一部分,源代码如下:
public static String getServerName(String hostName, int port, long startcode) { final StringBuilder name = new StringBuilder(hostName.length() + 1 + 5 + 1 + 13); name.append(hostName); name.append(SERVERNAME_SEPARATOR); name.append(port); name.append(SERVERNAME_SEPARATOR); name.append(startcode); return name.toString(); } |
在hbase的管理界面可以看到regionserver的信息:
4、v列,该列是在hbase0.92这个版本开始新增加的列,值是固定的0,主要主用是区别0.92和之前的版本,以便hbase进行版本迁移,源码如下:
/** * The current version of the meta table. * Before this the meta had HTableDescriptor serialized into the HRegionInfo; * i.e. pre-hbase 0.92. There was no META_VERSION column in the root table * in this case. The presence of a version and its value being zero indicates * meta is up-to-date. */ public static final short META_VERSION = 0;
// Update meta with new HRI if required. i.e migrate all HRI with HTD to // HRI with out HTD in meta and update the status in ROOT. This must happen // before we assign all user regions or else the assignment will fail. // TODO: Remove this when we do 0.94. org.apache.hadoop.hbase.catalog.MetaMigrationRemovingHTD. updateMetaWithNewHRI(this); //注:HTD指:HTableDescriptor, HRI指:HRegionInfo
public static final byte [] META_VERSION_QUALIFIER = Bytes.toBytes("v");
//Current meta table version or -1 if no version found. static short getMetaVersion(final Result r) { byte [] value = r.getValue(HConstants.CATALOG_FAMILY, HConstants.META_VERSION_QUALIFIER); return value == null || value.length <= 0? -1: Bytes.toShort(value); }
|
最后需要说明的是:-ROOT-表只存在一个region里,该region不会分裂成多个region ,因为-ROOT-表只保存.META.表的region信息,而.META.表的region理论上不会太多,.META.表可以有多个region,-ROOT-表和.META.表的每一行均描述一个region的信息。