千億級服務器監控數據存儲實踐

HBase 大數據 MySQL Hadoop 中國存儲 2017-06-28

導語

公司目前有幾十萬臺左右服務器,TMP(騰訊監控平臺)平均每天採集1200億+監控數據,本文將從當前存儲架構存在的問題出發,介紹使用大數據平臺組件Hbase存儲TMP監控數據的實踐歷程。

背景

近幾年開源的大數據處理系統已經逐步發展到一個比較成熟的階段了,各類大數據處理的場景都有了相應的解決方案,如同 mysql 在當今互聯網公司中的關係數據存儲廣泛應用地位一樣。

公司目前有幾十萬臺量級的服務器,TMP 系統按 1 分鐘粒度採集監控數據,平均每天採集 1200 多億的數據點。本文將從當前存儲架構存在的問題出發,介紹從嘗試使用 Opentsdb 到自行設計 Hbase 存儲方案來存儲 TMP 服務器海量監控數據的實踐歷程。

TMP 當前存儲架構分析

我們首先看下當前的 TMP 的 1 分鐘粒度數據存儲架構。Agent 上報的數據,通過 collector 從 mysql 數據表中查詢索引和路由規則 a,分發到不同的數據存儲結點上。數據節點 Datacache 收到數據後先緩衝到內存中,內存的數據定期 DUMP 到文件系統中。

千億級服務器監控數據存儲實踐

這套架構優點很明顯,設計簡潔、有新數據緩存、數據分佈式存儲、可橫向擴展,同時完全自研,各自實現細節可控。但同樣存在一些問題:

a.數據節點 Cache 程序異常,會導致內存緩存數據丟失,進而丟失監控數據,需要從 agent 端或者對等集群恢復;

b.數據節點磁盤故障或機器故障,持久化的 FILE 也會丟失,數據同樣需要從對等集群中恢復,數據訪問入口需要人工介入切換集群;

c.數據格式和佔用空間固定,不具備監控粒度擴展性,空的數據點也要佔據存儲空間,數據不支持壓縮;

d.索引和路由規則這類依賴外部 DB 系統,這些 metadata 的可用性影響整個系統。

Hbase 存儲引擎優勢

Hbase 是 Hadoop 生態棧中的分佈式列存儲數據庫,基於 Bigtable 模型和 LSM-Tree 存儲引擎,用於海量數據的隨機讀寫,在業界的大規模監控系統的時序數據存儲中已有成熟應用案例,如某度和某寶 。

千億級服務器監控數據存儲實踐

圖 1. Hbase 的存儲原理

我們看下使用 Hbase 存儲有何優勢:

a.數據高可靠,高可用。數據在寫內存的同時,會寫一份 HLog 到 HDFS 中,如果某臺 RegionServer 異常,內存中的數據會從 Hlog 中自動恢復。持久化數據保存在 HDFS 中,默認持有 3 個副本,無單點丟失數據風險。

b.高性能。LSM-Tree 存儲引擎保證了 Hbase 超高的寫性能,實際上前面介紹的 TMP 自研存儲系統也是一種簡化版的 LSM-Tree 存儲引擎,因而同樣有如此高的性能。

c.天然的水平伸縮,高可擴展性。存儲層 DataNode,數據服務層 RegionServer 均支持自由伸縮擴容。

d.數據表支持壓縮,空列不佔存儲空間。

Opentsdb 嘗試及瓶頸分析

在準備使用 Hbase 存儲 TMP 監控數據之初,我們曾嘗試使用基於 Hbase 的開源時序數據庫 Opentsdb 來直接存儲服務器監控數據。但 Opentsdb 到 70w/s 的時候整個 Hbase 集群就已超負荷運轉、響應緩慢了,完全無法滿足如此大規模的存儲需求。

我們仔細分析了 Opentsdb 在超大規模時序數據存儲上存在的主要瓶頸:

a.所有 metric 跟 tag 都要經過 tsdb-uid 表的轉換,此設計本意是為了壓縮 rowkey 大小,但引入較大的計算資源開銷;

b.數據寫入的 Append 機制及原始 compaction 設計存在較大的性能問題,這在後面部分會詳細分析;

c.所有的數據都放在同一張表裡,不利於基於時間對數據進行維護操作,比如對一個月前非熱點數據進行抽樣存儲,且無法控制 Region 數,也就無法控制 split,對性能影響較大;

基於這些原因,我們最終決定直接使用 Hbase 進行 TMP 服務器監控數據存儲。

TMP 監控存儲設計實踐

Hbase 的使用在整個 hadoop 生態棧中屬於較為複雜的一個類別。TMP 監控存儲設計結合了業界使用 Hbase 的一些成熟的實踐經驗,同時參考和改進了 OpenTSDB 在使用 HBase 時的比較好的設計思想,以支撐 TMP 監控數據的大規模讀寫。

2.1 Region 預切分

Hbase 中的數據會按 rowkey 所處範圍分佈在各個 Region 中,新建表的時候只有一個 Region,並隨著 Region 變大開始分裂。這在過程中會消耗大量在網絡、磁盤 IO 等資源,對集群會有較大性能影響。同時由於開始期間只有少量 Region,數據的讀寫很容易全落在單臺 RegionServer 上,造成 HotSpot 現象,嚴重影響讀寫性能。因此對存儲表進行 Region 預切分處理是 Hbase 使用中十分重要的一步。

這裡我們將每天的數據表預切分為 100 個 Region, 以{0x01, 0x01 … 0x63},即二進制的 1~99 為 splitKeys,第一個 Region Rowkey 範圍為 [0x00…~0x01],第二個 Region Rowkey 範圍為 [0x01…~0x02],以此內推。結合接下來這節中的 Rowkey salt 設計就可以均勻地將數據分散在各 Region 中。

2.2 Rowkey 和列設計

Rowkey 設計由 salt(1 byte) 服務器 ID(4 byte) timestamp(4 byte) 監控特性 ID(4 byte) 的方式組成。

a.Salt 是使用服務器 id 進行 hash 後對單表初始 Region 數進行求餘所得的一位字節,用來將不同服務器的監控數據 均勻分佈在表的各個 Region 中 ;

b.Rowkey 第二部分為服務器 ID,服務器監控數據查詢通常是查詢指定服務器的某些特徵,因而將服務器 ID 放在第二部分可以大幅提高查詢效率;

c.timestamp 實際上是一個 time-base,用於將一段時間內的數據存放在同一行;

d.attr_id 為特性 id,區分具體監控指標。

這裡使用一個字節 t 作為列族,列族名稱本身並沒什麼含義,主要強調只使用一個列族存儲數據,儘量小的名稱作為名字。使用多列族每個 Region 會對應有多個 Memstore,會加重內存消耗,在此場景下不適用。

列名(在 Hbase 中稱 Qualifier)為時間偏移,與 Rowkey 中的 time-base 一起組成 timestamp 標識數據點的時間。

2.3 基於列的 Compaction

在介紹列 Compaction 之前,我們先看下 Hbase 數據的具體存儲結構:

千億級服務器監控數據存儲實踐

如圖所示為表結構以及對應的存儲結構示例,在 Hbase 或表格存儲這類底層採用 LSM-tree 的數據庫中,表數據會按列存儲。每行中的每一列在存儲文件中都會以 Key-value 的形式存在於文件中。其中 Key 的結構為:行主鍵 列族 列名,Value 為列的值。該種存儲結構的特點是:

a、每行主鍵會重複存儲,取決於列的個數;

b、列名會重複存儲,每一列的存儲都會攜帶列名;

c、存儲數據按 row-key排序,相鄰的 row-key會存儲在相鄰的塊中。

可以注意到,在 Hbase 的物理存儲中,每一列都會存儲該列的 rowkey 和列族信息,在列很多的情況下這些重複的信息將佔用大量的存儲空間。因此這裡參考 Opentsdb 的做法,將同一 time-base 內的所有列合併壓縮為一列(注意這裡說的列 Compaction 與 HBase 本身的 Compation 是完全不同的,Hbase 的 Compation 是指將多個小的 HFile 合併為一個大的 HFile)。

Opentsdb 的列 Compaction 由數據量大小和時間間隔共同觸發,在併發寫操作巨大的時候會對 Hbase 產生很大的讀寫壓力,並且會阻塞寫操作,性能表現較差。2.2 版本加入的 append 機制更是每一次寫操作產生一次讀操作,對 Hbase 利用很不經濟,寫入量大時會對整個集群的讀壓力造成巨大影響。

基於這些原因,TMP 監控數據在每天凌晨對前一天的數據表進行全表掃描,並對每行數據的列名(Qualifier)和 Value 進行合併,壓縮為一列。在現網實際環境中可以看到, 列壓縮後的數據表比壓縮前佔用存儲空間減少接近90%,如下圖 。

2.4 Hbase 性能調優

Hbase 性能調優是個比較複雜的事情,網上可以看到很多專門講 Hbase 調優的文章。這裡僅挑出幾個比較立竿見影的點來分享。

a.Heap 和 Memstore 大小。儘量調大 RegionServer 的 heap 大小,如寫入量遠大於查詢量,可以增大 Memstore 與 BlockCache 的比例,如 0.5 : 0.3 。原因是 HBase 基於 LSM Tree 的存儲引擎,數據會先緩存至 Memstore 再刷入磁盤

b.Snappy 壓縮。對數據表啟用 Snappy 壓縮,可以減少磁盤 IO,增大寫入性能

c.Hbase 自身的 Compation 線程數。Hbase 在 flush 和 compaction 的時候會對 rowkey 進行排序操作,適當增大 compaction 線程,可更加充分利用 CPU,增加性能。具體可將 hbase.regionserver.thread.compaction.small/large 調節為 5。

d.GC 調優。GC 參數設置不當會觸發 Stop the world 這類嚴重影響性能的問題,具體可參考這篇文章 《HBase最佳實踐-CMS GC調優》

總結

千億級服務器監控數據存儲實踐

基於上述設計和優化後, TMP 監控數據存儲方案比直接使用 Opentsdb 存儲性能提高了 3~5 倍,8 臺 RegionServer 峰值寫入速率可達 400w/s ,Opentsdb 則到 70w/s 的時候整個 Hbase 集群就已經無法正常工作了。

目前此套基於 Hbase 的監控數據存儲系統已經上線提供服務,後續計劃在入庫 Hbase 之前加入緩衝層進行列的預 Compaction,可進一步成倍提升整體性能。HBase 發展至今已是個比較成熟的開源分佈式數據庫,其高性能,高可用性及高可擴展的特性,可為海量數據的存取提供強大動力。

相關推薦

推薦中...