HBase in Action前三章筆記
最近接觸HBase,看了HBase In Action的英文版。開始覺得還行,做了些筆記,但是後續看下去,越來越感覺到實戰這本書比較偏使用上的細節,對於HBase的詳細設計涉及得非常少。把前三章的一些筆記帖一下,後麵幾章內容不打算整理了,並不是說書內容不好。
key-value存儲,強一致性,多個RegionServer節點對client端是不暴露細節的
使用場景:典型的web-search, capture incremental data, ad. click stream, content serving, info exchange

設置 hbase.root 來改寫本來寫/tmp的數據路徑
HBase shell是jruby寫,hbase shell來啟動
一些命令:
list create 'pelick', 'cf' put 'pelick', 'first', 'cf:msg', 'wefewfwf' put 'pelick', 'sec', 'cf:num', 12234 get 'pelick', 'first' 默認返回version最新的數據,實際上put的時候會有帶新的版本號 scan 'pelick' describe 'pelick'
一些對應的API類和簡單使用
HTableInterface usersTable = new HTable("users"); Configuration myConf = HBaseConfiguration.create(); HTableInterface usersTable = new HTable(myConf, "users"); HTablePool pool = new HTablePool(); HTableInterface usersTable = pool.getTable("users"); ... // work with the table usersTable.close();
Get, Put, Delete, Scan, Increment
Put p = new Put(Bytes.toBytes(" TheRealMT")); p.add(Bytes.toBytes("info"), Bytes.toBytes("name"), Bytes.toBytes("Mark Twain"));
Put的時候,成功執行需要兩個保證,write-ahead log(WAL,即HLog)和MemStore
這兩部分保證了data durability,可以選擇不要WAL,就不保證數據不丟了,
Put p = new Put(); p.setWriteToWAL(false);
原因如下:
MemStore是內存的write buffer,到一定量會flush到磁盤上成為HFile,如果region server掛了,數據就丟失。而WAL可以用來恢複數據。
一個column family可以有多個HFile,但是一個HFile不能有多個column family的數據。每個column family對應一個MemStore。
每台HBase機器都保存一份WAL,而這份WAL的durable取決於下麵的文件係統,HDFS保證了這點。
一台HBase機器的WAL被所有的表、列簇共享。
Get的時候可以控製獲得數據內容,通過addColumn()和addFamily()
Get g = new Get(Bytes.toBytes("TheRealMT")); g.addColumn( Bytes.toBytes("info"), Bytes.toBytes("password")); Result r = usersTable.get(g);
讀數據的時候,有一個LRU cache來緩存經常訪問的數據,即BlockCache,用來緩存HFile內容,提升讀性能。
每個column family有自己的BlockCache。
HFile本質上是由Block組成的,index定位的。默認block大小是64K,可調整來影響順序/隨機讀性能。block是讀的最小單位。

Delete也相似,
Delete d = new Delete(Bytes.toBytes("TheRealMT")); d.deleteColumns( Bytes.toBytes("info"), Bytes.toBytes("email")); usersTable.delete(d);
對Delete來說,數據並沒有及時刪除,是做了標記,不能被scan和get到。實際上,在compaction的時候會刪除。
compaction分為minor和major兩種。前者是合並HFile,比較常發生,對於合並的HFile大小和數目的設定會影響寫性能。合並比較吃IO的。
後者是把給定的region的一個列簇的所有HFile合並為一個HFile,開銷大,要手動shell觸發。所以前者比較輕量級些。
隻有合並的時候,該刪除的數據才會真正被刪除。

HBase除了是schema-less的,也是版本化的。對同一個列,可以寫多次,每次會帶版本,是個long值,默認依賴時間戳。所以機器的時間應該要設置為同步。默認保留三份版本,如果多了,會把之前的舊版本替掉。
Table,Row,Column Family,Column qualifier,Cell,Version,這些組成了HBase數據構成。
Row:row key是唯一的,byte[]。列簇影響物理數據分布。Column qualifier的話各個row可以設置為不一樣。
cell是rowkey+cf+cq組成的一條唯一記錄,理解為一行數據,也是byte[]
在訪問上述這些元素的時候,是通過協調輸入的rowkey, column family, column qualifier, version四個維度來找的
可以用4D的查找方式來理解一個普通的二維表,下圖解釋很清楚
所以呢,我們可以把查找理解為key是一個map(可以是四維裏的前幾個組成的查詢條件),value為一個map或多個maps
HBase數據模型是半結構化的,即列數可以不同,域值長度也可以不同
從邏輯模型的角度看,HBase提供的是無限製的,持久的,嵌套不同版本的結構。可以把整個結構理解為java裏的這樣一個Map:
Map<RowKey, Map<ColumnFamily, Map<ColumnQualifier,Map<Version, Data>>>>
且裏麵是降序排列的
從物理模型的角度看,一個列簇有多個HFile,本身是二進製文件,裏麵不包含null記錄。

做Table Scan的時候,可以傳filter,具體API不列舉。
在設置rowkey的時候,盡量讓rowkey長度一致,比如hash一次。rowkey的設計影響重大,要盡量高效。
hbase.client.scanner.caching可以設置每次RPC返回的row個數,cache在client端,默認是1,比較影響性能。
HBase的原子操作,即Incremental Column Value(ICV),
long ret = usersTable.incrementColumnValue( Bytes.toBytes("TheRealMT"), Bytes.toBytes("info"), Bytes.toBytes("tweet_count"), 1L);
類似java的AtomicLong.addAndGet()
HBase的region存在於region server上,與HDFS的datanode共存。由matser進程來分布region。
hbase.hregion.max.filesize影響一個region的分裂
client讀寫數據的時候,主要靠-ROOT-和.META.來做類似B+樹的查找。結構如下:

第一次和zk通信,得到-ROOT-在哪裏。然後向某RS問,得到.META.在哪裏。然後向某RS2問,得到目標RS在哪裏。最後向目標RS問,數據的具體位置。
這兩表在client端會緩存。
HBase和MR的交互:可以把HBase當MR的數據源和寫入目標,HBase還可以參與map-side join。
reduce-side join需要把所有數據shuffle到reduce端並且sort,開銷大,那麼map端的join可以減小IO和網絡開銷。
小表可以直接放內存進行map-side join,此時把這步直接變成讀HBase,就節省了內存。具體例子不舉了。
本質上,把HBase當作一個外部的巨大的hash table。

MR要注意是冪等的,對於有map裏有狀態的操縱,要注意避免影響,比如HBase的increment命令
部署要注意,HBase部署的datanode上盡量不要起MR的進程了,會影響性能。
最後說說HBase的可用性和可靠性。
可用性指係統處理失敗的能力。RegionServer是具備可用性的,一台掛了,另一個可以代替它工作(數據在HDFS上保證,信息可以從master獲取)。要達到高可用,還可以做一些防禦性部署,比如考慮多master的機架分布。
可靠性是一個數據庫係統的名詞,指數據durability和性能保證的結合。
那麼HDFS作為HBase的支撐,帶來了什麼呢?
所有region servers是HDFS文件係統上的同一套namespace,保證了可用性。

RS和datanode共同部署,減少網絡IO開銷。
可靠性方麵,HDFS保證數據的備份和不丟失。HBase本身的寫語義具備durability的保證。
全文完 :)
最後更新:2017-04-03 07:57:13