Linux에서 "열린 파일이 너무 많습니다" 오류를 해결하는 방법

게시 됨: 2022-06-29
bash 프롬프트를 표시하는 Linux 노트북
Fatmawati achmad zaenuri/Shutterstock.com

Linux 컴퓨터에서 시스템 리소스는 사용자 간에 공유됩니다. 공정한 몫보다 더 많이 사용하려고 하면 상한선에 도달하게 됩니다. 다른 사용자나 프로세스에 병목 현상을 일으킬 수도 있습니다.

공유 시스템 리소스

수많은 다른 작업 중에서 Linux 컴퓨터의 커널은 RAM 및 CPU 주기와 같은 유한한 시스템 리소스를 누가 사용하는지 항상 확인하느라 바쁩니다. 다중 사용자 시스템은 사람과 프로세스가 주어진 시스템 리소스를 적절한 것보다 더 많이 사용하지 않도록 지속적으로 주의를 기울여야 합니다.

예를 들어, 누군가가 CPU 시간을 너무 많이 잡아서 컴퓨터가 다른 모든 사람들에게 느리게 느껴진다는 것은 불공평합니다. Linux 컴퓨터를 사용하는 유일한 사람이더라도 프로세스에서 사용할 수 있는 리소스에 대한 제한이 설정되어 있습니다. 결국, 당신은 여전히 ​​​​다른 사용자입니다.

램이란? 알아야 할 모든 것
관련 RAM이란 무엇입니까? 알아야 할 모든 것

RAM, CPU 주기 및 하드 드라이브 공간과 같은 일부 시스템 리소스는 잘 알려져 있고 명백합니다. 그러나 모니터링되는 리소스가 훨씬 더 많고 각 사용자 또는 각 사용자가 소유한 프로세스 에는 상한선이 설정되어 있습니다. 그 중 하나는 프로세스가 한 번에 열 수 있는 파일 수입니다.

터미널 창에서 "너무 많은 파일이 열려 있습니다" 오류 메시지를 보거나 시스템 로그에서 발견했다면 이는 상한선에 도달했으며 프로세스에서 더 이상 파일을 열 수 없다는 의미입니다.

당신이 연 파일이 아닙니다

Linux가 처리할 수 있는 열린 파일 수에는 시스템 전체에 제한이 있습니다. 우리가 보게 되겠지만, 그것은 매우 큰 숫자이지만 여전히 한계가 있습니다. 각 사용자 프로세스에는 사용할 수 있는 할당이 있습니다. 그들 각각은 그들에게 할당된 시스템 전체의 작은 몫을 받습니다.

실제로 할당되는 것은 많은 파일 핸들 입니다. 열려 있는 각 파일에는 핸들이 필요합니다. 상당히 관대한 할당이 있더라도 시스템 전체의 파일 핸들은 처음 상상하는 것보다 빨리 소진될 수 있습니다.

Linux에서 "모든 것이 파일입니다"는 무엇을 의미합니까?
관련 Linux에서 "모든 것이 파일임"은 무엇을 의미합니까?

Linux는 파일인 것처럼 보이도록 거의 모든 것을 추상화합니다. 때때로 그들은 그저 평범한 오래된 파일일 것입니다. 그러나 디렉토리 열기와 같은 다른 작업도 파일 핸들을 사용합니다. Linux는 블록 특수 파일을 일종의 하드웨어 장치용 드라이버로 사용합니다. 문자 특수 파일은 매우 유사하지만 파이프 및 직렬 포트와 같이 처리량 개념이 있는 장치에서 더 자주 사용됩니다.

블록 특수 파일은 한 번에 데이터 블록을 처리하고 문자 특수 파일은 각 문자를 개별적으로 처리합니다. 이러한 특수 파일은 모두 파일 핸들을 통해서만 액세스할 수 있습니다. 프로그램에서 사용하는 라이브러리는 파일 핸들을 사용하고 스트림은 파일 핸들을 사용하며 네트워크 연결은 파일 핸들을 사용합니다.

이러한 다양한 요구 사항을 모두 추상화하여 파일로 표시하면 해당 요구 사항과의 인터페이스가 간소화되고 파이핑 및 스트림과 같은 작업이 가능합니다.

배후에서 Linux가 파일을 열고 파일 핸들을 사용하여 자체적으로 실행하고 있음을 알 수 있습니다. 사용자 프로세스는 신경쓰지 마십시오. 열려 있는 파일의 개수는 단순히 열었던 파일의 개수가 아닙니다. 운영 체제의 거의 모든 것이 파일 핸들을 사용합니다.

파일 핸들 제한

시스템 전체의 최대 파일 핸들 수는 이 명령으로 볼 수 있습니다.

 고양이 /proc/sys/fs/file-max 

열린 파일에 대한 시스템 최대값 찾기

이것은 터무니없이 많은 수의 9.2 quintillion을 반환합니다. 그것이 이론적인 시스템 최대치입니다. 64비트 부호 있는 정수에서 보유할 수 있는 가장 큰 값입니다. 열악한 컴퓨터가 한 번에 열려 있는 많은 파일을 실제로 처리할 수 있는지 여부는 완전히 다른 문제입니다.

사용자 수준에서는 가질 수 있는 최대 열린 파일 수에 대한 명시적인 값이 없습니다. 하지만 대략적으로 해결할 수 있습니다. 프로세스 중 하나가 열 수 있는 최대 파일 수를 찾으려면 -n (파일 열기) 옵션과 함께 ulimit 명령을 사용할 수 있습니다.

 ulimit -n 

프로세스가 열 수 있는 파일 수 찾기

그리고 사용자가 가질 수 있는 최대 프로세스 수를 찾기 위해 -u (사용자 프로세스) 옵션과 함께 ulimit 를 사용할 것입니다.

 ulimit -u 

사용자가 가질 수 있는 프로세스 수 찾기

1024와 7640을 곱하면 7,823,360이 됩니다. 물론 이러한 프로세스 중 상당수는 데스크탑 환경 및 기타 백그라운드 프로세스에서 이미 사용하고 있을 것입니다. 이것은 또 다른 이론적 최대값이며, 현실적으로 결코 달성할 수 없는 최대값입니다.

중요한 수치는 프로세스가 열 수 있는 파일의 수입니다. 기본적으로 이것은 1024입니다. 동일한 파일을 동시에 1024번 여는 것은 1024개의 다른 파일을 동시에 여는 것과 같다는 점에 주목할 가치가 있습니다. 모든 파일 핸들을 사용하면 완료됩니다.

프로세스가 열 수 있는 파일 수를 조정할 수 있습니다. 실제로 이 숫자를 조정할 때 고려해야 할 두 가지 값이 있습니다. 하나는 현재 설정되어 있거나 설정하려는 값입니다. 이것을 소프트 한계 라고 합니다. 하드 제한 도 있으며 이것이 소프트 제한을 올릴 수 있는 가장 높은 값입니다.

이것을 생각하는 방법은 소프트 리미트가 실제로 "현재 값"이고 상한이 현재 값이 도달할 수 있는 가장 높은 값입니다. 루트가 아닌 일반 사용자는 소프트 한계를 하드 한계까지 모든 값으로 올릴 수 있습니다. 루트 사용자는 하드 제한을 늘릴 수 있습니다.

현재 소프트 및 하드 제한을 보려면 -S (소프트) 및 -H (하드) 옵션과 -n (파일 열기) 옵션과 함께 ulimit 를 사용하십시오.

 ulimit -Sn
 ulimit -Hn 

프로세스 파일 핸들에 대한 소프트 및 하드 한계 찾기

소프트 제한이 적용되는 것을 볼 수 있는 상황을 만들기 위해 실패할 때까지 파일을 반복적으로 여는 프로그램을 만들었습니다. 그런 다음 사용된 모든 파일 핸들을 포기하기 전에 키 입력을 기다립니다. 이 프로그램은 open-files 라고 합니다.

 ./open-파일 

1024의 소프트 한계에 도달한 열린 파일 프로그램

파일 1021개를 열고 파일 1022개를 열려고 하면 실패합니다.

1024 빼기 1021은 3입니다. 다른 세 개의 파일 핸들은 어떻게 되었습니까? STDIN , STDOUTSTDERR 스트림에 사용되었습니다. 각 프로세스에 대해 자동으로 생성됩니다. 이들은 항상 0, 1 및 2의 파일 설명자 값을 갖습니다.

관련: Linux lsof 명령을 사용하는 방법

lsof 명령을 -p (프로세스) 옵션과 함께 사용하고 open-files 프로그램의 프로세스 ID를 사용하여 이를 확인할 수 있습니다. 편리하게 프로세스 ID를 터미널 창에 인쇄합니다.

 lsof -p 11038 

lsof 명령 출력의 stdin, stdout 및 stderr 스트림 및 파일 핸들

물론 실제 상황에서는 어떤 프로세스가 모든 파일 핸들을 갉아먹었는지 모를 수도 있습니다. 조사를 시작하려면 이 일련의 파이프된 명령을 사용할 수 있습니다. 컴퓨터에서 파일 핸들을 가장 많이 사용하는 15명의 사용자를 알려줍니다.

 이소프 | awk '{ $1 인쇄 " " $2; }' | 정렬 -rn | 유니크 -c | 정렬 -rn | 머리 -15 

가장 많은 파일 핸들을 사용하는 프로세스 보기

더 많거나 적은 항목을 보려면 -15 매개변수를 head 명령으로 조정하십시오. 프로세스를 식별한 후에는 프로세스가 불량하여 제어할 수 없기 때문에 너무 많은 파일을 여는 것인지 또는 실제로 해당 파일이 필요한지 파악해야 합니다. 필요한 경우 파일 핸들 제한을 늘려야 합니다.

소프트 한계 증가

소프트 제한을 늘리고 프로그램을 다시 실행하면 더 많은 파일이 열리는 것을 볼 수 있습니다. ulimit 명령과 -n (파일 열기) 옵션을 숫자 값 2048과 함께 사용합니다. 이것이 새로운 소프트 한계가 됩니다.

 ulimit -n 2048 

프로세스에 대한 새 파일 핸들 소프트 제한 설정

이번에는 2045개의 파일을 성공적으로 열었습니다. 예상대로 STDIN , STDOUTSTDERR 에 사용된 파일 핸들 때문에 2048보다 3이 적습니다.

영구적인 변경

소프트 제한을 늘리면 현재 셸에만 영향을 줍니다. 새 터미널 창을 열고 소프트 제한을 확인하십시오. 이전 기본값임을 알 수 있습니다. 그러나 프로세스가 가질 수 있는 지속적이고 재부팅 후에도 지속되는 열린 파일의 최대 수에 대한 새 기본값을 전역적으로 설정하는 방법이 있습니다.

오래된 조언은 종종 "/etc/sysctl.conf" 및 "/etc/security/limits.conf"와 같은 파일을 편집할 것을 권장합니다. 그러나 시스템 기반 배포판에서는 이러한 편집이 일관되게 작동하지 않습니다. 특히 그래픽 로그인 세션에서는 더욱 그렇습니다.

여기에 표시된 기술은 시스템 기반 배포에서 이를 수행하는 방법입니다. 작업해야 할 파일이 두 개 있습니다. 첫 번째는 "/etc/systemd/system.conf" 파일입니다. sudo 를 사용해야 합니다.

 sudo gedit /etc/systemd/system.conf 

system.conf 파일 편집

"DefaultLimitNOFILE" 문자열이 포함된 줄을 검색합니다. 줄의 시작 부분에서 해시 "#"을 제거하고 첫 번째 숫자를 프로세스에 대한 새로운 소프트 제한으로 원하는 값으로 편집합니다. 우리는 4096을 선택했습니다. 그 줄의 두 번째 숫자는 하드 리미트입니다. 우리는 이것을 조정하지 않았습니다.

system.conf 파일의 DefaultLimitNOFILE 값

파일을 저장하고 편집기를 닫습니다.

"/etc/systemd/user.conf" 파일에서 이 작업을 반복해야 합니다.

 sudo gedit /etc/systemd/user.conf 

user.conf 파일 편집

"DefaultLimitNOFILE" 문자열이 포함된 줄도 동일하게 조정합니다.

user.conf 파일의 DefaultLimitNOFILE 값

파일을 저장하고 편집기를 닫습니다. systemd 가 다시 실행되고 새 설정을 수집하도록 컴퓨터를 재부팅하거나 daemon-reexec 옵션과 함께 systemctl 명령을 사용해야 합니다.

 sudo systemctl 데몬-reexec 

시스템 재시작

터미널 창을 열고 새 제한을 확인하면 설정한 새 값이 표시되어야 합니다. 우리의 경우 4096이었습니다.

 ulimit -n 

ulimit -n으로 새로운 소프트 제한 확인

파일 탐욕 프로그램을 다시 실행하여 이것이 실제 운영 가치인지 테스트할 수 있습니다.

 ./open-파일 

열린 파일 프로그램으로 새로운 소프트 한계 확인

프로그램이 파일 번호 4094를 열지 못했습니다. 즉, 4093개의 파일이 열렸습니다. 4096보다 3이 작은 우리의 기대값입니다.

모든 것이 파일입니다

이것이 Linux가 파일 핸들에 의존하는 이유입니다. 이제 부족하기 시작하면 할당량을 늘리는 방법을 알 수 있습니다.

관련: Linux에서 stdin, stdout 및 stderr은 무엇입니까?