수업 조교

[교내 강의 조교 일지 02] 퍼~~~펑! (서버와 내 속이 터지는 소리)

가나타르트 2024. 4. 22. 17:43

1. 개요

지난 일지에서는 Online Judge 사이트를 AWS 무료 티어 계정을 이용해서 열어보았다.

이번에는 사이트가 터지지 않도록 어떻게 관리하는 지에 대해서 써보려 한다.

2. 무료는 이유가 있다

일단 무료로 제공하는 건 다 이유가 있는 듯 하다. 그냥 모든 게 딸린다. 모든 부분이 딸려서 하나라도 터진다면 채점 사이트 자체가 먹통이 되버리는 문제가 있다. 따라서 어떤 문제들이 지금까지 발생했고, 어떻게 대처했는 지에 대해서 적어보려고 한다.

2-1. Memory Limit Error (진짜 에러임)

백준에서 보통 문제 당 메모리 제한을 256MB 정도로 둔다. 하지만 우리 나약한 서버는 256MB로 두면 돌아오지 못할 강을 건너고 만다. 메모리 제한을 너무 크게 두면 제출 하나만 해도 제출 코드를 처리하느라 서버가 멈춰버린다. 무료 티어라도 RAM은 1GB인데 왜 256MB 짜리 제출 하나에 터져버릴까는 의문이 들 수 있다.

 

그런데 이는 채점 현황을 보면 바로 알 수 있다. 이 온라인 저지 시스템은 256MB를 넘긴다고 바로 프로그램을 종료하는 것이 아니라, 제한의 2배 정도 넘기려고 하면 프로그램을 종료한다는 것이다. 실제로 32MB 정도로 제한을 두고 MLE가 나는 코드를 제출해봤는데, 약 50~60MB 정도 사용을 하고 MLE가 발생하였다.

 

따라서 256MB로 제한을 걸어도 코드는 그보다 훨씬 많은 메모리를 사용하고, 그로 인해 서버는 맛탱이가 가비런다. 서버가 얼마나 심각한 상황인지는 인스턴스 모니터링을 하면 확인할 수가 있다. 실제로 서버가 제출 코드 처리로 멈춰버리면 CPU 사용률이 계속 99.9%를 찍게 된다. 몇 십분동안 CPU 사용률이 최고점을 찍는 걸 보면 속의 열불도 최고점을 찍게 된다.

 

이를 막기 위해서 일단 2가지 처리를 했다. 일단 첫 번째로 가능한 것은 메모리 제한 줄이기이다. 일단 내 수업에서는 C++과 파이썬의 제출을 허용하고 있기 때문에 이를 고려해야 했다. python의 경우, C++보다 평균적으로 메모리를 많이 사용하기 때문에 메모리 제한을 C++ 기준으로 걸어버리면 맞아야 할 코드도 틀렸다 뜨기 때문이다. 그래서 일단 적당히 모든 문제의 메모리 제한을 32MB로 걸어두었다. 왜 32MB로 했냐 물어보면 16MB로 하면 너무 적고, 64MB는 너무 많아서다. 그게 전부다.

 

하지만 1GB라는 RAM 용량은 답도 없는 게 사실이다. 따라서 이를 어느정도 극복하기 위해 스왑 메모리가 존재한다. 스왑 메모리란 디스크의 일부를 RAM으로 대체해서 사용하는 것이다. 물론 RAM보단 속도는 느리지만 서버가 죽어나가는데 인공 호흡기라도는 달야아 하지 않을까. 스왑 메모리 설정은 어렵지 않다. ssh로 서버에 접속한 후 아래 명령어들만 치면 된다. 아래 명령어는 2GB의 스왑 메모리 공간을 마련하는 명령어이다.

sudo fallocate -l 2G swapfile
sudo chmod 600 swapfile
sudo mkswap swapfile
sudo swapon swapfile

이후 free -h 명령어를 통해 스왑 메모리가 잘 설정되었는지 확인할 수 있다.

 

이렇게 고치고 나면 어느정도 RAM이 딸려서 채점이 밀리는 것은 막을 수 있다. 물론 나는 수업에서 활용하는 채점 서버라 어느 정도 감당이 되는 거지만, 조금 더 많은 사람이 쓰는 채점 서버면 이걸로는 해결이 안될 수 있다.

2-2. 디스크 2G 빼앗은 스노우볼이 1달 뒤에 터지네

이렇게 서버를 만져놓고 방치하다가 지난 주에 서버가 터져버리고 말았다. 만약 2-1.처럼 MLE로 터졌던 거라면 인스턴스를 종료하고 다시 재시작하면 복구가 된다. Rejudge 버튼을 누르기 전까지는 채점 도중 중단된 코드를 다시 실행하지 않기 때문이다. 하지만 이번에는 상황이 뭔가 다른 것 같았다. 사실 2주 전에 disk 용량이 많이 찬 것 같은 징조가 있었다. 용량이 큰 테스트 케이스를 업로드하려 했으나 용량 제한에 걸려서 업로드를 하지 못한 것이다. 그래서 테스트 케이스 용량을 절반으로 줄여서 하니 일단 업로드는 되었다. 그리고 업로드는 되길래 일단 냅뒀는데...

 

이후 서버가 다운이 되어버리고 말았다! 저번에 말했듯이 pem 파일을 날려먹어서 ssh 접속도 안되고, 뭐 답이 없다. 그래서 일단 터진 서버는 터진 상태로 내비두고 이전 글처럼 새로 서버를 열었다.

 

서버가 터지는 이유는 용량이 큰 테스트 케이스 + 많은 제출의 무친 콜라보가 아닌가 싶다. 내 기억에 마지막으로 서버가 터지기 전 2,000 개가 넘어가는 제출이 있었던 걸로 기억한다. 원래는 채점 사이트를 완전 자동화로 파싱해서 코드 제출 내역을 미리 내 컴퓨터에 저장해두려 했는데, 완전 자동화는 불가능하고 일부 노가다를 해야만 코드를 저장할 수 있었다. 그래서 이걸 미루다가 결국 서버가 터져버렸다.

 

그래서 이를 어떻게 극복해야 하냐? 뭐 별 방법이 없다. 기존 문제들을 지우거나 주기적으로 코드를 저장해두고 서버를 다시 파는 방법밖엔 없지 않을까? 그래서 서버 반자동? 코드 복구 시스템을 마련해두긴 했다. 이에 관한 포스팅은 언젠간 하지 않을까.

 

암튼 디스크 용량은 그렇다 쳐도 일단 터져버린 기존 서버에서 내용을 어떻게든 가져와야 한다. 이건 열심히 시도해보고 복구에 성공한다면 포스팅을 하려고 한다. 복구에 실패한다면? 그런 미래는 존재해선 안된다.

 

그나마라고 해야 할까 메모리를 어느 정도 아끼는 법은 존재한다. 만약 문제에 테스트 케이스를 업로드했는데, 문제가 있어서 테스트 케이스를 다시 업로드한다면, 이 사이트는 기존 테케를 지우는 게 아니라 어딘가 깊숙한 곳에 방치해둔다. 다행히도 이 방치된 놈들을 없앨 수 있는데, root의 Management 창에서 General > Prune Testcase 에서 방치된 테케 목록들을 볼 수 있다. 여기서 쓰레기통 버튼을 누르면 모두 지울 수 있다.

 

3. 서버 여는 건 사람이 할 짓이 아니다

좋은 컴퓨터도 아니고 무료 서버를 받아서 이를 이용해 실질적으로 무언가를 하는 것은 쉽지 않다. 설령 그것이 교내 수업 원툴일지라도. 만약 무료 서버로 이렇게 수업 운영을 해야 한다면 다음에는 1달 주기로 서버를 리셋시켜야 할 것 같다. 제출이랑 문제들이 쌓이니 용량이 버티질 못한다.

 

암튼 서버 문제는 이렇게 어느 정도 해결해두고, 다음 포스팅에는 과제 문제를 어떻게 만들고 사이트에 올리는 지를 적어보려 한다.