深入淺出hbase和bigtable
關於hbase的實現,基本遵循bigtable的論文,而這篇論文的核心就是:
- 一個分散式的kv存儲,如何設計key value,可以讓模型更具有業務實用性
- 分散式一致性設計範式:在分散式系統中,哪些組件可以是無狀態的
- 分散式系統工程實踐的範式:三副本的情況下如何降低rt(response time)
1. 如何理解sorted map和column family
bigtable論文的精髓點就在於分散式的有序map,一切設計也是圍繞這個結構:
A Bigtable is a sparse, distributed, persistent multidimensional
sorted map. The map is indexed by a row
key, column key, and a timestamp; each value in the mapis an uninterpreted array of bytes.
結構寫出來是這樣:
(row:string, column:string, time:int64) -> string
難點:column family如何理解:
相同的column family 不同的column key的數據會被物理上存儲在一起,方便進行一起range scan。column family 有一點類似於rdbms中的multi-column index,如果沒有column family,那麼bigtable的存儲模型就是完全的kv range型的,而有了column family,則可以豐富查詢方式,加快同一個column family下的range scan,是一種物理上將一行中某幾個部分數據順序存儲在磁碟的聲明,類似於spanner中的parent-child table relation。
難點2:業務中如何設計rowkey和column family,這個在下面詳細討論。
2. hbase中的組件
從一次put請求涉及的組件來熟悉hbase的不同組件,其中
hbase region server = bigtable tablet
hdfs, hlog, dfs client = gfs 中的相應概念
每個region server主要處理一段key range的請求,而哪些key range需要路由到什麼region server的信息保存在其中一個region server上,這麼說可能有一點繞,來看一個實際的寫入例子。
如圖,client發起一次put請求後,涉及到的主要調用,同步的包括:
- 通過zk獲得region server地址
- region server 把一個row put,變成多句 kv put
- 先寫入HLog,作為WAL log
- 寫入MemStore
- 返回
其中通過zk獲得region server地址的行為又可以精細化為:
- 從zk中獲取meta table的region server
- 讀取meta table的region server獲取rowkey的真實region server
在同步調用中,不同的column family的寫入都在同一個Hlog,也對應著同一個DataNode,所以單行的更新,涉及多個column family,即使最終這些數據會分別寫入到不同column family對應的Hfile中,仍然是可以保證atomic和duration,isolation和visibility沒有保證,所以嚴格說不能算單行「事務」,但如果從事務要麼一起成功,要麼一起失敗這種狹隘定義來看,也可以算單行「事務」。
3. 如何設計rowkey和column family
首先,應該考慮到rowkey設計中不同於關係型資料庫的表結構的幾個反直覺點:
- 查詢必須要帶rowkey,至少也需要拼出rowkey範圍,否則效率極低
- rowkey由用戶自行定義且用戶自行保證rowkey唯一性
雖然很多的大型業務團隊也使用一套自己的seq id generator,但大部分的小型業務都是直接依賴資料庫提供的單調遞增id,沒有自行保證seq id唯一性且把有意義的業務欄位放入到seq id加速查詢和保證分散式全局唯一的經驗。
在這裡,可以參考OPENTSDB的設計經驗,它的rowkey為 [metric_type][event_timestamp],這個rowkey非常適合指定metric_type下的timestamp range查詢。(這個rowkey可能也不是完美的,這個設計下的寫入會集中在同一個region server,導致寫入熱點,達不到分攤寫入流量的目的,但是,假如沒用timestamp做後綴結尾,而是假如一個後綴結尾隨機數來把寫流量分攤到更多的region server,又會影響讀取效率,請自行判斷trade off)
整理clumn family的設計原則:
- 沒想好如何拆分的時候,就只用一個column family
- 把需要一起被取出的所有列放在同一個column family中
- 當range scan的時候,確定不需要獲取的列放在另一個column family
4. REF
big table 論文:https://static.googleusercontent.com/media/research.google.com/en//archive/bigtable-osdi06.pdf
hbase 的schema desgin建議:http://0b4af6cdc2f0c5998459-c0245c5c937c5dedcca3f1764ecc9b2f.r43.cf2.rackcdn.com/9353-login1210_khurana.pdf
hbase datamodel:Apache HBase ? Reference Guide
推薦閱讀:
※什麼鬼!基於備份恢復的數據還能變多?
※Python採集微博熱評進行情感分析祝你狗年脫單
※七周成為數據分析師:SQL,從熟練到掌握
※sql中插入中文問題