目標
本文將講述influxdb記憶體中都存了哪些資料?
什麼情況下會導致記憶體佔用暴增?
以及記憶體相關的配置。
我的influxdb配置
我的influxdb配置如下:
/etc/influxdb/config.toml
bolt-path = "/var/lib/influxdb/influxd.bolt"
engine-path = "/var/lib/influxdb/engine"
storage-cache-max-memory-size = 20737418240
storage-cache-snapshot-memory-size = 524288000
log-level = "info"
storage-max-index-log-file-size = 50485760
storage-max-concurrent-compactions = 2
幾個關鍵配置說明:
- storage-cache-max-memory-size: db例項可以使用的最大記憶體。如果機器記憶體超大,可以設定為 0,無限制。
cache-max-memory-size = "1g"
The maximum size that a shard cache can reach before it starts rejecting writes.
Valid memory size suffixes are: k, m, or g (case-insensitive, 1024 = 1k). Values without a size suffix are in bytes.
Consider increasing this value if encountering cache maximum memory size exceeded errors.
Environment variable: INFLUXDB_DATA_CACHE_MAX_MEMORY_SIZE
- storage-cache-snapshot-memory-size:
The size at which the engine will snapshot the cache and write it to a TSM file, freeing up memory.
Valid memory size suffixes are: k, m, or g (case-insensitive, 1024 = 1k). Values without a size suffix are in bytes.
Environment variable: INFLUXDB_DATA_CACHE_SNAPSHOT_MEMORY_SIZE
往 DB 寫資料時,資料先寫入 WAL 檔案,同時也會寫入記憶體中。然後定期把記憶體中的資料寫入 TSM 檔案。
這裡定義的就是記憶體中資料的最大 size。當超過這個 size,會對記憶體中的資料產生一個快照,然後把快照寫入 TSM 檔案。
同時,還有另外一個配置cache-snapshot-write-cold-duration
,它定義了當一個分割槽超過一定時間沒有新資料寫入,就會把記憶體中的資料重新整理到磁碟。
The time interval at which the engine will snapshot the cache and write it to a new TSM file if the shard hasn’t received writes or deletes.
三點:
- influxdb中每個分割槽的資料是單獨儲存的。因為每個分割槽會產生一個 WAL 檔案。同時每個分割槽會單獨佔用一份記憶體空間。因此,當資料時間亂序寫入時(寫入的資料有 23年的、24 年。。。),就會佔用更多的記憶體。
- 記憶體中的資料格式,具體來講每個time series 對應一個資料結構,他們是有序的。 因此,基數越大佔用記憶體也越多。
- 當機器記憶體不足時,可以降低storage-cache-snapshot-memory-size配置的大小,來降低總的記憶體佔用。同理,當記憶體充足時,可以調大該配置,降低重新整理磁碟的頻率,降低 cpu 和磁碟開銷。
- storage-max-concurrent-compactions
The maximum number of concurrent full and level compactions that can run at one time. The default value of 0 results in 50% of the CPU cores being used at runtime for compactions. If explicitly set, the number of cores used for compaction is limited to the specified value. This setting does not apply to cache snapshotting. For more information on GOMAXPROCS environment variable, see GOMAXPROCS environment variable on this page.
如果你的機器間歇性地 CPU 過高,可以降低這個引數的值。
透過influxdb監控資料,驗證上述配置的效果
https://docs.influxdata.com/influxdb/v2/reference/internals/metrics/#influxdb-storage-statistics
透過 DB 暴漏的metrics指標,可以監控 DB 的記憶體執行狀態。
我使用的是prometheus監控。
指標 1:
storage_cache_inuse_bytes: Gauge of current memory consumption of cache
該指標,顯示的是每一塊cache(一個分割槽對應一塊 cache) 的記憶體大小。
記憶體中一共有 10 份 cache,說明有 10 個活躍的分割槽最近有資料寫入。
每個分割槽佔用記憶體最大400 多 M,這也吻合了我們前面的配置storage-cache-snapshot-memory-size = 524288000
下面看下storage_cache_inuse_bytes
和的變化趨勢:
我們看到,這個總的記憶體佔用波動挺大。 記憶體佔用高的時段,基本都是因為我在匯入大量的歷史資料(寫活躍分割槽多了)。
這個和,應該是由配置storage-cache-max-memory-size = 20737418240
控制的,不能大於 20G。
那麼,總的記憶體佔用會大於 20G 嗎?如何避免呢?
- 降低配置
storage-cache-snapshot-memory-size = 524288000
- 避免基數太大。 因為influxdb中會建立反向索引,索引的大小和基數大小密切相關。
指標 2
storage_cache_disk_bytes: Gauge of size of most recent snapshot
這臉指標,一個是 cache 大小,一個是快照大小。
它們的區別,參考https://docs.influxdata.com/influxdb/v2/reference/internals/storage-engine/#cache
指標 3
go_memstats_alloc_bytes: Number of bytes allocated and still in use.
從 go 語言角度,當前該程式佔用了 6.9G 記憶體。明顯高於前面cache的總和(cache 2G、快照 500M)。
那麼,剩下的記憶體是誰佔用的呢?
- 索引是個大頭,但是好像沒有工具可以檢視索引到底佔用的多少記憶體。 https://community.influxdata.com/t/how-can-i-estimate-the-index-size-based-on-tags/2221