1. 簡(jiǎn)述
- 時(shí)間序列數(shù)據(jù):從定義上來(lái)說(shuō),就是一串按時(shí)間維度索引的數(shù)據(jù)。
- 時(shí)序數(shù)據(jù)庫(kù)(TSDB)特點(diǎn):
持續(xù)高并發(fā)寫(xiě)入、無(wú)更新;
數(shù)據(jù)壓縮存儲(chǔ);
低查詢(xún)延時(shí)。 - 常見(jiàn) TSDB:influxdb、opentsdb、timeScaladb、Druid 等。
1.1 influxdb概念
- influxdb是一個(gè)開(kāi)源分布式時(shí)序、時(shí)間和指標(biāo)數(shù)據(jù)庫(kù),使用 Go 語(yǔ)言編寫(xiě),無(wú)需外部依賴(lài)。其設(shè)計(jì)目標(biāo)是實(shí)現(xiàn)分布式和水平伸縮擴(kuò)展,是 InfluxData 的核心產(chǎn)品。
- 應(yīng)用:性能監(jiān)控,應(yīng)用程序指標(biāo),物聯(lián)網(wǎng)傳感器數(shù)據(jù)和實(shí)時(shí)分析等的后端存儲(chǔ)。
- influxdb 完整的上下游產(chǎn)業(yè)還包括:Chronograf、Telegraf、Kapacitor,其具體作用及關(guān)系如下:

有些人也會(huì)選擇 Telegraf (Heapster)+ influxdb + grafana組合。
1.2 與傳統(tǒng)數(shù)據(jù)庫(kù)相關(guān)區(qū)別
- 和傳統(tǒng)數(shù)據(jù)庫(kù)相比,influxdb在相關(guān)概念上有一定不同,具體如下:
| influxdb 中的概念 | 傳統(tǒng)數(shù)據(jù)庫(kù)中的概念 |
|---|---|
| database | 數(shù)據(jù)庫(kù) |
| measurement | 數(shù)據(jù)庫(kù)中的表 |
| point | 表中的一行數(shù)據(jù) |
- point的數(shù)據(jù)結(jié)構(gòu)由時(shí)間戳(time)、標(biāo)簽(tags)、數(shù)據(jù)(fields)三部分組成,具體含義如下:
| point 屬性 | 含義 |
|---|---|
| time | 數(shù)據(jù)記錄的時(shí)間,是主索引(自動(dòng)生成) |
| tags | 各種有索引的屬性 |
| fields | 各種value值(沒(méi)有索引的屬性) |
- 此外,influxdb還有個(gè)特有的概念:series(一般由:retention policy, measurement, tagset就共同組成),其含義如下:
所有在數(shù)據(jù)庫(kù)中的數(shù)據(jù),都需要通過(guò)圖表來(lái)展示,而這個(gè)series表示這個(gè)表里面的數(shù)據(jù),可以在圖表上畫(huà)成幾條線(xiàn):通過(guò)tags排列組合算出來(lái)。 - 需要注意的是,influxdb不需要像傳統(tǒng)數(shù)據(jù)庫(kù)一樣創(chuàng)建各種表,其表的創(chuàng)建主要是通過(guò)第一次數(shù)據(jù)插入時(shí)自動(dòng)創(chuàng)建,如下:
insert mytest, server=serverA count=1,name=5 //自動(dòng)創(chuàng)建表
“mytest”,“server” 是 tags,“count”、“name” 是 fields - fields 中的 value 基本不用于索引
1.3 保留策略(retention policy)
- 每個(gè)數(shù)據(jù)庫(kù)剛開(kāi)始會(huì)自動(dòng)創(chuàng)建一個(gè)默認(rèn)的存儲(chǔ)策略 autogen,數(shù)據(jù)保留時(shí)間為永久,在集群中的副本個(gè)數(shù)為1,之后用戶(hù)可以自己設(shè)置(查看、新建、修改、刪除),例如保留最近2小時(shí)的數(shù)據(jù)。插入和查詢(xún)數(shù)據(jù)時(shí)如果不指定存儲(chǔ)策略,則使用默認(rèn)存儲(chǔ)策略,且默認(rèn)存儲(chǔ)策略可以修改。InfluxDB 會(huì)定期清除過(guò)期的數(shù)據(jù)。
- 每個(gè)數(shù)據(jù)庫(kù)可以有多個(gè)過(guò)期策略:
show retention policies on "db_name" - Shard 在 influxdb中是一個(gè)比較重要的概念,它和 retention policy 相關(guān)聯(lián)。每一個(gè)存儲(chǔ)策略下會(huì)存在許多 shard,每一個(gè) shard 存儲(chǔ)一個(gè)指定時(shí)間段內(nèi)的數(shù)據(jù),并且不重復(fù),例如 7點(diǎn)-8點(diǎn) 的數(shù)據(jù)落入 shard0 中,8點(diǎn)-9點(diǎn)的數(shù)據(jù)則落入 shard1 中。每一個(gè) shard 都對(duì)應(yīng)一個(gè)底層的 tsm 存儲(chǔ)引擎,有獨(dú)立的 cache、wal、tsm file。
這樣做的目的就是為了可以通過(guò)時(shí)間來(lái)快速定位到要查詢(xún)數(shù)據(jù)的相關(guān)資源,加速查詢(xún)的過(guò)程,并且也讓之后的批量刪除數(shù)據(jù)的操作變得非常簡(jiǎn)單且高效。 - 建議在數(shù)據(jù)庫(kù)建立的時(shí)候設(shè)置存儲(chǔ)策略,不建議設(shè)置過(guò)多且隨意切換
create database testdb2 with duration 30d
1.4 存儲(chǔ)引擎
1.4.1 存儲(chǔ)引擎(Timestamp-Structure Merge Tree)
TSM是在LSM的基礎(chǔ)上優(yōu)化改善的,引入了serieskey的概念,對(duì)數(shù)據(jù)實(shí)現(xiàn)了很好的分類(lèi)組織。
TSM主要由四個(gè)部分組成: cache、wal、tsm file、compactor:
- cache:插入數(shù)據(jù)時(shí),先往 cache 中寫(xiě)入再寫(xiě)入wal中,可以認(rèn)為 cache 是 wal 文件中的數(shù)據(jù)在內(nèi)存中的緩存,cache 中的數(shù)據(jù)并不是無(wú)限增長(zhǎng)的,有一個(gè) maxSize 參數(shù)用于控制當(dāng) cache 中的數(shù)據(jù)占用多少內(nèi)存后就會(huì)將數(shù)據(jù)寫(xiě)入 tsm 文件。如果不配置的話(huà),默認(rèn)上限為 25MB
- wal:預(yù)寫(xiě)日志,對(duì)比MySQL的 binlog,其內(nèi)容與內(nèi)存中的 cache 相同,作用就是為了持久化數(shù)據(jù),當(dāng)系統(tǒng)崩潰后可以通過(guò) wal 文件恢復(fù)還沒(méi)有寫(xiě)入到 tsm 文件中的數(shù)據(jù),當(dāng) InfluxDB 啟動(dòng)時(shí),會(huì)遍歷所有的 wal 文件,重新構(gòu)造 cache。
- tsm file:每個(gè) tsm 文件的大小上限是 2GB。當(dāng)達(dá)到 cache-snapshot-memory-size,cache-max-memory-size 的限制時(shí)會(huì)觸發(fā)將 cache 寫(xiě)入 tsm 文件。
- compactor:主要進(jìn)行兩種操作,一種是 cache 數(shù)據(jù)達(dá)到閥值后,進(jìn)行快照,生成一個(gè)新的 tsm 文件。另外一種就是合并當(dāng)前的 tsm 文件,將多個(gè)小的 tsm 文件合并成一個(gè),減少文件的數(shù)量,并且進(jìn)行一些數(shù)據(jù)刪除操作。 這些操作都在后臺(tái)自動(dòng)完成,一般每隔 1 秒會(huì)檢查一次是否有需要壓縮合并的數(shù)據(jù)。
1.4.2 存儲(chǔ)目錄
influxdb的數(shù)據(jù)存儲(chǔ)有三個(gè)目錄,分別是meta、wal、data:
- meta 用于存儲(chǔ)數(shù)據(jù)庫(kù)的一些元數(shù)據(jù),meta 目錄下有一個(gè) meta.db 文件;
- wal 目錄存放預(yù)寫(xiě)日志文件,以 .wal 結(jié)尾;
- data 目錄存放實(shí)際存儲(chǔ)的數(shù)據(jù)文件,以 .tsm 結(jié)尾。
1.5 相關(guān)特點(diǎn)
1) 基于時(shí)間序列,支持與時(shí)間有關(guān)的相關(guān)函數(shù)(如最大,最小,求和等);
2) 可度量性:你可以實(shí)時(shí)對(duì)大量數(shù)據(jù)進(jìn)行計(jì)算;
3) 基于事件:它支持任意的事件數(shù)據(jù);
4) 無(wú)結(jié)構(gòu)(無(wú)模式):可以是任意數(shù)量的列;
5)支持min, max, sum, count, mean, median 等一系列函數(shù);
6)內(nèi)置http支持,使用http讀寫(xiě);
7)強(qiáng)大的類(lèi)SQL語(yǔ)法;
8)自帶管理界面,方便使用(新版本需要通過(guò)Chronograf)
1.6 influxdb和其他時(shí)序數(shù)據(jù)庫(kù)比較
- 從部署、集群、資源占用、存儲(chǔ)模型、性能等方面比較influxdb和opentsdb,具體如下:
| 特性 | InfluxDB | OpentsDB |
|---|---|---|
| 單機(jī)部署 | 部署簡(jiǎn)單、無(wú)依賴(lài) | 需要搭建 Hbase,創(chuàng)建 TSD 數(shù)據(jù)表,配置 JAVA 等 |
| 集群 | 開(kāi)源版本沒(méi)有集群功能 | 集群方案成熟 |
| 資源占用 | cpu 消耗更小,磁盤(pán)占用更小 | 資源消耗相比更多 |
| 存儲(chǔ)模型 | TSM | 基于HBase存儲(chǔ)時(shí)序數(shù)據(jù)(LSM) |
| 存儲(chǔ)特點(diǎn) | 同一數(shù)據(jù)源的tags不再冗余存儲(chǔ) ;列式存儲(chǔ),獨(dú)立壓縮 | 存在很多無(wú)用的字段;無(wú)法有效的壓縮;聚合能力弱 |
| 性能 | 查詢(xún)更快,數(shù)據(jù)匯聚分析較快 | 數(shù)據(jù)寫(xiě)入和存儲(chǔ)較快,但查詢(xún)和分析能力略有不足 |
| 開(kāi)發(fā) | 版本升級(jí)快,但架構(gòu)簡(jiǎn)單,類(lèi)SQL語(yǔ)言(InfluxQL)易開(kāi)發(fā) | API較為豐富,版本較為穩(wěn)定 |
1.7 相關(guān)資料文檔
- influxdb官網(wǎng):https://www.influxdata.com/
- 相關(guān)API官網(wǎng):https://docs.influxdata.com/influxdb/v1.7/
2. influxdb 訪(fǎng)問(wèn)
2.1 訪(fǎng)問(wèn)方式
influxdb訪(fǎng)問(wèn)本質(zhì)上都是 HTTP 方式,具體有如下:
- 客戶(hù)端命令行
- HTTP API 接口
- 各語(yǔ)言API 庫(kù)(對(duì) go 語(yǔ)言 API 封裝)
- 基于 WEB 管理頁(yè)面操作
2.2 連續(xù)查詢(xún)
- influxdb 的連續(xù)查詢(xún)是在數(shù)據(jù)庫(kù)中自動(dòng)定時(shí)啟動(dòng)的一組語(yǔ)句,語(yǔ)句中必須包含
SELECT 等關(guān)鍵詞。influxdb 會(huì)將查詢(xún)結(jié)果放在指定的數(shù)據(jù)表中。 - 目的:使用連續(xù)查詢(xún)是最優(yōu)的降低采樣率的方式,連續(xù)查詢(xún)和存儲(chǔ)策略搭配使用將會(huì)大大降低 InfluxDB 的系統(tǒng)占用量。而且使用連續(xù)查詢(xún)后,數(shù)據(jù)會(huì)存放到指定的數(shù)據(jù)表中,這樣就為以后統(tǒng)計(jì)不同精度的數(shù)據(jù)提供了方便。
CREATE CONTINUOUS QUERY wj_30m ON shhnwangjian
BEGIN
SELECT mean(connected_clients), MEDIAN(connected_clients),
MAX(connected_clients), MIN(connected_clients)
INTO redis_clients_30m
FROM redis_clients
GROUP BY ip,port,time(30m)
END
/*在shhnwangjian庫(kù)中新建了一個(gè)名為 wj_30m 的連續(xù)查詢(xún),
每三十分鐘取一個(gè)connected_clients字段的平均值、中位值、最大值、最小值 redis_clients_30m 表中,
使用的數(shù)據(jù)保留策略都是 default。*/
- 當(dāng)數(shù)據(jù)超過(guò)保存策略里指定的時(shí)間之后就會(huì)被刪除,但是這時(shí)候可能并不想數(shù)據(jù)被完全刪掉,可以使用連續(xù)查詢(xún)將數(shù)據(jù)聚合儲(chǔ)存。
2.4 操作優(yōu)化
- 控制 series 的數(shù)量;
- 使用批量寫(xiě);
- 使用恰當(dāng)?shù)臅r(shí)間粒度;
- 存儲(chǔ)的時(shí)候盡量對(duì) Tag 進(jìn)行排序;
- 根據(jù)數(shù)據(jù)情況,調(diào)整 shard 的 duration;
- 無(wú)關(guān)的數(shù)據(jù)寫(xiě)不同的database;
- 控制 Tag Key, 與 Tag Value 值的大??;
- 存儲(chǔ)分離 ,將 wal 目錄與 data 目錄分別映射到不同的磁盤(pán)上,以減少讀寫(xiě)操作的相互影響。
3. 安裝
3.1 資源下載配置
InfluxDB、Telegraf、Chronograf、Kapacitor可到下方官網(wǎng)下載各平臺(tái)版本
- 下載官網(wǎng):https://portal.influxdata.com/downloads/
這里以Windows為例,說(shuō)明一下環(huán)境搭建,使用Docker或者Linux下安裝配置都基本一樣
- 選擇對(duì)應(yīng)平臺(tái)的influxdb:https://dl.influxdata.com/influxdb/releases/influxdb-1.7.6_windows_amd64.zip;
- 下載后解壓,得到 influxd.exe、influx.exe、influxdb.conf 等文件,data、meta、wal 是自己建立的文件夾:

- influx.exe 表示客戶(hù)端,influxd.exe 表示服務(wù)端,influx_inspect.exe 表示查看工具,influx_stress.exe 表示壓力測(cè)試工具,influx_tsm 表示數(shù)據(jù)庫(kù)轉(zhuǎn)換工具(將數(shù)據(jù)庫(kù)從 b1 或 bz1 格式轉(zhuǎn)換為 tsm1 格式),influxdb.conf 是配置文件,我們需要修改該文件,主要是三個(gè)路徑修改:
[meta]
# Where the metadata/raft database is stored
dir = "C:/Install/influxdb-1.7.6-1/meta"
[data]
# The directory where the TSM storage engine stores TSM files.
#/var/lib/influxdb/data
dir = "C:/Install/influxdb-1.7.6-1/data"
# The directory where the TSM storage engine stores WAL files.
#/var/lib/influxdb/wal
wal-dir = "C:/Install/influxdb-1.7.6-1/wal"
3.2 啟動(dòng)
- 啟動(dòng)服務(wù)端 influxd.exe;
- 打開(kāi)客戶(hù)端 influx.exe,可看到客戶(hù)端也是 http 連接服務(wù)端,其端口在 conf 配置文件中
3.3 命令行操作
- 可通過(guò)SQL-like語(yǔ)言直接操作influxdb:

3.4 Web管理
- Web管理需要下載Chronograf,解壓后打開(kāi)chronograf.exe,網(wǎng)頁(yè)中輸入:localhost:8888,即可打開(kāi)網(wǎng)頁(yè);
- 網(wǎng)頁(yè)中的數(shù)據(jù)顯示需要配置才會(huì)有,這里簡(jiǎn)單示例一下,以讀取系統(tǒng)內(nèi)存和cpu使用情況為例:
下載Telegraf,啟動(dòng)命令行切換到對(duì)應(yīng)目錄,然后輸入以下命令生成conf配置文件:
C:\Users\meng.chai>cd C:\Install\telegraf
C:\Install\telegraf>telegraf -sample-config -input-filter cpu:mem -output-filter influxdb > telegraf1.conf
這里生成的配置文件名是 telegraf1.conf,是為了和原有的 telegraf.conf 區(qū)分開(kāi)。輸入啟動(dòng)命令,打開(kāi) telegraf.exe,開(kāi)始采集信息并輸入到 influxdb

-
這時(shí)候就可以看到 web 中的數(shù)據(jù)了:

3.5 go 語(yǔ)言開(kāi)發(fā)
- go語(yǔ)言開(kāi)發(fā)只需要一個(gè)依賴(lài)包:github.com/influxdata/influxdb/client/v2,需要注意是v1.8版本,直接clone會(huì)失敗,
可先到:github.com/influxdata/influxdb中選擇版本號(hào)V1.8,然后clone下載 - 對(duì)influxdb的操作主要有連接、插入、查詢(xún)、關(guān)閉等幾個(gè)步驟,其中查詢(xún)的時(shí)候需要注意時(shí)間,要設(shè)置相應(yīng)的時(shí)區(qū),不然可能顯示的時(shí)間結(jié)果不同
import (
"github.com/influxdata/influxdb/client/v2"
...
)
//連接influxdb
func ConnectInflux()(client.Client, error){
conn, err := client.NewHTTPClient(client.HTTPConfig{
Addr:"http://localhost:8086",
Username:username,
Password:password,
})
if nil != err{
fmt.Println(err)
return nil, err
}
return conn, nil
}
//寫(xiě)入point
func WritePoints(con client.Client)error{
batchpoint ,err := client.NewBatchPoints(client.BatchPointsConfig{
Precision:"s",
Database:MyDB,
})
if nil != err{
fmt.Println(err)
return err
}
record := Record{AssertId:"assert_aaaaa", ModelId:"model0", PoinntId:"point1",
ModelPath:"model0/model1/point1", Attr:"", ModelTime:"123456789"}
tags := map[string]string{Tag1:record.AssertId, Tag2:record.ModelId}
fields := map[string]interface{}{Field1:record.PoinntId, Field2:record.ModelPath,
Field3:record.Attr, Field4:record.ModelTime}
point, err := client.NewPoint(Measurement, tags, fields, time.Now())
if nil != err{
fmt.Println(err)
return err
}
batchpoint.AddPoint(point)
if err := con.Write(batchpoint); err != nil{
fmt.Println(err)
return err
}
}
//查詢(xún)時(shí)要注意時(shí)區(qū),東八區(qū)設(shè)置為:tz('Asia/Shanghai'),命令行需要:precision rfc3339
query := fmt.Sprintf("select * from %s limit %d tz('Asia/Shanghai')", Measurement, 5)
res, err := querydb(conn, query)
- 需要注意的是,influxdb雖然很多時(shí)候都可以通過(guò)SQL語(yǔ)句操作,但數(shù)據(jù)更新例外。influxdb中數(shù)據(jù)更新只能重新Insert,且需要tags和時(shí)間戳相同,所以不建議大量更新數(shù)據(jù)。
- 極少出現(xiàn)刪除數(shù)據(jù)的情況,刪除數(shù)據(jù)基本都是清理過(guò)期數(shù)據(jù)。
