最近 Windows 服务器上的内存使用率高达 95%,调查发现 InfluxDB 吃掉了大部分的内存。在服务器重启之后,InfluxDB 使用的内存为 1G,服务器的内存为 15.5G,整个服务器的内存使用率为 30%。但是随着时间的推移,InfluxDB 内存占用率越来越高,第一天占用内存 1.03G,第二天占用内存 3.7G,第三天占用内存 4.2G,直到服务器崩溃自动重启。
一、分析 Windows 的内存占用率
先看下在 Windows 下,我是如何分析内存的。
windows 内存分析
打开 Windows 的资源监视器,点击内存一栏,可以看到好几种内存:
- 提交(KB):操作系统为进程保存的虚拟内存量;
- 工作集(KB):进程当前正在使用的物理内存量;
- 可共享(KB):进程当前使用的可与其他进程共享的物理内存量;
- 专用(KB):进程当前使用的不能被其他进程共享的物理内存量;
- 工作集(KB) = 可共享(KB) + 专用(KB);
工作集就是我们要找的内存使用量,单位是KB。
比如说某个进程的工作集为 1,082,420KB,那么它使用的内存为: 1082420/1024/1024=1.03G。
二、InfluxDB 优化
1、数据库内存优化
# 设置为tsi1基于时间序列(TSI)磁盘的索引,默认inmem 内存分片索引
index-version = "tsi1"
2、关闭上报功能
# 关闭上报功能,默认false,环境变量:INFLUXDB_REPORTING_DISABLED
reporting-disabled = true
3、查询优化
# 查询超时时间,默认0不限制
query-timeout = "60s"
4、关闭监控设置
#关闭监控模块,默认true
store-enabled = false
本次主要调整了这四个参数的配置,修改之后,重启 InfluxDB,可以看到 InfluxDB 占用的内存明显下降了很多。是否还需要调整其他参数,还需要持续观察。
三、InfluxDB 配置文件回顾
1、全局设置
# 关闭上报功能,默认false,环境变量:INFLUXDB_REPORTING_DISABLED
reporting-disabled = true
2、元数据配置
[meta]
# 元数据存储路径,环境变量:INFLUXDB_META_DIR
dir = "/var/lib/influxdb/meta"
# 使用自动生成的存储策略,默认true,INFLUXDB_META_RETENTION_AUTOCREATE
retention-autocreate = true
# 是否开启 Meta日志,默认true,INFLUXDB_META_LOGGING_ENABLED
logging-enabled = true
存储策略(retention policy):在数据库里有一个默认的存储策略 autogen,数据保留时间为永久,在集群中的副本个数为1。插入和查询数据时如果不指定存储策略,则使用默认存储策略,默认存储策略可以修改。InfluxDB 会根据存储策略定期清除过期的数据。
# 查看某个数据库的存储策略
show retention policies on "db_name"
# 创建存储策略
create retention policy <retentionName> on <dbName> duration <durationTime> replication <replicaN> default
Shard 在 InfluxDB 中是一个比较重要的概念,它和存储策略相关联。每一个存储策略下会存在许多 shard,每一个 shard 存储一个指定时间段内的数据,并且不重复,例如 7点-8点 的数据落入 shard0 中,8点-9点的数据则落入 shard1 中。每一个 shard 都对应一个底层的 tsm 存储引擎,有独立的 cache、wal、tsm file。
这样做的目的就是为了可以通过时间来快速定位到要查询数据的相关资源,加速查询的过程,并且也让之后的批量删除数据的操作变得非常简单且高效。建议在数据库建立的时候设置存储策略,不建议设置过多且随意切换。
3、数据配置
[data]
# 数据存储目录,环境变量:INFLUXDB_DATA_DIR
dir = "/var/lib/influxdb/data"
# 预写日志(Write-Ahead Logging)文件的存储目录,环境变量:INFLUXDB_DATA_WAL_DIR
wal-dir = "/var/lib/influxdb/wal"
InfluxDB 的数据存储有三个目录,分别是meta、wal、data:
- meta 用于存储数据库的一些元数据,meta 目录下有一个 meta.db 文件;
- wal 目录存放预写日志文件,以 .wal 结尾;
- data 目录存放实际存储的数据文件,以 .tsm 结尾。
# 预写日志同步时间延迟,对于非SSD盘,InfluxData建议值的范围 0ms- 100ms
wal-fsync-delay = "0s"
# 默认inmem 内存分片索引, 设置为tsi1,基于时间序列(TSI)磁盘的索引
index-version = "inmem"
# 是否开启跟踪日志,默认值:false,环境变量:INFLUXDB_DATA_TRACE_LOGGING_ENABLED
trace-logging-enabled = false
# 是否开启tsm引擎查询日志,默认值:true
query-log-enabled = true
# 是否验证可以keys,开启后会产生开销,默认false
validate-keys = false
设置TSM(Timestamp-Structure Merge Tree)引擎
TSM是在LSM的基础上优化改善的,引入了serieskey的概念,对数据实现了很好的分类组织。
TSM主要由四个部分组成:cache、wal、tsm file、compactor:
cache:插入数据时,先往 cache 中写入再写入wal中,可以认为 cache 是 wal 文件中的数据在内存中的缓存,cache 中的数据并不是无限增长的,有一个 maxSize 参数用于控制当 cache 中的数据占用多少内存后就会将数据写入 tsm 文件。如果不配置的话,默认上限为 25MB。
# 预写日志同步时间延迟,对于非SSD盘,InfluxData建议值的范围 0ms- 100ms
wal-fsync-delay = "0s"
# 默认inmem 内存分片索引, 设置为tsi1,基于时间序列(TSI)磁盘的索引
index-version = "inmem"
# 是否开启跟踪日志,默认值:false,环境变量:INFLUXDB_DATA_TRACE_LOGGING_ENABLED
trace-logging-enabled = false
# 是否开启tsm引擎查询日志,默认值:true
query-log-enabled = true
# 是否验证可以keys,开启后会产生开销,默认false
validate-keys = false
wal:预写日志,对比MySQL的 binlog,其内容与内存中的 cache 相同,作用就是为了持久化数据,当系统崩溃后可以通过 wal 文件恢复还没有写入到 tsm 文件中的数据,当 InfluxDB 启动时,会遍历所有的 wal 文件,重新构造 cache。
# 用于限定shard最大值,大于该值时会拒绝写入
cache-max-memory-size = "1g"
tsm file:每个 tsm 文件的大小上限是 2GB。当达到 cache-snapshot-memory-size,cache-max-memory-size 的限制时会触发将 cache 写入 tsm 文件。
# 如果没有收到写或删除操作,TSM引擎将压缩一个分片中的所有TSM文件的时间间隔
compact-full-write-cold-duration = "4h"
compactor:主要进行两种操作,一种是 cache 数据达到阀值后,进行快照,生成一个新的 tsm 文件。另外一种就是合并当前的 tsm 文件,将多个小的 tsm 文件合并成一个,减少文件的数量,并且进行一些数据删除操作。这些操作都在后台自动完成,一般每隔 1 秒会检查一次是否有需要压缩合并的数据。
# 最大并发压缩数量,默认0,
max-concurrent-compactions = 0
# 在存储器( inmem)指数的设置
# 限制数据库的series数,该值为0时取消限制,默认值:1000000
max-series-per-database = 1000000
# 限制数据库的tags数,该值为0时取消限制,默认值:1000000
max-values-per-tag = 100000
# TSI( tsi1)指数的设置
# 索引预写日志文件将压缩为索引文件时的阈值
max-index-log-file-size = "1m"
# TSI索引中用于存储先前计算的系列结果的内部缓存的大小,0禁用缓存
series-id-set-cache-size = 100
4、查询管理的设置
[coordinator]
# 写超时时间,默认10s
write-timeout = "10s"
# 最大查询并发数,默认0不限制数量
max-concurrent-queries = 0
# 查询超时时间,默认0不限制
query-timeout = "60s"
# 慢查询时间
log-queries-after = "0s"
# 查询记录数量限制,默认0不限制
max-select-point = 0
# select语句可以处理的最大记录数,默认0不限制
max-select-series = 0
# elect语句可以处理的最大"GROUP BY time()"的时间周期,默认0不限制
max-select-buckets = 0
5、碎片预创设置
[shard-precreation]
#预创建分区的最大提前时间,默认值 :30m
advance-period = "30m"
6、监控设置
[monitor]
#关闭监控模块,默认false
store-enabled = false
7、http端点设置
[http]
# 是否开启http请求日志,默认值:true
log-enabled = true
# 系统在非分块查询中可以返回的最大行数。默认设置0允许无限制的行数
max-row-limit = 10000
8、配置文件中支持的单位
纳秒:ns (nanoseconds)
微秒:us or µs (microseconds)
毫秒: ms (milliseconds)
秒:s (seconds)
分:m (minutes)
小时:h (hours)
天: d (days)
星期:w (weeks)
相关文章:
Influxdb 想要删除一个字段怎么办?
时序数据库 Influxdb 中 in 的替换用法,多表查询
初次使用时序数据库InfluxDB,安装、简单的命令及详解配置
新手上路,时序数据库InfluxDB命令总是报错,这篇文章不容错过!
SpringBoot2.0快速整合InfluxDB,新增、批量新增,通过反射机制构建查询结果,简单易懂,拿来即用
Linux CentOS 7.X 时序数据库InfluxDB的安装及简单使用
官网文档: