時序數據庫技術體系 – 初識InfluxDB(原理)

原貼地址:http://hbasefly.com/2017/12/08/influxdb-1/?qytefg=c4ft23算法

在上篇文章《時序數據庫體系技術 – 時序數據存儲模型設計》中筆者分別介紹了多種時序數據庫在存儲模型設計上的一些考慮,其中OpenTSDB基於HBase對維度值進行了全局字典編碼優化,Druid採用列式存儲並實現了Bitmap索引以及局部字典編碼優化,InfluxDB和Beringei都將時間線挑了出來,大大下降了Tag的冗餘。在這幾種時序數據庫中,InfluxDB無疑顯的更加專業。接下來筆者將會針對InfluxDB的基本概念、內核實現等進行深刻的分析。本篇文章先行介紹一些相關的基本概念。數據庫

 

InfluxDB 數據模型

InfluxDB的數據模型和其餘時序數據庫有些許不一樣,下圖是InfluxDB中的一張示意表:架構

11

 

1. Measurement:從原理上講更像SQL中表的概念。這和其餘不少時序數據庫有些不一樣,其餘時序數據庫中Measurement可能與Metric等同,相似於下文講到的Field,這點須要注意。curl

 

2. Tags:維度列分佈式

(1)上圖中location和scientist分別是表中的兩個Tag Key,其中location對應的維度值Tag Values爲{1, 2},scientist對應的維度值Tag Values爲{langstroth, perpetual},二者的組合TagSet有四種:性能

location = 1 , scientist = langstroth
location = 1 , scientist = perpetual
location = 2 , scientist = langstroth
location = 2 , scientist = perpetual

 

(2)在InfluxDB中,表中Tags組合會被做爲記錄的主鍵,所以主鍵並不惟一,好比上表中第一行和第三行記錄的主鍵都爲’location=1,scientist=langstroth’。全部時序查詢最終都會基於主鍵查詢以後再通過時間戳過濾完成優化

 

3. Fields:數值列。數值列存放用戶的時序數據。ui

 

4. Point:相似SQL中一行記錄,而並非一個點。編碼

 

InfluxDB 核心概念 – Series

文章《時序數據庫體系技術 – 時序數據存儲模型設計》中提到時間線的概念,時序數據的時間線就是一個數據源採集的一個指標隨着時間的流逝而源源不斷地吐出數據,這樣造成的一條數據線稱之爲時間線。以下圖所示:url

12

 

上圖中有兩個數據源,每一個數據源會採集兩種指標:butterflier和honeybees。InfluxDB中使用Series表示數據源,Series由Measurement和Tags組合而成,Tags組合用來惟一標識Measurement。Series是InfluxDB中最重要的概念,在接下來的內核分析中會常常用到。

 

InfluxDB 系統架構

InfluxDB對數據的組織和其餘數據庫相比有很大的不一樣,爲了更加清晰的說明,筆者按照本身的理解畫了一張InfluxDB邏輯架構圖:

13

 

 

 

DataBase

InfluxDB中有Database的概念,用戶能夠經過create database xxx來建立一個數據庫。

 

Retention Policy(RP)

數據保留策略。很長一段時間筆者對RP的理解都不足夠充分,覺得RP只規定了數據的過時時間。其實否則,RP在InfluxDB中是一個很是重要的概念,核心做用有3個:指定數據的過時時間,指定數據副本數量以及指定ShardGroup Duration。RP建立語句以下:

 

CREATE RETENTION POLICY ON <retention_policy_name> ON <database_name> DURATION <duration> REPLICATION <n> [SHARD DURATION <duration> ] [DEFAULT]

 

其中retention_policy_name表示RP的名稱,database_name表示數據庫名稱,duration表示TTL,n表示數據副本數。SHARD DURATION下文再講。舉個簡單的栗子:

 

 

CREATE RETENTION POLICY "one_day_only" ON "water_database" DURATION 1d REPLICATION 1 SHARD DURATION 1h DEFAULT 

 

InfluxDB中Retention Policy有這麼幾個性質和用法:

1. RP是數據庫級別而不是表級別的屬性。這和不少數據庫都不一樣。

2. 每一個數據庫能夠有多個數據保留策略,但只能有一個默認策略。

3. 不一樣表能夠根據保留策略規劃在寫入數據的時候指定RP進行寫入,下面語句就指定six_mouth_rollup的rp進行寫入:

curl -X POST 'http://localhost:8086/write?db=mydb&rp=six_month_rollup' --data-binary 'disk_free,hostname=server01 value=442221834240i 1435362189575692182'

若是沒有指定任何RP,則使用默認的RP。

 

Shard Group

Shard Group是InfluxDB中一個重要的邏輯概念,從字面意思來看Shard Group會包含多個Shard,每一個Shard Group只存儲指定時間段的數據,不一樣Shard Group對應的時間段不會重合。好比2017年9月份的數據落在Shard Group0上,2017年10月份的數據落在Shard Group1上。

 

每一個Shard Group對應多長時間是經過Retention Policy中字段」SHARD DURATION」指定的,若是沒有指定,也能夠經過Retention Duration(數據過時時間)計算出來,二者的對應關係爲:

14

 

 

問題來了,爲何須要將數據按照時間分紅一個一個Shard Group?我的認爲有兩個緣由:

1. 將數據按照時間分割成小的粒度會使得數據過時實現很是簡單,InfluxDB中數據過時刪除的執行粒度就是Shard Group,系統會對每個Shard Group判斷是否過時,而不是一條一條記錄判斷。

2. 實現了將數據按照時間分區的特性。將時序數據按照時間分區是時序數據庫一個很是重要的特性,基本上全部時序數據查詢操做都會帶有時間的過濾條件,好比查詢最近一小時或最近一天,數據分區能夠有效根據時間維度選擇部分目標分區,淘汰部分分區。

 

Shard

Shard Group實現了數據分區,可是Shard Group只是一個邏輯概念,在它裏面包含了大量Shard,Shard纔是InfluxDB中真正存儲數據以及提供讀寫服務的概念,相似於HBase中Region,Kudu中Tablet的概念。關於Shard,須要弄清楚兩個方面:

1. Shard是InfluxDB的存儲引擎實現,具體稱之爲TSM(Time Sort Merge Tree) Engine,負責數據的編碼存儲、讀寫服務等。TSM相似於LSM,所以Shard和HBase Region同樣包含Cache、WAL以及Data File等各個組件,也會有flush、compaction等這類數據操做。

15

 

2. Shard Group對數據按時間進行了分區,那落在一個Shard Group中的數據又是如何映射到哪一個Shard上呢?

InfluxDB採用了Hash分區的方法將落到同一個Shard Group中的數據再次進行了一次分區。這裏特別須要注意的是,InfluxDB是根據hash(Series)將時序數據映射到不一樣的Shard,而不是根據Measurement進行hash映射,這樣會使得相同Series的數據確定會存在同一個Shard中,但這樣的映射策略會使得一個Shard中包含多個Measurement的數據,不像HBase中一個Region的數據確定都屬於同一張表。

 

InfluxDB Sharding策略

上文已經對InfluxDB的Sharding策略進行了介紹,這裏簡單地作下總結。咱們知道一般分佈式數據庫通常有兩種Sharding策略:Range Sharding和Hash Sharding,前者對於基於主鍵的範圍掃描比較高效,HBase以及TiDB都採用的這種Sharding策略;後者對於離散大規模寫入以及隨即讀取相對比較友好,一般最簡單的Hash策略是採用取模法,但取模法有個很大的弊病就是取模基礎須要固定,一旦變化就須要數據重分佈,固然能夠採用更加複雜的一致性Hash策略來緩解數據重分佈影響。

 

InfluxDB的Sharding策略是典型的兩層Sharding,上層使用Range Sharding,下層使用Hash Sharding。對於時序數據庫來講,基於時間的Range Sharding是最合理的考慮,但若是僅僅使用Time Range Sharding,會存在一個很嚴重的問題,即寫入會存在熱點,基於Time Range Sharding的時序數據庫寫入必然會落到最新的Shard上,其餘老Shard不會接收寫入請求。對寫入性能要求很高的時序數據庫來講,熱點寫入確定不是最優的方案。解決這個問題最天然的思路就是再使用Hash進行一次分區,咱們知道基於Key的Hash分區方案能夠經過散列很好地解決熱點寫入的問題,但同時會引入兩個新問題:

1. 致使Key Range Scan性能比較差。InfluxDB很優雅的解決了這個問題,上文筆者提到時序數據庫基本上全部查詢都是基於Series(數據源)來完成的,所以只要Hash分區是按照Series進行Hash就能夠將相同Series的時序數據放在一塊兒,這樣Range Scan性能就能夠獲得保證。事實上InfluxDB正是這樣實現的。

2. Hash分區的個數必須固定,若是要改變Hash分區數會致使大量數據重分佈。除非使用一致性Hash算法。筆者看到InfluxDB源碼中Hash分區的個數固定是1,對此還不是很理解,若是哪位看官對此比較熟悉能夠指導一二。

 

 

總結

本篇文章重點介紹InfluxDB中一些基本概念,爲後面分析InfluxDB內核實現奠基一個基礎。文章主要介紹了三個重要模塊:

1. 首先介紹了InfluxDB中一些基本概念,包括Measurement、Tags、Fields以及Point。

2. 接着介紹了Series這個很是很是重要的概念。

3. 最後重點介紹了InfluxDB中數據的組織形式,總結起來就是:先按照RP劃分,不一樣過時時間的數據劃分到不一樣的RP,同一個RP下的數據再按照時間Range分區造成ShardGroup,同一個ShardGroup中的數據再按照Series進行Hash分區,將數據劃分紅更小粒度的管理單元。Shard是InfluxDB中實際工做者,是InfluxDB的存儲引擎。下文會重點介紹Shard的工做原理。

相關文章
相關標籤/搜索