2,從邏輯存儲(chǔ)結(jié)構(gòu)到實(shí)際的物理存儲(chǔ)結(jié)構(gòu)要經(jīng)歷一個(gè)fold過(guò)程,所有的columnFamily下的內(nèi)容被有序的合并,因?yàn)镠Base把一個(gè)ColumnFamily存儲(chǔ)為一個(gè)StoreFile。
3,把HBase的查詢(xún)等價(jià)為一個(gè)逐層過(guò)濾的行為,那么在設(shè)計(jì)存儲(chǔ)時(shí)就應(yīng)該明白,使設(shè)計(jì)越趨向單一的keyvalue性能會(huì)越好;如果是因?yàn)閺?fù)雜的業(yè)務(wù)邏輯導(dǎo)致查詢(xún)需要確定rowkey、column、timestamp,甚至更夸張的是用到了HBase的Filter在server端做value的處理,那么整個(gè)性能會(huì)非常低。
4,因此在表結(jié)構(gòu)設(shè)計(jì)時(shí),HBase里有tall narrow和flat wide兩種設(shè)計(jì)模式,前者行多列少,整個(gè)表結(jié)構(gòu)高且窄;后者行少列多,表結(jié)構(gòu)平且寬;但是由于HBase只能在行的邊界做split,因此如果選擇flat wide的結(jié)構(gòu),那么在特殊行變的超級(jí)大(超過(guò)file或region的上限)時(shí),那么這種行為會(huì)導(dǎo)致compaction,而這樣做是要把row讀內(nèi)存的~~因此,強(qiáng)烈推薦使用tall narrow模式設(shè)計(jì)表結(jié)構(gòu),這樣結(jié)構(gòu)更趨近于keyvalue,性能更好。
5,一種優(yōu)雅的行設(shè)計(jì)叫做partial row scan,我們一般rowkey會(huì)設(shè)計(jì)為<key1>-<key2>-<key3>...,每個(gè)key都是查詢(xún)條件,中間用某種分隔符分開(kāi),對(duì)于只想查key1的所有這樣的情況,在不使用filter的情況下(更高性能),我們可以為每個(gè)key設(shè)定一個(gè)起始和結(jié)束的值,比如key1作為開(kāi)始,key1+1作為結(jié)束,這樣scan的時(shí)候可以通過(guò)設(shè)定start row和stop row就能查到所有的key1的value,同理迭代,每個(gè)子key都可以這樣被設(shè)計(jì)到rowkey中。
6,對(duì)于分頁(yè)查詢(xún),推薦的設(shè)計(jì)方式也不是利用filter,而是在scan中通過(guò)offset和limit的設(shè)定來(lái)模擬類(lèi)似RDBMS的分頁(yè)。具體過(guò)程就是首先定位start row,接著跳過(guò)offset行,讀取limit行,最后關(guān)閉scan,整個(gè)流程結(jié)束。
7,對(duì)于帶有時(shí)間范圍的查詢(xún),一種設(shè)計(jì)是把時(shí)間放到一個(gè)key的位置,這樣設(shè)計(jì)有個(gè)弊端就是查詢(xún)時(shí)一定要先知道查詢(xún)哪個(gè)維度的時(shí)間范圍值,而不能直接通過(guò)時(shí)間查詢(xún)所有維度的值;另一種設(shè)計(jì)是把timestamp放到前面,同時(shí)利用hashcode或者M(jìn)D5這樣的形式將其打散,這樣對(duì)于實(shí)時(shí)的時(shí)序數(shù)據(jù),因?yàn)閷⑵浯蛏?dǎo)致自動(dòng)分到其他region可以提供更好的并發(fā)寫(xiě)優(yōu)勢(shì)。
8,對(duì)于讀寫(xiě)的平衡,下面這張圖更好的說(shuō)明了key的設(shè)計(jì):salting等價(jià)于hash,promoted等價(jià)于在key中加入其他維度,而random就是MD這樣的形式了。
9,還有一種高級(jí)的設(shè)計(jì)方式是利用column來(lái)當(dāng)做RDBMS類(lèi)似二級(jí)索引的應(yīng)用設(shè)計(jì),rowkey的存儲(chǔ)達(dá)到一定程度后,利用column的有序,完成類(lèi)似索引的設(shè)計(jì),比如,一個(gè)CF叫做data存放數(shù)據(jù)本身,ColumnQualifier是一個(gè)MD5形式的index,而value是實(shí)際的數(shù)據(jù);再建一個(gè)CF叫做index存儲(chǔ)剛才的MD5,這個(gè)index的CF的ColumnQualifier是真正的索引字段(比如名字或者任意的表字段,這樣可以允許多個(gè)),而value是這個(gè)索引字段的MD5。每次查詢(xún)時(shí)就可以先在index里找到這個(gè)索引(查詢(xún)條件不同,選擇的索引字段不同),然后利用這個(gè)索引到data里找到數(shù)據(jù),兩次查詢(xún)實(shí)現(xiàn)真正的復(fù)雜條件業(yè)務(wù)查詢(xún)。
10,實(shí)現(xiàn)二級(jí)索引還有其他途徑,
比如:
1,客戶(hù)端控制,即一次讀取將所有數(shù)據(jù)取回,在客戶(hù)端做各種過(guò)濾操作,優(yōu)點(diǎn)自然是控制力比較強(qiáng),但是缺點(diǎn)在性能和一致性的保證上;
2,Indexed-Transactional HBase,這是個(gè)開(kāi)源項(xiàng)目,擴(kuò)展了HBase,在客戶(hù)端和服務(wù)端加入了擴(kuò)展實(shí)現(xiàn)了事務(wù)和二級(jí)索引;
3,Indexed-HBase;
4,Coprocessor。
11,HBase集成搜索的方式有多種:1,客戶(hù)端控制,同上;2,Lucene;3,HBasene,4,Coprocessor。
12,HBase集成事務(wù)的方式:1,ITHBase;2,ZooKeeper,通過(guò)分布式鎖。
13,timestamp雖然叫這個(gè)名字,但是完全可以存放任何內(nèi)容來(lái)形成用戶(hù)自定義的版本信息。