Centos

幫助解決難以捉摸的文件描述符洩漏

  • November 3, 2020

在過去的 6 個月裡,我一直面臨著一個我似乎無法擺脫的問題:顯然是隨機的“打開的文件太多”/“無法打開 TCP/IP 套接字 (24)”/“getaddrinfo: 可以” t 打開文件”我的應用程序日誌中的錯誤。

我按如下方式執行堆棧:mariadb、postgresql、memcached、redis 和 Docker 容器內的幾個基於節點的應用程序、Apache with Passenger 執行 Ruby on Rails(ruby 2.5.5、Rails 6)應用程序和 sidekiq,所有這些都在 CentOS 上7 台機器 (3.10.0-1127.el7.x86_64),具有 6 個核心和 16Gb 的 RAM。在主要工作時間內,負載平均約為 10%,有小峰值,幾乎從未超過 30%。

最初我認為是這個其他 Java 應用程序導致了這個問題,在關閉它之後問題仍然會在更多時間後彈出。

無論我做什麼,我都無法在 CLI 中重現它,它顯然是隨機發生的,機器上沒有任何顯著負載。

服務重啟 1 小時後,我有以下統計資訊:

打開的文件總數

$ lsof | wc -l
30594

打開文件排名靠前的程序

$ lsof | awk '{print $1}' | sort | uniq -c | sort -r -n | head
  8260 mysqld
  4804 node
  2728 Passenger
  2491 container
  2095 postgres
  1445 dockerd
  1320 processor
   817 php-fpm
   720 httpd
   709 ruby

Mariadb 變數:

MariaDB [(none)]> Show global variables like 'open_files_limit';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| open_files_limit | 65535 |
+------------------+-------+
1 row in set (0.01 sec)

MariaDB [(none)]> Show global status like 'opened_files';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| Opened_files  | 6151  |
+---------------+-------+
1 row in set (0.00 sec)

我在 sysctl.conf 中將最大打開文件設置為 130k 認為它會解決問題,它只是為我爭取了一些時間,它仍然只是稍後才會彈出

$ sysctl fs.file-nr
fs.file-nr = 3360   0   131070

我只是做了一個快速的“ab”測試,打開文件的數量並沒有增加多少:

$ ab -n 1000 -c 10 http://www.example.com/

  9589 mysqld
  4804 node
  4577 Passenger
  3756 httpd
  3225 postgres
  2491 container
  2166 utils.rb:
  2080 ruby
  1445 dockerd
  1364 processor

這可能無關緊要,因為真正的使用者不會重複點擊首頁。

我有一種預感,罪魁禍首可能是 Docker(我在沒有對數據庫進行 docker 化的情況下執行了更繁忙的伺服器),但我寧願在將數據庫移出 Docker 之前調查其他可能性,因為這將是一個非常痛苦的過程。

將不勝感激一些指示

這是因為只有 4096 個 inotify 處理程序。我增加了限制,問題就消失了。

fs.file-max = 131070
fs.inotify.max_user_watches = 65536

引用自:https://unix.stackexchange.com/questions/613129