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