分佈式結構化存儲系統-HBase應用案例mysql
做者:尹正傑sql
版權聲明:原創做品,謝絕轉載!不然將追究法律責任。數據庫
爲了讓讀者更進一步瞭解HBase在實際生成環境中的應用方法,在董西成的書裏介紹兩個經典的HBase實際應用案例,分別是社交關係數據存儲和時間序列數據庫OpenTSDB。我這裏手抄記錄一下。服務器
一.社交關係數據存儲微信
互聯網領域很大一類應用是社交關係數據,國內的新浪微博和微信,國外的Twitter和Facebook等,均是典型的表明。社交關係數據主要維護了Follower-folowed用戶關係,即用戶關注和被關注信息,目前有專門的圖數據庫很是適合存儲這些數據,但經過介紹HBase的方案,能夠幫助讀者更深刻理解HBase數據建模方法和應用技巧。 對於社交關係數據的存儲,一般有如下幾個功能需求:
(1)讀數據要求
1)查看用戶A關注來哪些用戶;
2)查看哪些用戶關注了用戶A;
3)查看用戶A是否關注了用戶B;
(2)寫數據要求
1)用戶A增長了一個新的關注者;
2)用戶A取消了對用戶B的關注;
爲了實現上述功能,對照HBase的數據模型,很容易嚮導以下圖所示的數據模型(咱們暫時稱爲模型A)
在該數據模型中,rowkey被設置爲userid以方便查找和定位,column family爲follows,其內部的每一列保存了一個關注着信息,以下圖所示:
模型A可以很好地解決讀數據要求中的第一條和第三條,但第二條很是低效,須要遍歷整張表查找哪些用戶關注了某個特定喲哦那個戶,另外,爲特定用戶增長一個新的關注者也很是困難;難以高效地肯定應爲新關注者賦予什麼編號,一種解決思路是新增一例counter,記錄最小可用編號值,但這將引入事務問題:counter值的更新沒法保證原子性,用戶需在應用層解決這一問題。 爲了解決模型A存在的問題,咱們該用以下圖所示的模型B,與模型A不一樣的是,用戶ID被用做列名,每列對應的cell值爲任意數值。該模型可以很高解決大多數需求,惟獨第二個讀要求:「查看哪些用戶關注了用戶A」,這是因爲HBase僅提供了基於rowkey的索引,所以,爲了查找哪些用戶關注了用戶A,須要遍歷整個表。
爲了進一步優化模型B,可考慮如下兩種方案: (1)構造第二張表,保存逆序關係,即用戶X以及關注X的用戶列表。 (2)在同一張表中保存用戶X關注的用戶列表以及關注X的用戶列表。
以方案2爲例,能夠獲得以下圖所示的模型C。
在該模型中,column family名稱被改成「f」以減小數據存儲空間和網絡傳輸數據量,同時將前面的「寬表」改成「窄表」,即表中的rowkey由用戶ID被關注用戶ID組合而成,column family中只有一列。 以下圖所示,給出了一個模型C的實例。
爲了劃整化rowkey,避免rowkey長度致使每次請求返回的數據量不一(形成調試困難),可將用戶ID映射成等長的hash值,組裝成rowkey,好比「md5(userID1)+md5(userID2)」。
二.時間序列數據庫OpenTSDB網絡
OpenTSDB是基於HBase構建的分佈式,可伸縮的時間序列數據庫(Time Series Database),它是一個典型應用場景是實時採集,存儲和展現各種監控指標(metric)信息(好比集羣中的網絡設備,操做系統,應用程序的監控信息),具備擴展性好,可以永久存儲全部監控指標等優勢。
1>.OpenTSDB數據模型架構
爲了規範化指標數據,OpenTSDB對指標進行了規範化,在OpenTSDB中,一條指標數據由如下幾個屬性構成:
(1)metric
metric名稱,好比CPU利用率。
(2)tags
用來描述metric的標籤,由tagk和tagv組成,即tagk=tagv。
(3)value
metric實際的值。
(4)timestamp
時間戳,描述value對應的時間點。
在實際應用中,一條MySQL數據庫相關的metric數據格式以下(表示某個時刻做用在某個表上的慢查詢的數目):
metric : mysql.slow_queries
timestamp : 1454557429
value : 100
tags : schema=userdb
監控系統最主要讀需求是,將一段時間內的metric數據取出,並經過曲線圖形化展現出來,以下圖所示:
2>.OpenTSDB存儲方式異步
OpenTSDB採用HBase存儲metric數據,若是僅考慮metric,timestamp和value三個屬性,一種可行的存儲方案(記爲方案A)以下:把HBase看成一個簡單的key/value存儲系統,其中key是由timestamp和metric組合而成,以下圖所示。
方案A可以知足讀寫需求,經過一個簡單的HBase scan操做即獲取某一時間段內的特定metric數值,但因爲該方案直接以字符串的方式保存metric名稱,會形成大量存儲空間的浪費。爲了對其進行優化,可對metric進行數值編碼,直接將編碼後的數字保存到rowkey中,進而產生以下圖所示的方案B。
在實際應用中,方案B仍存在性能問題:HBase自動按照rowkey排序,這使得最近的metric數據被緊挨着存儲在同一個RegionServer上,考慮到數據局部性特色(最新的數據訪問頻率最高),這將致使某個RegionServer讀請求負載太重。爲了解決該問題,一種可行的優化方式是將rowkey中timestamp和metric兩個字段位置互換一下,進而出現了以下所所示的方案C。
方案C可以很好均衡各個RegionServer的讀負載,可提升讀性能,但每次讀取一個時間區間的metric數值時,須要掃描多行數據,這明顯要慢於只讀一行或者若干行的狀況,爲了進一步提升性能,可將多行數據壓縮存儲到一行中(極爲方案D),以下圖所示。
在方案D中,每行數據保存了特定metric在一小時內的數值,其中rowkey中的timestamp爲整點時間戳,而各列名則爲相對於該整點時刻的偏移量,經過這種方式,在節省存儲空間(時間偏移量佔用空間要小於時間戳)的同時,可加快數據讀性能(主要讀請求爲區間掃描)。在方案D基礎上,將tags編碼後,保存到rowkey尾部,則造成了OpenTSDB完整的數據存儲方式。
3>.OpenTSDB基本架構分佈式
OpenSTDB架構如上圖所示,各個模塊功能以下: (1)Server OpenTSDB的代理,經過Collector收集數據,推送數據。 (2)TSD 是對外通訊的無狀態服務器,對數據進行彙總和存取。 (3)HBase TSD收到數據後,經過異步客戶端將數據寫入到HBase。