初識 InfluxDB
這次來聊一下 InfluxDB,不過在介紹之前,我們需要先了解一下什么是 "時序數據"。按照時間順序記錄系統、設備狀態變化的數據被稱為時序數據(Time Series Data),如 CPU 利用率、服務器指標、應用程序性能指標、函數接口調用指標、網絡流量數據、探測器數據、日志等等。時序數據以時間作為主要的查詢緯度,通常會將連續的多個時序數據繪制成線,制作基於時間的多緯度報表,用於揭示數據背后的趨勢、規律、異常,進行實時在線預測和預警,時序數據普遍存在於 IT 基礎設施、運維監控系統和物聯網中。時序數據主要有如下3個特點:
抵達的數據幾乎總是作為新條目被記錄,無更新操作
數據通常按照時間順序抵達
時間是一個主坐標軸
時序型數據庫是存放時序數據的專用型數據庫,並且支持時序數據的快速寫入、持久化、多緯度的實時聚合運算等功能。傳統數據庫通常記錄數據的當前值,時序型數據庫則記錄所有的歷史數據,在處理當前時序數據時又要不斷接收新的時序數據,同時時序數據的查詢也總是以時間為基礎查詢條件,並專注於解決以下海量數據場景的問題:
時序數據的寫入:如何支持千萬級/秒數據的寫入
時序數據的讀取:如何支持千萬級/秒數據的聚合和查詢
成本敏感:海量數據存儲帶來的是成本問題,如何更低成本地存儲這些數據,是時序型數據庫需要解決的關鍵問題
而 InfluxDB 便是一個由 InfluxData 公司開發的時序型數據庫,專注於海量時序數據的高性能讀、高性能寫、高效存儲與實時分析,廣泛應用於DevOps監控、IoT監控、實時分析等場景。而在時序型數據庫排行榜上, InfluxDB 也位列榜首:
那么 InfluxDB 都有哪些優點呢?
- 1. 部署簡單,使用方便,在技術實現上充分利用了 Go 語言的特性,無須任何外部依賴即可獨立部署;
- 2. 提供類似於SQL的查詢語言,接口友好,使用方便;
- 3. 擁有豐富的聚合運算和采樣能力;
- 4. 提供靈活的數據保留策略(Retention Policy)來設置數據的保留時間和副本數;
- 5. 在保障數據可靠性的同時,及時刪除過期數據,釋放存儲空間;
- 6. 提供靈活的連續查詢(Continuous Query)來實現對海量數據的采樣;
- 7. 支持多種通信協議,除了HTTP、UDP等原生協議,還兼容CollectD、Graphite、OpenTSDB、Prometheus等組件的通信協議;
而講到 InfluxDB,就不得不提 InfluxData 公司開源的高性能時序中台 TICK(Telegraf+InfluxDB + Chronograf + Kapacitor),其中 InfluxDB 就是作為 TICK 的存儲系統進行設計和開發的。TICK 專注於 DevOps 監控、IoT監控、實時分析等應用場景,是一個集成了采集、存儲、分析、可視化等能力的開源時序中台,由 Telegraf、InfluxDB、Chronograf、Kapacitor 共 4 個組件以一種靈活松散但緊密配合、互為補充的方式構成。
- Telegraf 是用於采集和上報指標的數據采集程序,采用靈活的、可配置的插件實現。Telegraf 可以通過配置文件中的相關配置,采集當前運行主機的指定指標,如 CPU 負載、內存使用等,也可以從第三方消費者服務(如 StatsD、Kafka)拉取數據,上報到已支持的多種存儲系統、服務或消息隊列,如 InfluxDB、Graphite、OpenTSDB、Datadog、Librato、Kafka、MQTT、NSQ 等。
- InfluxDB 是專注於時序數據場景(如 DevOps 監控、IoT 監控、實時分析等)的高性能時序型數據庫,支持靈活的自定義保留策略和類 SQL 的操作接口。
- Chronograf 是可視化的、BS 架構管理系統,可用於配置和管理接收到的監控數據、告警,並支持通過靈活強大的模塊和庫,快速配置數據可視化儀表盤、告警規則、可視化規則。
- Kapacitor 是從零構建的原生數據處理引擎,支持流式處理和批量處理,支持靈活強大的自定義功能,如定義新的告警閾值、告警指標特征、告警統計異常特征等,以及后續的告警處理行為。除了靈活,Kapacitor 也很開放,能靈活地集成對接第三系統,如 HipChat、OpsGenie、Alerta、Sensu、PagerDuty、Slack 等。
所以 TICK 是一個集成了采集、存儲、分析、可視化等能力的開源時序型中台,由 Telegraf 實現數據的采集功能、InfluxDB 實現數據的時序存儲和分析功能、Chronograf 實現數據的可視化功能、Kapacitor 實現數據的實時流式處理功能,是一個完善的時序數據解決方案。這些組件的 GitHub 地址如下:
Telegraf:https://github.com/influxdata/telegraf
InfluxDB:https://github.com/influxdata/influxdb
Chronograf:https://github.com/influxdata/chronograf
Kapacitor:https://github.com/influxdata/kapacitor
InfluxDB 的優勢
存儲和分析時序數據的時序型系統並不鮮見,自計算機問世以來,我們一直在數據庫中存儲時序數據,比如 MySQL。在之后第一代時序平台,如 KDB +、RRDtool、Graphite 等就推出了,主要用於存儲和分析數據中心的時序數據,以及高頻金融數據、股票波動率等。
根據數據庫趨勢跟蹤和行業分析網站(DB-Engines)發布的信息,時序型數據庫是數據庫市場中份額增長最快的部分。原因很明顯,計算機世界中的數據庫、網絡、容器、系統、應用程序等,和物理世界中的家用設備、城市基礎設施、工廠機器、電力設施等,正在創建海量的時序數據。現在更多的企業會通過時序存儲和數據分析來獲得預測能力和實時決策能力,從而為客戶提供更好的使用體驗。這意味着底層數據平台需要發展以應對新的工作負載的挑戰,以及更多的數據點、數據源、監控維度、控制策略和精度更高的實時響應,對下一代時序中台提出了更高的要求,比如:
專為時序存儲和高性能讀寫而設計:計算機世界的各種系統和應用,以及物理世界的 IoT 設備都在創建海量的時序數據,每秒千萬級的數據吞吐量是很常見的,而且這些數據還需要可以以非阻塞方式接收並且可壓縮以節省有限的存儲資源
專為實時操作而設計:預測能力和實時決策能力,需要收到數據后,就能實時輸出最新的數據分析結果,執行預定義的操作
專為高可用性而設計:現代軟件系統需要全天候可用,除了基本的集群能力,還需要根據需求自動擴容和縮容,支持柔性可用等
InfluxData 公司選擇從頭開始構建 InfluxDB 以支持下一代時序中台的需求,InfluxDB 通過實現高度可擴展的數據接收和存儲引擎,可以高效地實時收集、存儲、查詢、可視化顯示和執行預定義操作。它通過連續查詢提升查詢效率和縮短延遲,通過數據保留策略,及時高效地刪除過期冷數據,提升存儲效率。
到這里就必須提一下其它種類的數據庫了,比如關系型數據庫、Cassandra、MongoDB、HBase 等,利用它們也可以實現時序數據的存儲,但卻不是最優的選擇,這是為什么呢?原因就在於和 InfluxDB 相比,其需要開發人員投入大量的時間進行代碼編寫,以開發和 InfluxDB 相似的功能,比如:
編寫代碼實現跨集群數據分片功能、聚合運算和采樣功能、數據生命周期管理功能等
實現豐富的 API 接口
編寫用於數據采集的工具
實現實時處理模塊並編寫用於監控和警報的代碼
編寫可視化引擎以向用戶顯示時序數據
為了能對 InfluxDB 的優勢有個直觀的認識,接下來我們將 InfluxDB 和其他被用作時序存儲的系統(如 ElasticSearch、MongoDB、OpenTSDB)做個簡要的對比,更直觀地感受 InfluxDB 的優勢。
InfluxDB vs ElasticSearch
ElasticSearch 是專為搜索而設計的系統,是實現搜索功能的絕佳選擇,然而對於時序數據,卻並非如此。在處理時序數據時,InfluxDB 的性能遠遠超過 ElasticSearch 系統,對於寫入吞吐量,ElasticSearch 通常少於 InfluxDB 5~10 倍,具體差值取決於架構。對於特定時序的查詢速度,使用 ElasticSearch 比使用 InfluxDB 要慢 5~100 倍,具體差值取決於查詢的時間范圍。最后,如果需要存儲原始數據以便稍后查詢,則 ElasticSearch 上的硬盤占用比 InfluxDB 大 10~15 倍。如果先匯總數據再存儲,ElasticSearch 的硬盤占用比 InfluxDB 大 3~4 倍。綜合來看,ElasticSearch 非常適合進行搜索,但不適用於時序存儲和實時分析。
InfluxDB vs MongoDB
MongoDB 是一個開源的、面向文檔的數據庫,俗稱 NoSQL 數據庫,用 C 和 C ++ 語言編寫。雖然它通常不被認為是真正的時序型數據庫(TSDB),但它經常被用作時序存儲系統。它以時間戳和分組的形式提供建模原語,使用戶能夠存儲和查詢時序數據。MongoDB 旨在存儲 "無模式" 數據,其中每個對象可能具有不同的結構。實際上,MongoDB 通常用於存儲內容大小可變的 JSON 或 BSON 對象。由於其采用通用性和無模式數據存儲區設計,MongoDB 無法利用時序數據的高度結構化特性。需要特別指出的是,時序數據由標簽(鍵/值串對)和時間戳組成,這時必須對 MongoDB 做專門配置以支持時序數據,但這樣做效率很低。相比 MongoDB,InfluxDB 的性能和成本優勢明顯,InfluxDB 的寫性能大約是 MongoDB 的 2.4 倍,存儲效率大約是 MongoDB 的 20 倍,查詢效率大約是 MongoDB 的 5.7 倍。綜合來看,MongoDB 非常適合文檔和自定義對象,但不適用於大規模的時序數據和實時分析。
InfluxDB vs OpenTSDB
OpenTSDB 是一個可擴展的分布式時序型數據庫,用 Java 語言編寫,構建在 HBase 之上。它最初是由 Benoît Sigoure 於2010年開始編寫的,並在 LGPL 下開源。OpenTSDB 不是一個獨立的時序型數據庫,相反,它依賴 HBase 作為其數據存儲層,因此 OpenTSDB 時序守護進程(OpenTSDB 中的 TSD)在實例之間沒有共享狀態可以高效地提供查詢引擎的功能。OpenTSDB 允許通過其 API 進行簡單的聚合和數學運算,但沒有完整的查詢語言。OpenTSDB 支持毫秒的分辨率,但隨着亞毫秒級操作的普及,OpenTSDB 有時會出現精度不足的問題。相比 OpenTSDB,InfluxDB 的性能和成本優勢明顯,InfluxDB 的寫性能大約是 OpenTSDB 的 5 倍,存儲效率大約是 OpenTSDB 的 16.5 倍,查詢效率大約是 OpenTSDB 的 3.65 倍。另外,OpenTSDB 的設計初衷主要是用於生成儀表板圖,不是為了滿足任意查詢,也不是為了存儲數據,這些限制會影響它的使用方式。
InfluxDB 的特性
作為一個開源系統,InfluxDB 究竟有什么魅力吸引了如此多的用戶,從而在時序型數據庫排行榜上排名第一呢,並且還和第二名拉開如此大的差距。
首先 InfluxDB 是支持時序數據高效讀寫、壓縮存儲、實時計算能力的數據庫服務,除了具有成本優勢的高性能讀、高性能寫、高存儲率之外,InfluxDB 還具有如下特點:
無系統環境依賴,部署方便
無模式(schema-less)的數據模型,靈活強大
原生 HTTP 管理接口,免插件配置和免第三方依賴
強大的類 SQL 查詢語句,學習成本低,上手快
豐富的權限管理功能:精細到"表"級別
豐富的時效管理功能:自動刪除過期數據,自定義刪除指標數據
低成本存儲,采樣時序數據,壓縮存儲
豐富的聚合函數,支持 AVG、SUM、MAX、MIN 等聚合函數
InfluxDB 的安裝
InfluxDB 支持多個主流系統環境下的安裝部署,這里我們以 CentOS 為例,我使用的是阿里雲上的雲服務器。我們直接進入 InfluxDB 的下載頁面,選擇相應的系統之后,會自動顯示下載方式。
這里我們直接選擇 InfluxDB 1.8.9,我們按照提示進行安裝即可。另外需要說明的是,這篇關於 InfluxDB 的博客很早就有了,但當時因為用不上所以就寫了一點,最近打算寫完整。
wget https://dl.influxdata.com/influxdb/releases/influxdb-1.8.9.x86_64.rpm
sudo yum localinstall influxdb-1.8.9.x86_64.rpm
我這里已經安裝成功了,安裝時需要使用 root 或管理員權限。如果想卸載的話也很簡單,直接 yum remove influxdb -y 即可。
然后是端口,默認情況下,InfluxDB 服務監聽了兩個端口:8086 和 8088。其中 8086 端口是 InfluxDB 服務端 HTTP RESTful API 接入服務的監聽端口,8088 端口是 RPC 服務的監聽端口,主要用於數據的備份與還原、以及通信等等。如果使用的是雲服務器,那么要確保這兩個端口是對外開放的。除了這些端口外,InfluxDB 還集成了第三方插件的服務監聽端口,所有端口都可以通過 InfluxDB 配置文件進行修改,默認情況下,該文件位於 /etc/influxdb/influxdb.conf 下。
InfluxDB 軟件包程序
通常,InfluxDB 在安裝之后會提供以下幾個程序:
influx:InfluxDB 的命令行工具,如果以 Redis 為例,那么這里的 influx 就類似於 redis-cli
influxd:InfluxDB 的服務器程序,如果以 Redis 為例,那么這里的 influxd 就類似於 redis-server
influx_inspect:InfluxDB 的數據檢查工具
influx_stress:壓力測試工具
接下來,我們分別看一下這幾個程序的使用方式和參數。
influx 介紹
influx 是 InfluxDB 的命令行工具,用於通過命令行的形式訪問 InfluxDB 服務。
注意:influx 的版本必須和 InfluxDB 服務器程序(influxd)的版本相同,如果兩者版本不相同,則查詢時可能會出現解析錯誤的問題。
InfluxDB 的常用參數如下:
-version:顯示程序版本信息
-host 'IP 或者主機名':指定要連接的主機
-port '端口':指定要連接的主機的端口號
-socket 'unix domain socket':以 UNIX 域 socket 的方式連接 InfluxDB
-database '數據庫名':指定要連接的數據庫
-username '用戶名':連接時用於認證的用戶名
-password '密碼':連接時用於認證的密碼
-ssl:啟用 HTTPS 連接
-unsafeSsl:當使用 HTTPS 連接到集群時不使用 SSL 驗證
-execute '命令':要執行的命令
-type 'influxql、fux':指定調用 REPL 時使用的查詢語言
-format 'json、csv、column':指定服務器響應內容的格式,支持 JSON、CVS、COLUMN
-precision 'rfc3339、h、m、s、ms、u、ns':指定時間戳的格式,支持 rfc3339、h、m、s、ms、u、ns,默認格式為 rfc3339
-consistency 'any、one、quorum、all':指定寫入一致性級別,支持 any、one、quorum、all
-pretty:以閱讀友好的方式顯示 JSON 格式的內容
-import:從之前的備份文件中還原備份數據
-pps:設置數據導入時每秒允許導入多少條時序數據,默認值為 0,不限制導入速率
-path:需要還原的備份文件的存儲路徑
-compressed:設置為 true 時,表示支持導入壓縮格式的備份文件
此外 influx 還支持代理訪問,可以通過 HTTP_PROXY 和 HTTPS_PROXY 環境變量設置相應的 HTTP 代理和 HTTPS 代理,比如:
HTTP_PROXY=http://ip:port
HTTPS_PROXY=http://ip:port
以上就是 influx 的常用參數,也可以通過 influx -h 進行查看。
influxd 介紹
influxd 是 InfluxDB 的服務器守護進程,啟動之后即可提供相關服務了,而啟動方式如下:
influxd -config 配置文件路徑
下面再來看看 influxd 的基本語法和支持的命令,先有個印象,后面會詳細說。
influxd backup:數據備份
influxd config:顯示 influxd 的配置信息
influxd help:顯示幫助信息
influxd restore:還原之前通過 backup 命令備份的數據
influxd run:運行程序,默認參數,可以省略,也就是說 influxd 和 influxd run 效果是一樣的
influxd version:顯示 influxd 程序的版本信息
我們打印一下版本信息,來演示一下。
influx_inspect 介紹
influx_inspect 是 InfluxDB 的數據檢查工具,可通過 influx_inspect 查看 InfluxDB 的 TSM 格式文件的內容。InfluxDB 存儲的數據在物理磁盤上由 .tsm 文件所承載,我們使用 influx_inspect 可以查看其內容。
其命令如下:
deletetsm:批量刪除原始 TSM 文件
dumptsi:顯示 tsi1 文件的底層細節信息
dumptsm:顯示 tsm1 文件的底層細節信息
buildtsi:從 tsm1 數據中生成 tsi1 索引信息
help:顯示幫助信息
export:導出數據
report:顯示分片級別的數據信息
verify:驗證 TSM 文件的完整性
verify-seriesfile:驗證時序文件的完整性
InfluxDB 配置文件
InfluxDB 的配置文件為 /etc/influxdb/influxdb.conf,我們將里面的注釋刪掉貼出來,看看都有哪些可配置項。或者我們也可以通過 influxd config 命令進行查看,更方便一些,因為如果將配置文件中的注釋都刪掉,那么和 influxd config 輸出的內容是一樣的。
所以,如果哪天不小心把配置文件給搞沒了,那么也可以通過 influxd config > /etc/influxdb/influxdb.conf 重新生成一份。
可配置內容如下:
#### 全局配置 ####
# 是否禁止將 InfluxDB 使用信息上報到 usage.influxdata.com,默認為 false,也就是不禁止,也就是上報
reporting-disabled = false
# RPC 服務對應的地址,用於數據備份、通信等等
bind-address = "127.0.0.1:8088"
#### meta 節點相關配置 ####
[meta]
# META 數據和 Raft 數據庫的存儲目錄
dir = "/var/lib/influxdb/meta"
# 是否在創建數據庫時,創建默認保留策略 autogen,默認為 true
retention-autocreate = true
# 是否開啟 META 日志,默認為 true
logging-enabled = true
#### data 節點相關配置 ####
[data]
# TSM 文件的存儲目錄,我們說該文件是實際數據的載體
dir = "/var/lib/influxdb/data"
# 分片索引類型
index-version = "inmem"
# WAL 文件的存儲目錄
wal-dir = "/var/lib/influxdb/wal"
# 在同步寫入之前等待的總時間
wal-fsync-delay = "0s"
# 檢查寫請求中的表名、標簽鍵、標簽值是否是有效的 UNICODE 字符,此設置會產生額外的性能開銷
# 因為必須檢查每條時序數據的表名、標簽鍵、標簽值,默認為 false,也就是不檢查
validate-keys = false
# 是否提供更多的錯誤檢查
strict-error-handling = false
# 是否開啟查詢日志,默認為 true
query-log-enabled = true
# 設置分片緩存最大值,大於該值的時候拒絕寫入,單位 byte,也就是 1GB
cache-max-memory-size = 1073741824
# 設置快照大小,大於該值時數據會寫入到 TSM 格式的文件中,默認大小為 25MB
cache-snapshot-memory-size = 26214400
# TSM 引擎快照寫入磁盤延時,默認值為 10 分鍾
cache-snapshot-write-cold-duration = "10m0s"
# TSM 文件在壓縮前可以存儲的最大時間,默認為 4 小時
compact-full-write-cold-duration = "4h0m0s"
# 設置 TSM 壓縮寫入磁盤的速率限制,單位 "字節/秒"
compact-throughput = 50331648
# 設置 TSM 壓縮寫入磁盤的峰值速率限制,單位 "字節/秒"
compact-throughput-burst = 50331648
# 設置數據庫的時間序列線最大值,該值為 0 時表示無限制,默認值為 1000000
max-series-per-database = 1000000
# 設置一個標簽鍵對應的標簽值的最大數量,該值為 0 時表示無限制,默認值為 100000
max-values-per-tag = 100000
# TSM 壓縮的最大並發數,默認為 0,表示當前 CPU 核數除以 2,否則以設置的非零值為准
max-concurrent-compactions = 0
# WAL 文件壓縮到 TSI 索引文件的閾值,單位為 byte,默認值為 1m
max-index-log-file-size = 1048576
# TSI 索引引擎用於存放處理后的時序結果的內部緩存大小
series-id-set-cache-size = 100
# 是否開啟 TSM 引擎和 WAL 模塊的調試日志記錄,可以提供更詳細的內容,默認為 false
trace-logging-enabled = false
# 該配置不建議使用,作用是幫助磁盤速度較慢的用戶,但是會存在一些問題,所以為 false,不建議改為 true
tsm-use-madv-willneed = false
#### coordinator 節點相關配置 ####
[coordinator]
# 寫超時閾值,默認值為 10 秒
write-timeout = "10s"
# 最大並發查詢數,默認為 0 表示無限制
max-concurrent-queries = 0
# 查詢超時閾值,0 表示不設置超時時間
query-timeout = "0s"
# 慢查詢超時閾值,超時后生成一條慢查詢日志,0 表示無限制
log-queries-after = "0s"
# 一次 SELECT 操作可以處理的最大時序數據記錄的條數,0 表示無限制
max-select-point = 0
# 一次 SELECT 操作可以處理的最大時間序列線的數量,0 表示無限制
max-select-series = 0
# 一次 SELECT 操作可以創建的 GROUP BY 時間段的最大數量,0 表示無限制
max-select-buckets = 0
#### coordinator 節點相關配置 ####
[retention]
# 是否開啟保留策略功能,默認為 true
enabled = true
# 檢查的時間間隔,默認值為 30 分鍾
check-interval = "30m0s"
#### shard-precreation 節點相關配置 ####
[shard-precreation]
# 是否開啟分片預創建服務,默認值為 true
enabled = true
# 檢查時間間隔,默認值為 10 分鍾
check-interval = "10m0s"
# 創建分片組的最大提前時間間隔,默認值為 30 分鍾
advance-period = "30m0s"
#### monitor 節點相關配置 ####
[monitor]
# 是否開啟 Monitor 功能,默認值為 true
store-enabled = true
# 默認數據庫名
store-database = "_internal"
# 統計時間間隔,默認值為 10 秒
store-interval = "10s"
#### subscriber 節點相關配置 ####
[subscriber]
# 是否開啟 Subscriber 功能,默認值為 true
enabled = true
# HTTP 通信超時閾值,默認值為 30 秒
http-timeout = "30s"
# 是否准許接入自簽名證書的 HTTPS 連接,默認值為 false
insecure-skip-verify = false
# 設置 CA 證書的存儲目錄
ca-certs = ""
# 設置寫並發數,默認為 40
write-concurrency = 40
# 設置寫緩存大小,默認為 1000,單位 byte
write-buffer-size = 1000
#### http 節點相關配置 ####
[http]
# 是否開啟 HTTP 服務
enabled = true
# HTTP 服務監聽的地址信息
bind-address = ":8086"
# 是否開啟認證,默認不開啟
auth-enabled = false
# 是否開啟 HTTP 請求日志
log-enabled = true
# 當啟用 HTTP 請求日志時,是否關閉 HTTP 寫請求日志
suppress-write-log = false
# 是否開啟寫操作日志,如果為 true,那么每一次寫操作都會打開日志
write-tracing = false
# 是否開啟 flux 查詢協議
flux-enabled = false
# 是否開啟 flux 查詢日志
flux-log-enabled = false
# 是否開啟 pprof
pprof-enabled = true
# 開啟 pprof 是否啟用認證
pprof-auth-enabled = false
# 是否開啟 pprof,並綁定 localhost:6060 端口
debug-pprof-enabled = false
# 是否啟用 HTTPS 功能
https-enabled = false
# 設置 HTTPS 證書的路徑
https-certificate = "/etc/ssl/influxdb.pem"
# 設置 HTTPS 私鑰的存儲路徑
https-private-key = ""
# 配置查詢返回的最大行數,0 表示無限制
max-row-limit = 0
# 配置最大連接數,0 表示無限制
max-connection-limit = 0
# 用於 JWT 簽名的共享密鑰
shared-secret = ""
# 配置 realm,默認值為 "InfluxDB"
realm = "InfluxDB"
# 是否啟用 UNIX 域 socket 通信
unix-socket-enabled = false
# 設置 UNIX 域 socket 的權限
unix-socket-permissions = "0777"
# 設置 UNIX 域 socket 的路徑
bind-socket = "/var/run/influxdb.sock"
# 客戶端請求主體的最大值,以字節為單位
max-body-size = 25000000
# HTTP 請求日志的存儲目錄
access-log-path = ""
# 並發處理的寫請求的最大數量,0 表示無限制
max-concurrent-write-limit = 0
# 排隊等待處理的寫請求的最大數量,0 表示無限制
max-enqueued-write-limit = 0
# 在隊列匯總等待處理的寫請求的超時閾值,單位 秒
enqueued-write-timeout = 30000000000
#### logging 節點相關配置 ####
[logging]
# 日志格式,默認為 auto
format = "auto"
# 日志級別,默認為 info,也可以改成 debug、warn、error
level = "info"
# 當程序啟動時,是否禁用打印 LOGO 信息,默認為 false,也就是打印
suppress-logo = false
#### graphite 節點相關配置 ####
[[graphite]]
# 是否啟用該模塊,默認 false
enabled = false
# Graphite 接入服務的地址信息
bind-address = ":2003"
# 數據庫名稱
database = "graphite"
# 配置保留策略,默認為保留策略默認值
retention-policy = ""
# 通信協議
protocol = "tcp"
# 批處理閾值
batch-size = 5000
# 在內存中等待批處理的最大值
batch-pending = 10
# 批處理等待閾值,默認值為 1 秒
batch-timeout = "1s"
# 一致性級別
consistency-level = "one"
# 多個表名之間的連接符
separator = "."
# UDP 讀緩存的大小,0 表示使用操作系統提供的值
udp-read-buffer = 0
#### collectd 節點相關配置 ####
[[collectd]]
# 是否啟用該模塊,默認 false
enabled = false
# Collectd 接入服務的地址信息
bind-address = ":25826"
# 數據庫名稱
database = "collectd"
# 配置保留策略,默認為保留策略默認值
retention-policy = ""
# 批處理閾值
batch-size = 5000
# 在內存中等待批處理的最大值
batch-pending = 10
# 批處理等待閾值,默認值為 10 秒
batch-timeout = "10s"
# UDP 讀緩存的大小,0 表示使用操作系統提供的值
read-buffer = 0
# DB 文件存放目錄
typesdb = "/usr/share/collectd/types.db"
# 安全級別
security-level = "none"
# 認證文件存放路徑
auth-file = "/etc/collectd/auth_file"
# 兩種處理方式:split 和 join,默認 split
# split:將不同插件的數據存儲到不同的表中;join:將多個插件的數據存儲到同一張表中
parse-multivalue-plugin = "split"
#### opentsdb 節點相關配置 ####
[[opentsdb]]
# 是否啟用該模塊,默認 false
enabled = false
# Opentsdb 接入服務的地址信息
bind-address = ":4242"
# 數據庫名稱
database = "opentsdb"
# 配置保留策略,默認為保留策略默認值
retention-policy = ""
# 一致性級別
consistency-level = "one"
# 是否開啟 TLS
tls-enabled = false
# 整數存儲路徑
certificate = "/etc/ssl/influxdb.pem"
# 批處理閾值
batch-size = 1000
# 在內存中等帶批處理的最大值
batch-pending = 5
# 批處理等待閾值
batch-timeout = "1s"
# 當檢測到數據格式異常時,輸出錯誤日志
log-point-errors = true
#### udp 節點相關配置 ####
[[udp]]
# 是否啟用該模塊,默認 false
enabled = false
# UDP 接入服務的地址信息
bind-address = ":8089"
# 數據庫名
database = "udp"
# 配置保留策略,默認為保留策略默認值
retention-policy = ""
# 批處理閾值
batch-size = 5000
# 在內存中等帶批處理的最大值
batch-pending = 10
# UDP 讀緩存的大小,0 表示使用操作系統提供的值
read-buffer = 0
# 批處理等待閾值,默認值為 1 秒
batch-timeout = "1s"
# 解析時間戳的精度值,默認使用數據庫默認值,即納秒
precision = ""
#### continuous_queries 節點相關配置 ####
[continuous_queries]
# 是否開啟日志,默認值為 true
log-enabled = true
# 是否啟用該模塊
enabled = true
# 是否記錄連續查詢執行的統計信息
query-stats-enabled = false
# 連續查詢定時運行的時間間隔
run-interval = "1s"
#### tls 節點相關配置 ####
[tls]
# 支持的 TLS 協議的最小版本,有效值包括 tls1.0、tls1.1 和 tls1.2
# 如果未指定,min-verison 則為編譯 InfluxDB 的 Go 編譯器中,crypto/tls 包內指定的最小 TLS 版本
min-version = ""
# 支持的 TLS 協議的最大版本
max-version = ""
以上就是相關配置,基本上能用到的也比較少。
寫入和查詢
了解完 InfluxDB 的安裝部署之后,我們就開始激動人心的 InfluxDB 基礎操作。作為一款優秀的開源軟件,InfluxDB 不僅提供了操作友好的類 SQL 風格的操作接口,如 influx 命令行工具、類 SQL 語法等,還支持 RESTful API 風格的 InfluxDB API,學習成本低,使用方便。下面就來 3 個部分介紹 InfluxDB 的寫入和查詢,首先介紹 InfluxDB 的操作模式,接着介紹行協議和數據的寫入操作,最后介紹 InfluxQL 和數據的查詢操作。
首先我們將服務啟動起來,由於默認是前台啟動的,我們改成需要后台啟動。
nohup influxd -config /etc/influxdb/influxdb.conf > /dev/null &
操作模式
InfluxDB 支持兩種原生的操作模式:influx 命令行工具和 InfluxDB API。influx 命令行工具是一種類似於 mysql 命令行工具的命令行接口,可以方便地執行管理、運維、調試性質的操作。InfluxDB API 是一種可編程性強、編程語言友好的 RESTful API 的操作接口,支持 HTTP 和 HTTPS 協議。
influx 命令行模式
influx 是 InfluxDB 的命令行工具,用於通過命令行的形式訪問 InfluxDB 服務。
默認連接至本地的 8086 端口,當然我們也可以手動指定。注意:還是之前那句話,InfluxDB 服務器程序版本和 influx 命令行程序版本要相同,如果不相同,則查詢時可能會出現解析錯誤的問題。
我們還可以在不進入 influx 命令行的情況下執行相關命令:
當前默認只有一個 _internal 數據庫。
InfluxDB API 模式
InfluxDB API 是一種 RESTful API 風格的接口,返回 JSON 格式的響應數據,並支持身份認證、JWT令牌、豐富的HTTP響應代碼等。
InfluxDB API 支持的接口及接口的定義描述如下所示。
舉個栗子,我們可以使用 /ping 接口檢查當前地址的 InfluxDB 實例是否健康,如果實例健康運行則返回 InfluxDB 的版本信息;如果實例運行異常,則返回相關錯誤信息。
from pprint import pprint
import requests
res = requests.get("http://47.94.174.89:8086/ping")
print(res.text == "") # True
pprint(dict(res.headers))
"""
{'Content-Type': 'application/json',
'Date': 'Tue, 12 Oct 2021 12:08:38 GMT',
'Request-Id': '2219324c-2b55-11ec-805d-00163e2e4507',
'X-Influxdb-Build': 'OSS',
'X-Influxdb-Version': '1.8.9',
'X-Request-Id': '2219324c-2b55-11ec-805d-00163e2e4507'}
"""
返回響應體是一個空字符串,證明實例健康運行,而實例版本信息則在請求頭中。
InfluxDB API 支持豐富的 HTTP 響應碼,在異常跟蹤定位上尤其有用,HTTP 響應碼列表和含義如下:
204 No Content:執行成功
400 Bad Request:請求錯誤,可能是由於行協議語法錯誤或寫入了一個錯誤的字段類型
401 Unauthorized:請求錯誤,可能是由於認證憑據無效
404 Not Found:請求錯誤,可能是由於指定了一個不存在的數據庫
500 Internal Server Error:系統過載或核心信息不匹配,可能是由於指定了一個不存在的保留策略
以上就是 influx 的兩種模式,簡單介紹一下,更多內容我們在下面的數據寫入和數據讀取中介紹。
數據寫入
InfluxDB 寫操作支持簡明的行協議(Line Protocol),行協議是一種基於文本格式的協議。
基於兼容開放和生態的考慮,除了行協議,InfluxDB 還支持 CollectD、Graphite、OpenTSDB、Prometheus、UDP 等第三方協議,第三方協議將會在后續詳細介紹。
行協議
行協議的單行文本表示一條時序數據,由表、標簽集、指標集和時間戳 4 部分組成,行協議的基本語法如下所示。
<measurement> [, <tag-key>=<tag-value>...] <field-key>=<field-value> [, <field-key>=<field-value>...] [timestamp]
InfluxDB 實現了類 SQL 的接口,但在語義體系上還是有很大差別的,我們解釋一下這些標簽的含義。
- measurement:必填,表示一組有關聯的時序數據,類似於 MySQL 中表(Table)的概念。
- tag:選填,表示標簽,由標簽鍵(tag-key)和標簽值(tag-value)共同組成,比如 host=server01 和 location=cn-sz 這種形式。標簽可以用於創建索引,提升查詢性能,一般存放的是表示數據點來源的屬性信息。
- field:表示指標,同 tag 類似,指標由指標鍵(field-key)和指標值(field-value)共同組成,比如 user=23.0 和 system=57.0。一般存放的是具體的時序數據,即隨着時間戳的變化而變化的數據,與標簽不同的是,指標數據不會被索引,並且至少出現一組。指標鍵要求是字符串,而指標值可以是字符串、浮點型、整型,或布爾型。
- timestamp:可選,表示納秒級精度的時間戳,如果沒有該參數,那么 InfluxDB 寫入數據時會根據當前時間自動生成。與 MySQL 不同的是,在 Influx DB中,時間幾乎可以看作主鍵的代名詞,因為是時序數據庫。
還有幾個需要注意的地方:
行協議對空格敏感,標簽集和指標集中間必須有空格
時間戳參數不可以加引號,否則會報錯
指標值支持字符串類型,要使用雙引號將字符串類型的指標值括起來;但對於非字符串類型的指標值,要注意不能加引號,否則會被當成字符串類型來處理
整型默認會被當成浮點型處理,比如 23 會被解析成 23.0,如果想表示整型,那么需要在結尾加上小寫字母 i,比如 23i
我們舉個栗子:
cpu_usage,host=server01,location=cn-sz user=23,system=57
以上就是一個單行的行協議表達式,也代表一條時序數據,我們注意到第一個指標的前面不是逗號,而是一個空格。然后時間戳我們沒有指定,那么 InfluxDB 會自動生成一個。
最后是 InfluxDB 中的的保留字,我們要避免在表名或者字段名中使用 InfluxDB 的保留字,那么 InfluxDB 中的保留字都有哪些呢?
ALL ALTER ANALYZE ANY AS ASC
BEGIN BY CREATE CONTINUOUS DATABASE DATABASES
DEFAULT DELETE DESC DESTINATIONS DIAGNOSTICS DISTINCT
DROP DURATION END EVERY EXPLAIN FIELD
FOR FROM GRANT GRANTS GROUP GROUPS
IN INF INSERT INTO KEY KEYS
KILL LIMIT SHOW MEASUREMENT MEASUREMENTS NAME
OFFSET ON ORDER PASSWORD POLICY POLICIES
PRIVILEGES QUERIES QUERY READ REPLICATION RESAMPLE
RETENTION REVOKE SELECT SERIES SET SHARD
SHARDS SLIMIT SOFFSET STATS SUBSCRIPTION SUBSCRIPTIONS
TAG TO USER USERS VALUES WHERE
WITH WRITE
另外,關鍵字 time 是一個特殊的保留字,time 不可以用作標簽鍵和指標鍵的命名,但可以用作其他命名,如表的命名、保留策略的命名等。除了時間戳字段,其他字段如表、標簽鍵、標簽值、指標鍵、指標值,是大小寫敏感的。
數據寫入
我們可以通過 influx 命令行寫入數據,也可以使用 InfluxDB API 寫入,先來看看命令行。
還是很簡單的,然后我們看到寫入數據通過 insert 進行寫入,注意后面沒有 into,直接跟行協議表達式。另外與 MySQL 等傳統數據庫不同的是,InfuxDB 不需要顯式地創建新表,當使用 insert 語句插入數據時,InfuxDB 會自動根據 insert 數據的格式和指定的表名自動創建新表。
不過在實際應用中,我們更多還是通過 InfluxDB API 寫入時序數據,我們可以一次只寫入一條,也可以同時寫入多條,多條數據之間用換行符分隔。
curl -ig http://47.94.174.89:8086/write?db=monitor -d "cpu_usage,hostname=server2 percent=32.9
mem_usage,hostname=server1 percent=38.733,value=298864752"
寫入多條數據時,表可以不相同。
如果寫入數據時沒帶上時間戳,InfuxDB 會默認使用本地 UTC 納秒時間作為寫入數據的時間,當需要同時向同一個數據庫同一個時間序列線寫入多條數據時,每條數據都需要帶時間戳,否則后寫的數據會覆蓋前面的數據。
另外導入數據的時候也可以通過文件的方式,舉個栗子: