GEO基礎(chǔ)知識(shí):Schema標(biāo)記 / Schema設(shè)計(jì)原則
Schema創(chuàng)建
HBase schema(模式)可以通過(guò)Apache HBase Shell或者Java API Admin來(lái)創(chuàng)建或者更新。 進(jìn)行ColumnFamily(列族)修改時(shí),必須禁用表,例如:
Configuration config = HBaseConfiguration.create();
Admin admin = new Admin(conf);
TableName table = TableName.valueOf("myTable");
admin.disableTable(table);
HColumnDescriptor cf1 = ...;
admin.addColumn(table, cf1);
HColumnDescriptor cf2 = ...;
admin.modifyColumn(table, cf2);
admin.enableTable(table);Schema更新
當(dāng)表或者列族被修改時(shí)(比如region大小、block大小),這些更改會(huì)在下一次major合并、StoreFiles重新寫(xiě)入時(shí)生效。
Schema設(shè)計(jì)經(jīng)驗(yàn)
HBase存在許多種不同的數(shù)據(jù)集,具有不同的訪(fǎng)問(wèn)模式和服務(wù)層級(jí)的要求。因此,以下經(jīng)驗(yàn)法則只是概述。
目標(biāo)region的大小限制在10GB到50GB之間。
限制cell的大小在10MB之內(nèi),如果使用的是mob類(lèi)型,限制在50MB之內(nèi)。否則,考慮把cell的數(shù)據(jù)存儲(chǔ)在HDFS中,并在HBase中存儲(chǔ)指向該數(shù)據(jù)的指針。
典型的scheme每張表包含1到3個(gè)列族。HBase表設(shè)計(jì)不應(yīng)當(dāng)和RDBMS表設(shè)計(jì)類(lèi)似。
對(duì)于擁有1或2個(gè)列族的表來(lái)說(shuō),50-100個(gè)region是比較合適的。注意region是列族的連續(xù)段。
保持列族名稱(chēng)盡可能短。每個(gè)值都會(huì)存儲(chǔ)列族的名稱(chēng)(忽略前綴編碼)。它們不應(yīng)該像在典型的RDBMS中一樣具有自我記錄和描述性。
如果正在存儲(chǔ)基于時(shí)間的機(jī)器數(shù)據(jù)或者日志信息,并且rowkey是基于設(shè)備ID或者服務(wù)ID+時(shí)間,最終可能會(huì)出現(xiàn)這樣一種情況,即更舊的數(shù)據(jù)region在某個(gè)時(shí)間段后永遠(yuǎn)不會(huì)有額外寫(xiě)入。在這種情況下,最終會(huì)存在少量的活動(dòng)region和大量不會(huì)再有新寫(xiě)入的region。
HBase列族數(shù)量
HBase目前不適合兩個(gè)或三個(gè)列族以上的任何項(xiàng)目,因此應(yīng)保持模式中的列族數(shù)量較少。目前,flushing和compactions是基于每個(gè)region進(jìn)行的,因此如果一個(gè)列族承載大量數(shù)據(jù)帶來(lái)flushing,則即使它們攜帶的數(shù)據(jù)量很小,相鄰的族也將被flushing。當(dāng)存在許多列族時(shí),flushing和compactions可能會(huì)產(chǎn)生一堆不必要的I/O。
如果單個(gè)表中存在多個(gè)列族,請(qǐng)注意基數(shù)(即行數(shù))不用相差太大。如果 ColumnFamilyA有100萬(wàn)行而ColumnFamilyB有10億行,則ColumnFamilyA 的數(shù)據(jù)可能會(huì)分布在許多區(qū)域(和RegionServers)中。這使得 ColumnFamilyA的大規(guī)模掃描效率降低。
版本數(shù)
最大版本數(shù)
HBase通過(guò)HColumnDescriptor給各列族配置要存儲(chǔ)的最大行版本數(shù)。最大版本的默認(rèn)值為1。這是一個(gè)重要的參數(shù),因?yàn)镠Base不會(huì)覆蓋一個(gè)值,只會(huì)時(shí)間戳來(lái)區(qū)分值的不同版本。早期的版本會(huì)在major compaction過(guò)程中被刪除。根據(jù)應(yīng)用需求,可以需要增加或減少最大版本的數(shù)量。 不建議將最大版本的數(shù)量設(shè)置為非常高的級(jí)別(例如,數(shù)百或更多),除非這些舊值非常珍貴,因?yàn)檫@將大大增加StoreFile的大小。
最小版本數(shù)
與最大行版本數(shù)一樣,HBase通過(guò)HColumnDescriptor按列族配置要保留的最小行版本數(shù)。最小版本的默認(rèn)值為0,表示該功能已禁用。行版本參數(shù)的最小數(shù)量與生存時(shí)間參數(shù)一起使用,并且可以與行版本參數(shù)的數(shù)量組合,以允許配置諸如“保留最后T分鐘的數(shù)據(jù),最多N個(gè)版本,但至少保留M個(gè)版本”(其中M是最小行版本數(shù)的值,M<N)。
支持的數(shù)據(jù)類(lèi)型
HBase通過(guò)Put和Result操作支持“byte-in/bytes-out”接口,因此任何可以轉(zhuǎn)換為字節(jié)數(shù)組的都可以存儲(chǔ)為值。輸入可以是字符串、數(shù)字、復(fù)雜對(duì)象、圖像,只要它們可以呈現(xiàn)為字節(jié)。 值的大小存在實(shí)際限制。HBase中的所有行都符合數(shù)據(jù)模型,包括版本控制。在進(jìn)行設(shè)計(jì)時(shí)要考慮到這一點(diǎn),以及列族的塊大小。
生存時(shí)間
列族可以設(shè)置TTL(Time To Live)長(zhǎng)度(以秒為單位),HBase將在超時(shí)后自動(dòng)刪除行。TTL設(shè)置適用于行的所有版本。在HBase中TTL時(shí)間為UTC時(shí)區(qū)。 僅包含過(guò)期的行的存儲(chǔ)文件,會(huì)在minor compaction時(shí)刪除。將hbase.store.delete.expired.storefile設(shè)置為false可禁用此功能。將最小版本數(shù)設(shè)置為0以外的值也會(huì)禁用此功能。
最新版本的HBase還支持按每個(gè)cell(單元)設(shè)置生存時(shí)間。cell TTL使用Mutation#setTTL作為變更請(qǐng)求的一個(gè)屬性提交。如果設(shè)置了TTL屬性,則它將應(yīng)用于被操作更新的所有cell。cell TTL處理和列族TTL之間存在兩個(gè)顯著差異:
cell TTL以毫秒而不是秒為單位表示。
cell TTL不能超過(guò)列族TTL設(shè)置的有效時(shí)間。