파악하기 어려운 파일 설명자 누출 문제를 해결하는 데 도움을 주세요.

파악하기 어려운 파일 설명자 누출 문제를 해결하는 데 도움을 주세요.

지난 6개월 동안 나는 제거할 수 없는 문제에 직면해 있었습니다. 무작위로 "열린 파일이 너무 많습니다"/"TCP/IP 소켓을 열 수 없습니다(24)"/"getaddrinfo: OK" I 내 응용 프로그램 로그에 "파일을 열지 않음" 오류가 표시됩니다.

나는 다음과 같은 스택을 실행합니다: mariadb, postgresql, memcached, redis 및 Docker 컨테이너 내의 여러 노드 기반 애플리케이션, Ruby on Rails(ruby 2.5.5, Rails 6) 애플리케이션 및 sidekiq를 실행하는 Passenger가 있는 Apache, 모두 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에서 이동하기 전에 다른 가능성을 조사하는 것이 매우 고통스러운 프로세스가 될 것이기 때문에 조사하고 싶습니다.

몇 가지 조언을 얻을 수 있기를 바랍니다.

답변1

이는 4096개의 inotify 핸들러만 있기 때문입니다. 한도를 늘렸더니 문제가 사라졌습니다.

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

관련 정보