회사에서 다른 팀들과 공용으로 사용하는 서버가 있는데 자꾸 이유없이 무작위로 프로세스가 죽는 현상이 발생했다.
각 프로젝트의 로그를 봐도 특별하게 남아있는게 없었고.. 원인은 메모리가 부족하여 리눅스 커널이 OOM Killer 작업을 실행한 것!
OOM Killer란 ?
OOM : Out of Memory
메모리 부족시 메모리를 확보하기 위한 것으로 프로세스의 메모리 할당시 메모리가 부족한 상황을 해결하기 위해 linux kernel이 OOM Killer를 실행한다. (점수를 매겨 높은 점수를 받은 프로세스를 죽여 메모리를 확보함)
프로세스를 종료시키는 순위
oom_badnesss() 메소드에서 프로세스별 점수를 계산하여 선택
OOM Killer는 점수를 매겨 가장 높은 점수를 받은 프로세스부터 kill 시키는데 이를 'OOM Scoring' 이라고 한다.
프로세스의 점수는 /proc/<pid>/oom_score 파일에서 직접 확인할 수 있다.
점수를 매기는 로직은 커널 코드에서 확인할 수 있으며, 아래 주석으로 OOM Killer의 목표를 알 수 있다.
/*
* oom_badness - calculate a numeric value for how bad this task has been
* @p: task struct of which task we should calculate
* @p: current uptime in seconds
*
* The formula used is relatively simple and documented inline in the
* function. The main rationale is that we want to select a good task
* to kill when we run out of memory.
*
* Good in this context means that:
* 1) we lose the minimum amount of work done
* 2) we recover a large amount of memory
* 3) we don't kill anything innocent of eating tons of memory
* 4) we want to kill the minimum amount of processes (one)
* 5) we try to kill the process the user expects us to kill, this
* algorithm has been meticulously tuned to meet the principle
* of least surprise ... (be careful when you change it)
*/
1) 완료된 작업의 수를 최대로 유지할 수 있게 한다.
2) 많은 양의 메모리를 복구한다.
3) 메모리를 많이 소비하지 않는(Leak이 발생하지 않은) 프로세스는 죽이지 않는다.
4) 최소한의 프로세스만 희생시킨다.
5) 사용자가 특별히 지정한 프로세스를 죽인다.
Kill 대상에서 제외시키는 방법
OOM Killer를 비활성화하는 것을 불가능하지만 scoring 대상에서 벗어나게하는 것(우선순위에서 밀려나게하는 것)은 가능하다.
따라서 종료되면 안되는 프로세스는 제외시켜야 하는데 비교적 간단한데 먼저 특정 프로세스의 PID를 확인해야 한다.
방법 1
/proc/<pid>/oom_adj 파일에 -17을 입력한다. oom_adj는 -17~ 15 범위의 값을 가지며 낮은 값일수록 우선순위에서 밀려난다.
$ echo -17 > /proc/<pid>/oom_adj
방법 2
/proc/<pid>/oom_score_adj 파일에 -1000을 입력한다. oom_score_adj는 -1000~1000 범위의 값을 가지며 낮은 값일수록 우선순위에서 밀려난다.
$ echo -1000 > /proc/<pid>/oom_score_adj
로그 위치
/var/log/messages
'개발 > Linux' 카테고리의 다른 글
[Linux] 패스워드 없이 서버 간 파일 전송하기 : ssh-keygen (1) | 2022.05.18 |
---|---|
[Linux] netstat 명령어로 네트워크 상태 확인하기(+ TCP 상태 전이) (2) | 2021.12.29 |
[Linux] 방화벽 설정하기 / 특정 포트 방화벽 오픈 (1) | 2021.12.22 |
[Linux] MySQL DB 백업 스크립트 - 자동으로 백업하기 (0) | 2021.12.17 |
[Linux] 리눅스에서 Unix ODBC 사용하기 (0) | 2021.12.16 |
댓글