influxdb一般情況下比較穩定,但是隨着數據量越來越大,也會出現一些性能問題,需要進行一些調優。我目前遇到的關於influxdb的性能問題大體上可以分爲兩類
- CPU持續居高不下
- 內存持續居高不下,並伴隨着較高的iowait
下面分別來討論我當時的處理方法。
CPU持續居高不下
當時遇到的現象是,influxdb進程的CPU利用率持續居高不下,查詢數據的速度很慢。經過分析,最終定位到influxdb.conf配置文件中的一個參數
# The maximum time a query will is allowed to execute before being killed by the system. This limit
# can help prevent run away queries. Setting the value to 0 disables the limit.
# query-timeout = "0"
我認爲這簡直是influxdb的一個bug,默認情況下查詢數據居然沒有超時時間。一般情況下大家都是在grafana上展示influxdb的數據,如果一次查詢了非常多的數據,那麼這個查詢就會執行很長時間,如果這種大的查詢比較多的話,influxdb就會耗費幾乎所有的CPU來做這些數據查詢,並且其它小的查詢也會受到影響。
我的做法是設置了一個60秒的超時時間
query-timeout = "60s"
這樣的話,大查詢如果60秒內結束不了,會超時並結束,不影響後續的查詢。
內存持續居高不下,並伴隨着較高的iowait
針對這種情況,我認爲比較常見的原因是series過多。
關於series,influxdb官網的解釋是
InfluxDB, a series is a collection of points that share a measurement, tag set, and field key.
簡單來講,series就是一個監控對象的一組相同的tag,它決定了被監控對象的粒度。
我的理解是,series是influxdb的索引,會被存儲在內存裏,series過多的話,就會導致內存持續居高不下。
對於這種問題,首先需要識別出哪各數據庫的series比較多,然後再降低series的數量。
發現哪個數據庫的series過多
influxdb本身提供了一些針對調試的支持,通過下面的接口返回的數據,可以分析出所有數據庫的series數量
http://localhost:8086/debug/vars
在返回的數據中,每個數據庫都會出現下面的數據,numSeries
就是series的數量
"database:_internal": {
"name": "database",
"tags": {
"database": "_internal"
},
"values": {
"numMeasurements": 12,
"numSeries": 2050
}
}
上面的數據顯示的是_internal
數據庫的數據。
一般情況下,如果series的數量在10萬以內,對性能不會造成太大影響。
如何降低series的數量
series的多少,主要是由tag的個數和tag的值決定的,所以如果要降低series的數量,可以從兩個方面來考慮。
第一,通過合理地規劃,來減少不必要的tag。如果某個tag的值分佈非常的多,可以考慮下它是否有必要作爲tag,是不是作爲field更合適。
第二,通過設置保留策略,保留更少的數據。influxdb是時序數據庫,主要被用來存儲監控數據,可以根據具體場景來保留更短的數據,這樣的話會有一些舊數據由於過期而被清理掉,從而減少series的數量。
關於如何設置series的保留策略,可以參考
降低內存利用的一個配置項
跟內存相關的還有一個配置項可以簡單粗暴地把內存降下來
# CacheMaxMemorySize is the maximum size a shard's cache can
# reach before it starts rejecting writes.
# Valid size suffixes are k, m, or g (case insensitive, 1024 = 1k).
# Values without a size suffix are in bytes.
# cache-max-memory-size = "1g"
默認情況下這個值是不設置的,可以通過設置一個最大上限,來限制influxdb的cache。
cache-max-memory-size = "4g" # 針對服務器的內存情況來設置
修改配置文件需要重啓influxdb實例才能生效
磁盤佔用過多
這個問題一般比較好理解,有些數據庫可能會保存大量數據,從而佔用過多的磁盤空間,進而對服務器造成一定的影響。
一個influxdb數據庫的數據量大小和series的數量沒有什麼絕對的關係。
識別這個問題也比較簡單,influxdb的數據默認存儲在 /var/lib/influxdb/data 目錄下,只要 cd 到這個目錄下,然後通過 du 來查下哪個目錄最大即可。
# cd /var/lib/influxdb/data
# du -d 1 -h .
找出比較大的數據庫,然後再想辦法減少數據量。