HiTSDB 時序數據庫技術架構和產品解析
8月24日阿裏雲數據庫技術峰會上,來自阿裏數據庫事業部高級專家鍾宇帶來HiTSDB 時序數據庫方麵的演講。本文主要從時序數據開始介紹,包括時序序列數據的特點,接著介紹了時序數據業務場景,以及OpenTSDB在HBase上的優化,最後分享了HiTSDB的優化和提高。
時序數據介紹
時序數據就是在時間上分布的一係列數值,時間和數值是兩個關鍵字,時序數據一般指指標型數據,比如股票價格、廣告數據、氣溫變化、網站的PV/UV、個人健康數據、工業傳感器數據,還有關於應用程序的性能監控,像服務器係統監控數據,比如cpu和內存占用率,此外還有車聯網。
據統計,在大數據領域中時序數據會超過一半。
圖為廣告的監測數據,可以看到事例中跟蹤了三個廣告來源,每個來源跟蹤了三個指標,包括展示了多少次、點擊了多少次以及產生了多少收入。廣澳來源是用不同的標簽來區分的,比如由誰發布、廣告商、針對目標用戶的性別和發布在哪個國家等。 大家可以清晰的看到每個指標,在不同的時間點有不同的數值,這就構成了一係列的時間數據。左邊成為數據源,中間成為metric,右邊稱為時間序列,時間序列在時間上具有不同的值,
如果對時間序列建模會有兩種方式,一種是單值,一種是多值。單值是把每一個數據源的每一個指標的每一個值當成一行。多值模型是把同一個數據源的不同指標放在不同列中,也就是每個數據源在每個時間點隻會產生一行數據。
多值模型一定能用單值模型來模擬,多值模型在處理某些數據時更方便些,但是單值建模可以模擬所有場景。
時間序列數據的處理和一般數據庫處理有所不同,一般數據庫基於行,每一個數據點是一行,時間序列數據是按時間線處理數據。每個時間線上的數據是非常關聯的,比如某一個廣告源收入在不同時間上就構成時間序列,這些時間序列中的收入可以畫成一條變化曲線,針對曲線我們可以做時間序列變化處理,最常見的是插值和降精度。由於數據源采樣的原因,往往會丟失一些點,我們用插值在中間插上常見的線性插值或者零值補償;如果廣告數據不一定需要最細時間粒度來看,我們就可以降精度,不同數據降精度的方式不一樣。
針對時間數據,還有一個最常見的處理——聚合,我們往往看的不僅僅是從一個數據源來的指標,如果我們要看北美地區某一個廣告源在一段時間內產生的所有收入的總和,我們就需要把跟廣告源標簽對應的時間線全部挑出來,然後將廣告收入時間點加和在一起,得到一個新的求和曲線,如圖所示,我們找到了非常多的時間線,最後用某種聚合函數聚合在一起。每一種業務需要的聚合方式也是不一樣的,比如廣告數據算加和,或者按廣告源作平均,也有可能找最大最小值,或者作統計性事情,比如99%值都在某個數值以上。
時間序列數據的特點
因此,我們得出時間序列特點包括以下幾方麵:
- 持續產生大量數據。不論是廣告監控還是傳感器、氣溫,它針對的情況很多。比如監控工業園區中燈的耗電量,每盞燈就會有傳感器實時傳輸燈耗電量,如果采樣間隔是一秒鍾,每盞燈每一秒就會產生一個數據點,幾萬盞燈沒秒就會有幾萬次寫入,如果涉及樓宇多,就會產生每秒幾百萬上千萬的寫入。
- 數據產生率平穩,無明顯的波峰穀。這帶來了優化的好處和壞處,好處是不會產生明顯的峰值,所以在做容量評估時會比較方便;壞處是沒辦法在閑暇時間做數據合並和補償的工作。
- 近期的數據關注度更高。
- 時間久遠的數據,極少被訪問,甚至不再需要。所以時間序列數據一般需要數據回滾功能。
- 數據存在多個維度的標簽。
- 展示或使用時往往需要對數據做聚合計算。
時序數據業務場景
阿裏巴巴鷹眼係統
阿裏巴巴鷹眼係統能跟蹤一個分布式係統的係統調用情況,其中就有監控應用指標。包括係統內存處理器占用以及應用本身的TPS和QPS,在實際內部的阿裏巴巴係統中,去年的寫入峰值是570萬點/秒,平均寫入350萬點/秒,產生了上萬個不同的metric,幾千萬個時間序列,每個時間序列平均有5個維度(tags),每秒幾百次聚合展示。
阿裏巴巴智慧園區
還有物聯網方麵,物聯網數據與係統監控很像,你可以把設備中的傳感器想象成服務器應用的不同指標,比如每盞燈、每個空調出風口的溫度等都有指標,阿裏巴巴接入的數據跨越兩個城市,三個園區,有數以萬計的設備,每秒產生數百萬的采集點,要求數據寫入立即可用。
當傳統數據庫遇到時間序列數據
時間序列數據存到傳統數據庫中會遇到一些問題,例如時間序列數據直接保存到關係數據庫中(例如MySQL 的InnoDB引擎),使用SQL語句進行分析。這裏就會遇到以下一些問題:
1. tag重複存儲,存儲開銷大,如果將模型變成MySQL的行時,每個數據點會產生獨立的行,也就是標簽會重複存儲,在一個時間序列上每個數據點需要保存到標簽重複存儲一遍,這樣才能用標簽把這個序列上所有的數據點找出來。
2. 可以用聯合索引部分解決多維度的問題,但是進一步增加了存儲的開銷。
3. B樹索引在持續寫入的時候產生大量隨機IO,寫性能迅速下降,多聯合索引加劇了寫入慢的問題,InnoDB是用B+Tree進行索引的,為了數據查詢快,一般會根據標簽不同組合建立不同索引,當寫入數據時,不同標簽寫進去的數據排序是不一樣的,大部分的標簽在寫進去時會在索引上產生隨機插入。
4. 數據量大導致索引/數據很容易超過內存容量,查找/聚合性能不高。查詢時會導致大量的磁盤IO的開銷。
5. 降精度的SQL子查詢很難被SQL優化器優化。
OpenTSDB在HBase上的優化
OpenTSDB時間序列數據庫架構如圖所示,它的存儲基於HBase,HBase具有高性能,可以線性擴展。TSD被設計為無狀態節點,任何一個節點可以隨時替換另一個節點進行服務,對外提供的RPC協議是HTTP/Json接口,很方便使用。TSD依賴HBase解決一致性,當TSD產生寫時,它一定會將寫及時更新到HBase, 而產生讀不命中時候,也會從HBase中將數據讀回來。
OpenTSDB 存儲格式如圖所示,它的存儲上做了很多針對時序的考慮和優化。
- 最核心的點是將Tags壓縮,將tags分成兩個級別,第一個級別有一個表將tags轉換成 id,所有的tags id和指標的名稱以及時間一起被組合成row key,row key實際上是OpenTSDB保存的行鍵,每一行中重複存儲隻有row key,row key 實際上是每一個tags都被轉換成了整型,row key 相對來說比較短。
- 每個row key對應時間序列+一個時間戳,時間序列上的數據一直存在時間序列之上,理論上row key 不需要重複保存,所以一個小時的數據保存在同一行裏,OpenTSDB的存儲格式中每一行有3600個列,每個列對應一個小時內的點,而這一小時的時間邊界、指標名稱、id一起構成了row key。row key重複存儲的空間就變成了按行設計的1/3600,大大地壓縮了row key。
- Row key的構建也經過了很好的設計,時間位於metric和tags之間,不需要預先定義數據格式,保證了靈活性;tags掃描時候,我們經常遇到的場景是聚合,需要找到某個tags的一係列時間線,OpenTSDB場景中,在tags和搜索條件正好滿足前綴規則時可以很好的優化,如果共有三個標簽園區、樓、樓層構建row key,如果搜索園區,掃過的數據就是我們要的數據,別的園區數據就會排出掉,HBase常見的問題是產生熱點,OpenTSDB用salt機製保證熱點。
OpenTSDB的缺點
OpenTSDB也有很多缺點,具體如下:
- 時間序列的Meta Data以緩存的方式在所有的TSD節點中存在,時間序列太多的時候內存壓力很大
- 以RowScan的方式做多維度查詢,當查詢條件不滿足RowKey的前綴時,會掃過很多無用的RowKey
- 在固定的Column中保存一小時內的時間點,Qualifier存在額外的開銷
- 單點聚合,容易出現聚合性能瓶頸(cpu&memory)
- 通用壓縮算法,壓縮率依然不理想(每個數據點大約消耗20字節,包括了RowKey的開銷)
HiTSDB的優化和提高
倒排索引
參考搜索引擎的倒排索引實現,每個時間序列作為一個文檔,通過tags的倒排索引到時間序列ID,把timestamp + 時間序列ID作為RowKey,取代由timestamp + metric ID + tag IDs拚接成的RowKey。
使用倒排索引的解決的問題和對比如下:
- 倒排索引在集群中的分片和一致性問題,解決辦法:BinLog寫入到HDFS,每個分片一個BinLog文件
- 分片策略的問題:按metric,按特定的tag,還是按metric+tags?
- 倒排索引加速了多維度的任意條件查詢
- 倒排索引可以方便的實現metric和tagkey/tag value的輸入提示
- RowScan vs mget
- 從HBase讀取數據是瓶頸,包括網絡吞吐率和磁盤IO
高壓縮比算法
我們一般認為最近的數據是最熱的,我們希望最近的數據能夠完全的被內存緩存,但是時序數據量比較大,因此我們需要采用高壓縮比算法:平均每個時間點壓縮到1.37字節。timestamp采用delta-delta壓縮,value采用二進製xor壓縮。
高壓縮比使得最近一段時間(若幹小時)的數據可以完全緩存在內存裏,查詢的時候避免了HBase的mget操作。解壓縮速度很快,而且降精度可以在解壓的過程中同時處理,減少內存的開銷。
預降精度功能
我們做了預降精度,HiTSDB會在寫入之前根據很多預測好的降精度級別將數據計算好,預降精度在邏輯上會有一些問題,包括以下幾個方麵:
• 數據老化 vs 預降精度
• 預降精度的級別和額外空間開銷
• 預降精度和實時降精度結合
• 平均值帶來的問題
• 精確計算 vs 概略計算,在預降精度數據上統計P99
• 時間窗口和數據修改
最後更新:2017-08-31 23:32:51