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

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

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

공유 시스템 리소스

수많은 작업 중에서 Linux 컴퓨터의 커널은 RAM 및 CPU 주기와 같은 유한한 시스템 리소스를 누가 사용하는지 항상 모니터링하느라 바쁘다. 다중 사용자 시스템은 사람과 프로세스가 시스템 리소스를 필요 이상으로 사용하지 않도록 지속적인 주의가 필요합니다.

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

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

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

당신은 파일뿐만 아니라

Linux가 처리할 수 있는 열린 파일 수에는 시스템 전체에 제한이 있습니다. 앞으로 살펴보겠지만 이것은 매우 많은 수이지만 여전히 한계가 있습니다. 각 사용자 프로세스에는 사용할 수 있는 선택 항목이 있습니다. 그들 각각은 그들에게 할당된 전체 시스템 양의 작은 몫을 받습니다.

실제로 눈에 띄는 것은 파일 설명자의 수입니다. 열리는 각 파일에 대해 핸들이 필요합니다. 상당히 관대한 리소스 할당이 있더라도 시스템 전체의 파일 설명자는 생각보다 빨리 소진될 수 있습니다.

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

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

이러한 모든 요구 사항을 추상화하여 파일로 표시하면 요구 사항과 더 쉽게 상호 작용할 수 있고 파이프라인 및 스트림과 같은 작업을 수행할 수 있습니다.

Linux가 사용자 프로세스는 말할 것도 없고 파일을 열고 파일 설명자만 실행하여 실행한다는 배후를 볼 수 있습니다. 열려 있는 파일의 수는 단순히 연 파일의 수가 아닙니다. 운영 체제의 거의 모든 것이 파일 설명자를 사용합니다.

파일 설명자 제한

이 명령을 사용하면 파일 디스크립터의 최대 시스템 수를 볼 수 있습니다.

cat /proc/sys/fs/file-max

이것은 터무니없이 많은 9.2 quintillion을 반환합니다. 이것은 시스템의 이론상 최대값입니다. 이것은 64비트 부호 있는 정수에 저장할 수 있는 최대값입니다. 열악한 컴퓨터가 동시에 열려 있는 너무 많은 파일을 처리할 수 있는지 여부는 완전히 다른 문제입니다.

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

ulimit -n

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

ulimit -u

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

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

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

소프트 한계는 실제로 “현재 값”이고 상한은 현재 값이 도달할 수 있는 최대 값입니다. 루트가 아닌 일반 사용자는 소프트 한계를 하드 한계까지 모든 값으로 올릴 수 있습니다. 루트 사용자는 하드 제한을 늘릴 수 있습니다.

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

ulimit -Snulimit -Hn

소프트 제한이 적용되는 것을 볼 수 있는 상황을 만들기 위해 실패할 때까지 파일을 반복적으로 여는 프로그램을 만들었습니다. 그런 다음 사용 중인 파일 설명자를 버리기 전에 키 누르기를 기다립니다. 프로그램이 호출 open-files됩니다.

./open-Files

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

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

(process) 매개변수와 프로그램의 프로세스 ID와 lsof함께 명령을 사용하여 볼 수 있습니다 . 편리하게는 프로세스 ID를 터미널 창에 인쇄합니다.-popen-files

lsof -p 11038

물론 실제 상황에서는 어떤 프로세스가 모든 파일 디스크립터를 방금 먹었는지 모를 수도 있습니다. 조사를 시작하기 위해 이 일련의 명령을 사용할 수 있습니다. 컴퓨터에서 가장 활동적인 15명의 파일 설명자 사용자에 대해 알려줍니다.

lsof | awk '{ print $1 ""$2; }' | sort -rn | uniq -c | sort -rn | head -15

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

소프트 한계 증가

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

ulimit -n 2048

이번에는 2045개의 파일을 성공적으로 열었습니다. STDIN예상대로 , STDOUT및 에 사용된 파일 설명자로 인해 2048보다 3이 적습니다 STDERR.

영구적인 변경

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

레거시 조언은 종종 “/etc/sysctl.conf” 및 “/etc/security/limits.conf”와 같은 파일을 편집할 것을 권장합니다. 그러나 시스템 기반 배포에서 이러한 변경 사항은 특히 그래픽 로그인 세션에서 일관되게 작동하지 않습니다.

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

sudo gedit /etc/systemd/system.conf

“DefaultLimitNOFILE” 문자열이 포함된 줄을 찾습니다. 줄 시작 부분에서 해시 표시 “#”를 제거하고 첫 번째 숫자를 원하는 새 프로세스 소프트 제한으로 변경합니다. 우리는 4096을 선택했습니다. 이 줄의 두 번째 숫자는 하드 제한입니다. 우리는 그것을 규제하지 않았습니다.

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

“/etc/systemd/user.conf” 파일로 이 작업을 반복해야 합니다.

sudo gedit /etc/systemd/user.conf

“DefaultLimitNOFILE” 문자열이 포함된 줄을 동일하게 변경합니다.

파일을 저장하고 편집기를 닫습니다. 컴퓨터를 다시 시작하거나 매개 변수 systemctl와 함께 명령을 사용하여 컴퓨터를 다시 실행하고 새 설정을 수락해야 합니다.daemon-reexecsystemd

sudo systemctl daemon-reexec

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

ulimit -n

파일 욕심 많은 프로그램을 다시 실행하여 이것이 실제 작동하는 값인지 확인할 수 있습니다.

./open-Files

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

모든 것은 파일이다

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

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다