天天看點

Hbase作者為什麼允許一張表可以有多個列簇?

HBase的設計目标是海量,高吞吐存儲。資料在底層是基于LSMT那一套的實作(當然分了很多region,支援分布式)。簡單來說,要維護一套memstore + 可分裂的filestore的存儲,差不多就是:

新資料寫入/更改先寫入WAL,然後進入memstore

memstore滿了就進filestore

filestore太大了就分裂

而這一套機制實作的機關是column family——每個column family有自己的memstore和filestore。盡管在高層上看起來是同一張表,但是表裡每一個column family的存儲都是互相獨立的。如果和mysql比較的話,column family更像是mysql裡的table,而hbase的table更像是mysql裡的一個db。如果同時查詢同一個hbase table的不同column family,大概等價于不同mysql table之間基于row key做了一個join。

那到底為啥要區分column family呢?

3個原因:

通路的方式不一樣(access pattern )。試想一下用hbase存儲一個産品的資訊,比如A列是産品詳情。這個詳情可能非常大,但是并不會經常變。而B列是産品的關注次數,會頻繁地随着使用者點選“關注“/“取消關注”而變化。對于hbase來講,新的資料更新總會進入memstore,然後滿了就會寫filestore。如果A和B在一個column family,那麼這個寫入的過程是要A和B兩列都要寫的。但實際上A的資料可能壓根就沒變,是以直覺上A列的寫入浪費了IO。如果A和B拆到兩個column family,那麼B的

手遊拍賣

更改隻會引發他自己的filestore寫入。

壓縮(compression)方式不一樣。HBase允許為每個column family配置一個compressor。問題是不同資料類型适合的壓縮方式不一樣。比如文本很适合壓縮。但是類似于jpg和png這種圖檔就不适合——它們的資料本身已經是被壓縮的了,再壓一遍隻是浪費CPU而已。但是如果不同類型資料在同一個column family,就意味着它們要共享同一個壓縮方式。這時也許需要考慮将他們拆開成不同的column family。

權限管理。HBase的ACL控制可以定義每個column family可以定義不同的權限。是以如果有希望一撥人能通路列A、B、C,另外一撥人通路列D、E、F這樣的需求,可以考慮使用column family。

那麼為什麼一般都不建議弄很多個column family呢?因為太多了會影響性能,比如做file compact和file splict時,備選的檔案會增多(記得每個column family都會增加一批檔案);比如說memstore裡要為每個column family配置設定一部分空間。畢竟我們用HBase的原因是希望他能高吞吐明顯影響性能就得不償失了。于是乎設計時就要折衷,比如上面産品詳情和關注數的例子,我們是可以考慮直接拆成兩個HBase table然後再進行app join的。

總之,trade off is everything