前言
某天当prometheus添加到大致2500个指标(Targets)时,prometheus开始出现了打开缓慢,无法重新加载配置文件,并且服务偶尔会挂掉的现象.于是进行了对这个问题进行了处理.
报错
查看服务日志和系统日志
systemctl status prometheus
journalctl -u prometheus
tail -f /var/log/messages
msg="Scrape commit failed" err="write to WAL: log samples: create new segment file: open /data/prometheus/wal/00007563: too many open files"
这几个日志都包含Too many open files
原因及处理
上面的报错通常是由于limit设置导致,
系统或某进程 在某个时刻打开了超过系统限制的文件数量以及通讯链接数
<1>查看系统的limit设置
ulimit -n
(open files 系统通常默认为1024)
or
cat /etc/security/limits.conf
* soft nofile 102400 ##任何用户可以打开的最大的文件描述符数量,默认1024
* hard nofile 102400
* soft nproc 102400 #任何用户可以打开的最大进程数
* hard nproc 102400
由上可知参数相当大,已经是系统调优过了
<2>查看该进程的文件句柄数
查询prometheus进程pid
ps aux |grep prometheus
cat /proc/<pid>/limits
Limit Soft Limit Hard Limit Units
Max cpu time unlimited unlimited seconds
Max file size unlimited unlimited bytes
Max data size unlimited unlimited bytes
Max stack size 8388608 unlimited bytes
Max core file size 0 unlimited bytes
Max resident set unlimited unlimited bytes
Max processes 256486 256486 processes
Max open files 1024 1024 files
Max locked memory 65536 65536 bytes
Max address space unlimited unlimited bytes
Max file locks unlimited unlimited locks
Max pending signals 256486 256486 signals
Max msgqueue size 819200 819200 bytes
Max nice priority 0 0
Max realtime priority 0 0
Max realtime timeout unlimited unlimited us
由上可知,当前进程的最大打开文件数较低,应该调这个就可以了
<3>查看系统中进程打开文件数的排序(或查看该进程的已打开文件数)
(Centos6使用)
lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr|more
or
lsof -n |awk '{print $2}'|sort|uniq -c |sort -nr|more |grep <pid>
在Centos7及其以上版本,通过lsof统计的文件句柄数比Centos7以下系统高很多倍,
是lsof的版本不同造成的,新版本的lsof 默认打印TID(-K 参数),因此上方的命令建议在Centos6中使用
lsof -p <pid> |wc -l 是统计某个进程打开的文件句柄数
lsof -n|grep <pid> |wc -l 是统计某个进程及其所有线程打开的文件句柄数
<4>统计多少文件被某进程打开
(Centos7使用)
lsof -p <pid> |wc -l
or
ls /proc/<pid>/fdinfo/ | grep '^[0-9]'| wc
<5>调整该服务的limit
由于配置的systemctl的管理方式,修改service文件,并重新加载即可
通常在/etc/systemd/system/ 或 /usr/lib/systemd/system/
cat /usr/lib/systemd/system/prometheus.service
[Unit]
Description=Prometheus Node Exporter
After=network.target
[Service]
ExecStart=/data/prometheus/prometheus --config.file=/data/prometheus/prometheus.yml --storage.tsdb.path=/data/prometheus --web.read-timeout=5m --web.max-connections=100 --storage.tsdb.retention=10d --query.max-concurrency=20 --query.timeout=2m --web.enable-lifecycle
User=root
LimitNOFILE=10240
[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl restart prometheus
系统limit调优补充
<1>资源限制配置文件
cat /etc/security/limits.conf
#当前shell该用户能打开的最大文件数
* soft nofile 102400
* hard nofile 102400
#当前shell该用户所能创建的最大进程数
* soft nproc 102400
* hard nproc 102400
nofile的值的上限是由/proc/sys/fs/nr_open限制的,默认是1048576
如果你修改limit.conf的nofile,超过这个值就会导致连接ssh失败
---------------------------------------------------------------
<2>当前系统使用的打开文件描述符数
cat /proc/sys/fs/file-nr
3072 0 794326
系统已分配使用的打开文件描述符数 第二个数为分配后已释放的(目前已不再使用) 内核可分配最大文件描述符数(file-max)
---------------------------------------------------------------
<3>系统内核最大可分配文件描述符数
cat /proc/sys/fs/file-max
6815744
临时修改方法:
sysctl -w “fs.file-max=6553560”
永久修改file-max的值
vi /etc/sysctl.conf添加
fs.file-max = 6553560
---------------------------------------------------------------
<4>单个进程可分配的最大文件数
cat /proc/sys/fs/nr_open
1048576
临时修改方法:
sysctl -w “fs.nr_open=1048576”
永久修改file-max的值
vi /etc/sysctl.conf添加
fs.nr_open=1048576
---------------------------------------------------------------
<5>总结
file-max的值要大于nr_open,nr_open单进程最大能配置的文件数量不能大于file-max
所有进程打开的文件描述符数不能超过/proc/sys/fs/file-max
单个进程打开的文件描述符数不能超过user limit中nofile的soft limit
nofile的soft limit不能超过其hard limit
nofile的hard limit不能超过/proc/sys/fs/nr_open