數據字典用來存儲了系統的元數據。HBase的元數據包括:用戶表的定義、表的切分方案、分片的分佈情況(即分片分佈在哪個regionserver上)、分片對應的數據文件和日誌文件。其中,分片和數據文件的映射關係是通過目錄映射實現的,即不同的分片的數據文件存儲在不同的目錄中,其中目錄的名稱是分片的名稱。【對比:在Hypertable中分片與數據文件的映射關係記錄在表中】
如圖3-13所示。HBase使用表-ROOT-和表.META存儲元數據【Oracle也用表存儲元數據】。和普通的表一樣,這兩張表對應的分片分佈在RegionServer上的。.META.存儲了所有用戶表的元數據庫,可以被分裂,其元數據存儲在表-ROOT-中。-ROOT-有且只有一個分片,不能被分裂。ZooKeeper的節點ZK/hbase/root-region-server存儲了加載-ROOT-分片的RegionServer的地址信息,是整個系統的入口。
注:在本文描述的HBase0.90.0中,.META.還不支持分裂,不過最新版本已經支持分裂.META.了。
圖3-13 定位分片的層次
1 表.META.
表.META.的定義腳本如下:
create '.META.', {NAME => 'info', VERSIONS => 10, COMPRESSION => 'none', IN_MEMORY => true, BLOCKCACHE => true, BLOCKSIZE =>8096,TTL => 2147483647, BLOOMFILTER => 'NONE', REPLICATION_SCOPE => 0 }
family |
qualifer |
描述 |
info |
regioninfo |
分片的屬性信息,包括startkey,endkey,對應表的定義等 |
server |
加載本分片的RS地址信息 |
|
serverstartcode |
加載本分片的RS的啓動時間,用於MasterServer區分RS是否重啓 |
|
splitA |
子分片A的regioninfo |
|
splitB |
子分片B的regioninfo |
表3-1 .META.的定義
.META.的rowKey是分片的名稱。regionname的格式如表3-2.
分片類型 |
分片名稱的格式 |
-ROOT- |
tablename+','+startkey+','+regionid 規定-ROOT-分片的regionid爲0,所以名稱爲: "-ROOT-,,0" |
.META. |
tablename+','+startkey+','+regionid 0.90.3版本不支持.META.分裂,規定.META.分片的regionid爲1所以名稱爲: ".META.,,1" |
普通分片 |
tablename+','+startkey+','+regionid+'.'+md5+'.'其中md5是tablename+','+startkey+','+regionid的md5碼 |
表3-2 分片名稱的格式
分片名稱中存在regionid的原因?
父分片分裂後,由於垃圾回收機制的需要,父分片的元數據不能立即在.META.得到刪除,所以父分片和子分片的元數據會同時出現在.META.中。但是第一個子分片與父分片的tablename和startkey都一樣, tablename+startkey無法唯一標識一個分片,所以在分片名稱的尾部增加了一個regionid,從而使得分片名稱可以唯一標記一個分片。regionid實際是分片的生成時間,子分片的regionid一定要比父分片的regionid要大。
regioninfo的定義參見下圖。
圖3-14 序列化的regioninfo
字段 |
描述 |
version |
版本號。爲0 |
endkey |
|
offLine |
用於分裂。true表示已經closed,但是還不能刪除,因爲其數據文件還在被子分片使用 |
regionId |
分片創建當前時間 |
regionName |
見表3-2 |
split |
true:本分片已經被split。 |
startKey |
|
tableDesc |
見表3-4 |
hashCode |
前面所有字段的hash值 |
表3-3 regioninfo的各個字段的定義
字段 |
描述 |
version |
5 |
name |
表名 |
isRoot |
是否是表-ROOT- ,冗餘信息? |
isMeta |
是否是表.META. ,冗餘信息? |
tableAttrNum |
字段tableAttrList中表屬性的個數 |
tableAttrList |
見表3-5 |
familyListNum |
列族的數量 |
familyList |
見表3-6 |
表3-4 tableDesc的定義
名稱 |
描述 |
默認值 |
FAMILIES |
未使用? |
|
IS_ROOT |
是否是表"-ROOT-" |
|
IS_META |
是否是表".META." |
|
READONLY |
表的狀態 |
false |
DEFERRED_LOG_FLUSH |
若爲true。寫數據時,無需確認WAL是否寫入磁盤,即可返回。以數據的持久性交換寫性能。 |
false |
MAX_FILESIZE |
分片所有數據文件的總大小達到這個閥值後,需要分裂分片。單位是字節。 |
256M |
MEMSTORE_FLUSHSIZE |
當分片的所有MemStore的總大小到達這個閥值後,需要把MemStore中的數據寫入磁盤數據文件。單位是字節。 |
64M |
表3-5 tableAttrList
名稱 |
描述 |
默認值 |
NAME |
列族名稱 |
無 |
VERSIONS |
最大版本數 |
3 |
TTL |
time to live |
Integer.MAX_VALUE,表示永久有效 |
IN_MEMORY |
是否常駐內存 |
false |
COMPRESSION |
列族的壓縮算法 包括 "lzo" "gz" "none" |
"none" |
COMPRESSION_COMPACT |
major時的壓縮算法 |
同COMPRESSION |
BLOOMFILTER |
"NONE" "ROW" "ROWCOL" |
"NONE" |
REPLICATION_SCOPE |
多個數據中心備份數據的參數。【待研究】 |
0 |
BLOCKSIZE |
StoreFile的 data block大小, 單位字節 |
64*1024 |
BLOCKCACHE |
是否緩存其block |
true |
表3-6 familyAttrList
2 表-ROOT-
表-ROOT-存儲了表的.META.的元數據,並且不可以分裂。創建-ROOT-表的腳本如下:
create '-ROOT-', {NAME => 'info', VERSIONS => 10, COMPRESSION => 'none', IN_MEMORY => true, BLOCKCACHE => true, BLOCKSIZE =>8096,TTL => 2147483647, BLOOMFILTER => 'NONE', REPLICATION_SCOPE => 0 }
3 系統入口
從某種程度上來說,zookeeper是一個小型文件系統,可以用來存儲及少量的數據。ZK/hbase/root-region-server是zookeeper中的一個文件,用來存儲了加載-ROOT-分片的RegionServer的地址信息(主機名+port),是HBase集羣的總入口。