linux 的文件描述符
文件描述符(FD:file descriptors),也可以说是文件句柄,当某个程序打开文件时,内核返回相应的文件描述符,程序为了处理该文件必须引用此描述符。文件描述符是一个正整数,用以标明每一个被进程所打开的文件和 socket。最前面的三个文件描述符(0,1,2)分别与标准输入(stdin),标准输出(stdout)和标准错误(stderr)对应,后面打开的文件依此类推对应 3、4…… 。
linux 系统对每个用户、进程、或整个系统的可打开文件描述符数量都有一个限制,一般默认为 1024。当我们在系统或应用的日志中碰到“too many open files”错误记录时,这个其实不是说打开的文件过多,而是打开的文件描述符数量已达到了限制,这时就需要增加文件描述符的数量限制了。
获取系统打开的文件描述符数量
1 | [root@localhost ~]# cat /proc/sys/fs/file-nr |
- 第一列 1216 :为已分配的 FD 数量
- 第二列 0 :为已分配但尚未使用的 FD 数量
- 第三列 197787 :为系统可用的最大 FD 数量
已用 FD 数量=为已分配的 FD 数量 - 为已分配但尚未使用的 FD 数量。注意,这些数值是系统层面的。
获取进程打开的文件描述符数量
1 | [root@localhost ~]# pidof vim |
可以看到 vim 进程用了 4 个 FD
更改文件描述符限制
当碰到“too many open files”错误时,就需要增加文件描述符的限制数量,系统的默认文件描述符都比较大,一般来说,只需增加用户或进程的就可以了
用户或进程
1 | [root@localhost ~]# ulimit -n |
注意,使用 ulimit 命令更改后只是在当前会话生效,当退出当前会话重新登录后又会回到默认值 1024,要永久更改可以修改文件 /etc/security/limit.conf
,如
1 | [root@localhost ~]#vi /etc/security/limits.conf |
加入 “abc hard nofile 10240”
abc:用户名,即允许 test 使用 ulimit 命令更改 FD 限制,最大值不超过 10240,更改后 abc 用户的每一个进程(以 abc 用户运行的进程)可打开的 FD 数量为 10240 个
hard:限制类型,有 soft/hard 两种,达到 soft 限制会在系统的日志(一般为/var/log/messages)里面记录一条告警日志,但不影响使用。hard,达到这个限制,有日志且会影响使用。
nofile:限制的内容,nofile - max number of open files
1024 :值
更改后,退出终端重新登录,用 ulimit 看看有没有生效,如果没生效,可以在 abc 用户的.bash_profile 文件加上 ulimit -n 10240 ,以使用户 abc 每次登录时都会将 FD 最大值更改为 10240,如:
1 | [root@localhost ~]#echo "ulimit -n 10240" >> /home/abc/ .bash_profile |
limit.conf 文件里面本身已有很详细的使用方法,这个下次可以说说。
系统级别
将整个操作系统可以使用的 FD 数量更改为 51200
1 | [root@localhost ~]# echo "51200" > /proc/sys/fs/file-max |
像这样更改在系统重启后会恢复到默认值,要永久更改可以在 sysctl.conf 文件加上 fs.file-max = 51200
如:
1 | [root@localhost ~]# echo "fs.file-max = 51200" >> /etc/sysctl.conf |
获取打开的文件数量
linux 的一切皆为文件,那么如何知道系统/应用打开了哪些或是多少个文件呢?很简单,用 lsof 命令就行了,lsof,list open files 的简写,可列出程序或系统正在使用的文件。
获取整个系统打开的文件数量
1 | [root@localhost ~]# lsof |wc -l |
获取某个用户打开的文件数量
1 | [root@localhost ~]# lsof -u test |wc -l |
获取某个程序打开的文件数量
1 | [root@localhost ~]# pidof vim |
上面所示只是用 lsof 来显示已打开的文件数量,lsof 的功能远不止这些,有兴趣可以 man lsof 看一下
指标 | 测试值 |
---|---|
测试时长 | 12 小时 15 分 |
数据量 | 108000000 |
平均消费速率(TPS) | 6500 条/秒 |
总结 | 在这种高峰数据量的情况下,mthinkingdata 会堵塞一部分流量,除非优化利用 Redis 的机制,使服务支持多个 Redis 实例存储 |