리눅스 시스템 자원 제한.
아주 접속이 많은 웹 서버를 운영하던중에 다음과 같은 종류의 메시지를 접하는 경우가 종종 있다.
1 |
Too many open files (24) |
너무나 많은 파일을 열었다는 건데, 도대체 무슨 파일을 열었다는건지 서비스하는 웹 페이지의 파일 개수도 많지도 않은데 말이다.
이 문서는 이러한 의문을 가지는 사람들 위한 것이다.
모든게 파일!
리눅스 시스템은 모든것이 파일이다. 장치도 파일이다. 그 유명한 /dev/ 디렉토리에 있는 팡리들이 바로 장치들이다. 저 파일들에게 cat 명령어로 데이터를 던져주면 그것을 알아먹는 장치는 동작하게 된다.
또, 리눅스에서 프로그램의 실행은 혼자 동작하는 것이 아니다. C 프로그램을 해본사람이라면 라이브러리(Library) 개념을 알고 있을 텐데 프로그램이 동작할때에는 이러한 라이브러리 파일도 함께 로딩(Loading)된다. 예를들어 sshd 라는 명령어가 어떤 라이브러리들고 로딩되는지는 다음과 같이 알수 있다.
1 |
lsof -c sshd |
sshd 가 실행중인데, 현재 이 프로그램은 아주 많은 파일들을 사용하고 있다. 프로그램 실행을 위한 라이브러리 파일뿐만 아니라 sshd 설정파일들도 눈에 보인다.
그런데, 리눅스 시스템에서 각 프로그램에게 64개 이상의 파일을 사용하지 못하도록 설정되어 있다면 어떻게 될까? 그것이 바로 위에서 만나게 되는 메시지이다.
리눅스 시스템 자원 제어하기.
리눅스 시스템은 위에서 설명한 것처럼 열어야할 파일 개수뿐만아니라 다양한 자원들에게 대해서 제어를 할 수 있도록 해놨다. 이를 위해서 ulimit 라는 명령어를 제공하고 이를 통해서 각각의 자원들을 제어할 수 있다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# - core - limits the core file size (KB) # - data - max data size (KB) # - fsize - maximum filesize (KB) # - memlock - max locked-in-memory address space (KB) # - nofile - max number of open file descriptors # - rss - max resident set size (KB) # - stack - max stack size (KB) # - cpu - max CPU time (MIN) # - nproc - max number of processes # - as - address space limit (KB) # - maxlogins - max number of logins for this user # - maxsyslogins - max number of logins on the system # - priority - the priority to run user process with # - locks - max number of file locks the user can hold # - sigpending - max number of pending signals # - msgqueue - max memory used by POSIX message queues (bytes) # - nice - max nice priority allowed to raise to values: [-20, 19] # - rtprio - max realtime priority |
위에 나열한 것처럼 cpu, login, file open, file size 등 다양한 것에 대해서 제한(limit)을 둘 수 있다.
또, 각각의 제한은 리눅스 시스템 계정 사용자별, 그룹별, 프로세스별로 줄 수 있다. 그렇다면 현재 로그인한 상태에서 제한은 다음과 같이 확인이 가능하다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
core file size (blocks, -c) 0 data seg size (kbytes, -d) unlimited scheduling priority (-e) 0 file size (blocks, -f) unlimited pending signals (-i) 14848 max locked memory (kbytes, -l) 64 max memory size (kbytes, -m) unlimited open files (-n) 1024 pipe size (512 bytes, -p) 8 POSIX message queues (bytes, -q) 819200 real-time priority (-r) 0 stack size (kbytes, -s) 10240 cpu time (seconds, -t) unlimited max user processes (-u) 14848 virtual memory (kbytes, -v) unlimited file locks (-x) unlimited |
만일 슈퍼 유저(혹은 root 유저) 라면 다른 사용자의 제한도 다음과 같이 확인할 수 있다.
1 |
su - linux -c 'ulimit -a' -s '/bin/bash' |
Soft and Hard Limit
시스템 리소스 제한에는 Soft Limit 와 Hard Limit 가 있다. Hard Limit 는 Soft Limit 의 최대임계치로서 이 제한에 걸리면 곧바로 문제가 된다. 하지만 Soft Limit 는 최대 임계치는 아니여서 이것을 벗어나더라도 Hard Limit 까지는 문제가 없다. 대신에 Soft Limit 를 벗어났을때에 메일을 보낸다든지 경고 메시지를 내보내는등 조만간에 최대 임계치에 도달할 수 있다는 것을 미리 알려줄 수 있다.
사용자별, 자원별 제한
사용자별, 자원별로 제한을 둘 수 있다. 이는 /etc/security/limits.conf 파일에 명시하면 사용자별, 자원별로 제한이 된다. 파일을 열어보면 자원별은 item 으로 부르고 있는데 제한을 두고 싶은 시스템 자원에 대한 지시어를 찾아서 적으면 된다.
예를들어 systemv 사용자에 대해 최대 파일 열기 디스크립터 개수를 제한고 싶다면 다음과 같이 해주면 된다.
1 2 |
systemv soft nofile 500000 systemv hard nofile 500000 |
이 내용을 적은 이후부터 systemv 로 시스템에 로그인 하는 사용자는 바로 적용이 되고 이 사용자 계정으로 실해되는 데몬 프로그램은 재시작을 해주면 바로 적용된다.
각 프로세스당 자원에 대한 제한을 알고 싶다면 PID 를 알아낸뒤에 다음과 같이 해주면 된다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
]# cat /proc/377/limits Limit Soft Limit Hard Limit Units Max cpu time unlimited unlimited seconds Max file size unlimited unlimited bytes Max data size unlimited unlimited bytes Max stack size 10485760 unlimited bytes Max core file size 0 unlimited bytes Max resident set unlimited unlimited bytes Max processes 14848 14848 processes Max open files 1024 4096 files Max locked memory 65536 65536 bytes Max address space unlimited unlimited bytes Max file locks unlimited unlimited locks Max pending signals 14848 14848 signals Max msgqueue size 819200 819200 bytes Max nice priority 0 0 Max realtime priority 0 0 Max realtime timeout unlimited unlimited us |