本文首發於 vivo互聯網技術 微信公衆號
連接: https://mp.weixin.qq.com/s/qayKiwk5QAIWI7-nyD3FVA
做者:DuZhimin
隨着互聯網、尤爲是物聯網的發展,咱們須要把各類類型的終端實時監測、檢查與分析設備所採集、產生的數據記錄下來,在有時間的座標中將這些數據連點成線,往過去看能夠作成多緯度報表,揭示其趨勢性、規律性、異常性;往將來看能夠作大數據分析,機器學習,實現預測和預警。前端
這些數據的典型特色是:產生頻率快(每個監測點一秒鐘內可產生多條數據)、嚴重依賴於採集時間(每一條數據均要求對應惟一的時間)、測點多信息量大(實時監測系統均有成千上萬的監測點,監測點每秒鐘都產生數據,天天產生幾十GB的數據量)。數據庫
基於時間序列數據的特色,關係型數據庫沒法知足對時間序列數據的有效存儲與處理,所以迫切須要一種專門針對時間序列數據來作優化處理的數據庫系統。微信
時序數據是基於時間的一系列的數據。架構
時序數據庫就是存放時序數據的數據庫,而且須要支持時序數據的快速寫入、持久化、多緯度的聚合查詢等基本功能。機器學習
對比傳統數據庫僅僅記錄了數據的當前值,時序數據庫則記錄了全部的歷史數據。同時時序數據的查詢也老是會帶上時間做爲過濾條件。分佈式
毫無遺漏的接收並存儲大量的時間序列數據。工具
咱們來看一下這樣一段信息:2019-12-5 22:31:21版本號爲‘3.2.1’的某產品客戶端的首頁PV是1000Woop
上面描述2019-12-5 22:31:21版本號爲‘3.2.1’的某產品客戶端的首頁PV是1000W,就是1個DataPoint。性能
從OpenTSDB的部署架構中咱們看到OpenTSDB是創建在HBase之上的,那麼HBase又是啥呢?爲了更好的剖析OpenTSDB,這裏咱們簡要介紹一下HBase。學習
一、HBase是一個高可靠性、強一致性、高性能、面向列、可伸縮、實時讀寫的分佈式開源NoSQL數據庫。
二、HBase是無模式數據庫,只須要提早定義列簇,並不須要指定列限定符。同時它也是無類型數據庫,全部數據都是按二進制字節方式存儲的。
三、它把數據存儲在表中,表按「行鍵,列簇,列限定符和時間版本」的四維座標系來組織,也就是說若是要惟必定位一個值,須要四個都惟一才行。下面參考Excel來講明一下:
四、對 HBase 的操做和訪問有 5 個基本方式,即 Get、Put、Delete 和 Scan 以及 Increment,HBase 基於非行鍵值查詢的惟一途徑是經過帶過濾器的掃描。
五、數據在HBase中的存儲(物理上):
六、數據在HBase中的存儲(邏輯上):
若是你第一次用你的HBase實例運行OpenTSDB,須要建立必要的HBase表,OpenTSDB 運行僅僅須要四張表:tsdb, tsdb-uid, tsdb-tree 和 tsdb-meta,全部的DataPoint 數據都保存在這四張表中,建表語句以下:
create 'tsdb-uid', {NAME => 'id', COMPRESSION => 'NONE', BLOOMFILTER => 'ROW', DATA_BLOCK_ENCODING => 'PREFIX_TREE'}, {NAME => 'name', COMPRESSION => 'NONE', BLOOMFILTER => 'ROW', DATA_BLOCK_ENCODING => 'PREFIX_TREE'}
create 'tsdb', {NAME => 't', VERSIONS => 1, COMPRESSION => 'NONE', BLOOMFILTER => 'ROW', DATA_BLOCK_ENCODING => 'PREFIX_TREE'}
create 'tsdb-tree', {NAME => 't', VERSIONS => 1, COMPRESSION => 'NONE', BLOOMFILTER => 'ROW', DATA_BLOCK_ENCODING => 'PREFIX_TREE'}
create 'tsdb-meta', {NAME => 'name', COMPRESSION => 'NONE', BLOOMFILTER => 'ROW', DATA_BLOCK_ENCODING => 'PREFIX_TREE'}
後面將對照實際數據來專門講解這四張表分別存儲的內容。
從上面看,四個表裏面的數據都是空的
@Test public void addData() { String metricName = "metric"; long value = 1; Map<String, String> tags = new HashMap<String, String>(); tags.put("tagk", "tagv"); long timestamp = System.currentTimeMillis(); tsdb.addPoint(metricName, timestamp, value, tags); System.out.println("------------"); }
發現HBase裏面有數據,在tsdb-uid、tsdb、和 tsdb-meta 表裏面有數據,而tsdb-tree 表裏面沒任何數據,下面咱們針對這些數據作一下具體分析。
它是一張索引表,用於展現樹狀結構的,相似於文件系統,以方便其餘系統使用,這裏咱們不作深刻的分析。
經過配置項tsd.core.tree.enable_processing來打開是否須要往此表裏面寫入數據。
這個表是OpenTSDB中不一樣時間序列的一個索引,能夠用來存儲一些額外的信息,該表只有一個列族name,兩個列,分別爲ts_meta、ts_ctr。這個表裏面的數據是能夠根據配置項配置來控制是否生成與否,生成幾個列,具體的配置項有:
tsd.core.meta.enable_realtime_ts tsd.core.meta.enable_tsuid_incrementing tsd.core.meta.enable_tsuid_tracking
Row Key 和tsdb表同樣,其中不包含時間戳,<metric_uid><tagk1><tagv1>[...<tagkN><tagvN>]
ts_meta Column 和UIDMeta類似,其爲UTF-8編碼的JSON格式字符串
ts_ctr Column 計數器,用來記錄一個時間序列中存儲的數據個數,其列名爲ts_ctr,爲8位有符號的整數。
tsdb-uid用來存儲UID映射,包括正向的和反向的。存在兩列族,一列族叫作name用來將一個UID映射到一個字符串,另外一個列族叫作id,用來將字符串映射到UID。列族的每一行都至少有如下三列中的一個:
若是配置了metadata,則name列族還能夠包括額外的metatata列。
時間點數據就保存在此表中,只有一個列簇t:
column qualifier 佔用2 Bytes或者4 Bytes,
佔用2 Bytes時表示以秒爲單位的偏移,格式爲:
佔用4 Bytes時表示以毫秒爲單位的偏移,格式爲:
value 使用8 Bytes存儲,既能夠存儲long,也能夠存儲double。
若是須要支持特大批量時序數據,建議使用Druid或InfluxDB,其中InfluxDB是最易用的時序數據庫。
更多內容敬請關注vivo 互聯網技術微信公衆號
注:轉載文章請先與微信號:Labs2020聯繫。