在網上較多的文章都會介紹hbase的兩個關鍵表ROOT表與meta表歹嘹。其實在hbase0.98之后征唬,hbase就廢棄了ROOT表谨履,僅保留meta表(還有namespace表笛求,該表只與hbase命名空間有關,這里不做介紹)扭粱,并且該表不允許split舵鳞。
meta split
在0.98后,meta被禁止進行split操作琢蛤。要知道m(xù)eta表的一條記錄包含了一個region的位置蜓堕、起始key,創(chuàng)建時間等信息虐块。那萬一region數量過大怎么辦俩滥?查看了公司集群一共1091個region嘉蕾,meta表的大小如圖所示:
假定集群有十萬個region贺奠,meta表也就400多M。在生產環(huán)境下错忱,hbase.hregion.max.filesize配置為10G儡率,如果按照這個大小來看挂据,meta可支持的region的數據是一個很可觀的數量。
meta位置
meta表location info以非臨時znode的方式注冊到zk上儿普,如下圖崎逃,可知meta region位置為centos063機器。
meta rowkey
meta表的rowkey信息在HRegionInfo類的createRegionName方法中構建眉孩,代碼如下:
public static byte [] createRegionName(final TableName tableName,
final byte [] startKey, final byte [] id, final int replicaId, boolean newFormat) {
int len = tableName.getName().length + 2 + id.length +
(startKey == null? 0: startKey.length);
if (newFormat) {
len += MD5_HEX_LENGTH + 2;
}
byte[] replicaIdBytes = null;
// Special casing: replicaId is only appended if replicaId is greater than
// 0. This is because all regions in meta would have to be migrated to the new
// name otherwise
if (replicaId > 0) {
// use string representation for replica id
replicaIdBytes = Bytes.toBytes(String.format(REPLICA_ID_FORMAT, replicaId));
len += 1 + replicaIdBytes.length;
}
byte [] b = new byte [len];
int offset = tableName.getName().length;
System.arraycopy(tableName.getName(), 0, b, 0, offset);
b[offset++] = HConstants.DELIMITER;
if (startKey != null && startKey.length > 0) {
System.arraycopy(startKey, 0, b, offset, startKey.length);
offset += startKey.length;
}
b[offset++] = HConstants.DELIMITER;
System.arraycopy(id, 0, b, offset, id.length);
offset += id.length;
if (replicaIdBytes != null) {
b[offset++] = REPLICA_ID_DELIMITER;
System.arraycopy(replicaIdBytes, 0, b, offset, replicaIdBytes.length);
offset += replicaIdBytes.length;
}
if (newFormat) {
//
// Encoded name should be built into the region name.
//
// Use the region name thus far (namely, <tablename>,<startKey>,<id>_<replicaId>)
// to compute a MD5 hash to be used as the encoded name, and append
// it to the byte buffer.
//
String md5Hash = MD5Hash.getMD5AsHex(b, 0, offset);
byte [] md5HashBytes = Bytes.toBytes(md5Hash);
if (md5HashBytes.length != MD5_HEX_LENGTH) {
LOG.error("MD5-hash length mismatch: Expected=" + MD5_HEX_LENGTH +
"; Got=" + md5HashBytes.length);
}
// now append the bytes '.<encodedName>.' to the end
b[offset++] = ENC_SEPARATOR;
System.arraycopy(md5HashBytes, 0, b, offset, MD5_HEX_LENGTH);
offset += MD5_HEX_LENGTH;
b[offset++] = ENC_SEPARATOR;
}
return b;
}
根據上圖源碼个绍,再通過hbase shell查詢mate表信息如下圖:
可知,hash值=MD5Hash.getMD5AsHex(byte(表名,region startKey,創(chuàng)建時間))浪汪,meta表的rowkey組成為:表名,region startKey,創(chuàng)建時間.hash值巴柿。如果當前region為table的第一個region時(第一個region無start key)時,region startKey=null死遭。
mete info
meta表只有一個列簇info广恢,并且包含四列:
1、regioninfo :當前region的startKey與endKey呀潭,name等消息
2钉迷、seqnumDuringOpen:
3、server:region所在服務器及端口
4钠署、serverstartcode:服務開始的時候的timestamp