OOM(Out Of Memory) killer 회피하기

문법식·2022년 3월 9일
0
post-thumbnail

운영 중인 앱의 스프링 부트 프로젝트가EC2 서버에서 종료한 적이 없는데 자꾸 종료되는 일이 발생했다. 프로젝트의 오류 로그도 없고 EC2도 인스턴스 상태 검사 오류가 발생한 적이 없었다. 원인이 무엇인가 확인해보니 OOM(Out Of Memory) killer의 대상이 되서 프로젝트가 종료된 것이다.

OOM killer

  • https://medium.com/@EJSohn/out-of-memory-killer-%ED%9A%8C%ED%94%BC%ED%95%98%EA%B8%B0-9efc65f88c92
    위 블로그의 글을 보면 OOM killer의 작동 방식을 알 수 있다. EC2 서버가 메모리가 부족한 상황이 오면 OOM killerOOM Scoring을 통해 가장 나쁜 점수를 가진 프로세스를 종료한다. 블로그를 참고하면 메모리를 많이 차지하는 프로세스가 나쁜 점수를 받아 죽을 수 있는데 현재 EC2 서버에서 스프링 부트 프로젝트가 많은 메모리를 차지한다. 그래서 OOM killer의 대상이 된 것이다. 그러나 스프링 부트 프로젝트는 앱의 백엔드를 담당하는 프로세스이기 때문에 OOM killer의 대상이 되면 안된다. 그러므로 아래의 방법을 통해 OOM killer의 대상에서 제외한다. 일단 OOM killer로 종료된 것인지 확인해보겠다.

프로젝트 로그

dmesg | grep -E -i -B100 'killed process'

위의 명령으로 종료된 프로세스의 목록을 확인해보았다.

[52*2*5.*54*91] Out of memory: Killed process 30264 (java) total-vm:2858720kB, anon-rss:255412kB, file-rss:0kB, shmem-rss:0kB, UID:0 pgtables:916kB oom_score_adj:0

로그를 확인해보니 Java 프로세스가 종료되었다.

cat /var/log/kern.log

위의 명령으로 Java 프로세스가 언제 종료되었는지 확인해보았다.

Mar  8 11:32:12 ip-172-31-10-193 kernel: [52*2*5.*54*35] oom-kill:constraint=CONSTRAINT_NONE,nodemask=(null),cpuset=/,mems_allowed=0,global_oom,task_memcg=/user.slice,task=java,pid=30264,uid=0
Mar  8 11:32:12 ip-172-31-10-193 kernel: [52*2*5.*54*91] Out of memory: Killed process 30264 (java) total-vm:2858720kB, anon-rss:255412kB, file-rss:0kB, shmem-rss:0kB, UID:0 pgtables:916kB oom_score_adj:0
Mar  8 11:32:12 ip-172-31-10-193 kernel: [52*2*5.*93*89] oom_reaper: reaped process 30264 (java), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB

EC2 모니터링 로그

상황을 확인해보니 UTC기준 3월 8일 11:30분쯤에 OOM Killer가 스프링 부트 프로젝트를 종료했고 EC2 모니터링 로그에 UTC기준 3월 8일 11:30분쯤에 CPU 사용률이 30%까지 올라갔다.
CPU 사용량이 급증하는 과정에서 EC2 서버의 메모리가 부족해졌고 그래서 OOM killer가 스프링 부트 프로젝트를 종료한 것이었다. 시스템이 멈추는 것을 막기 위해 OOM killer는 종료할 수 없게 되어있다. 그러나 스프링 부트 프로젝트는 위에서 말했듯이 OOM killer의 대상이 되면 안되므로 아래의 방법으로 회피한다.

OOM killer 회피

$ echo -17 > /proc/<pid>/oom_adj

OOM killer를 끌 수는 없지만 OOM killerOOM scoring 대상에서 벗어나는 것은 가능하다. 위의 명령으로 oom_adj 값을 -17로 설정하는 것이다. -17 값은 OOM_DISABLE의 상수 값입니다. 위의 명령으로는 권한 문제가 발생해서 실제로는 아래의 명령을 적용하였다.

$ sudo bash -c "echo '-17' | tee /proc/<pid>/oom_adj"
profile
백엔드

0개의 댓글