Software Engineering Note

application 이 out of memory 로 죽을 때 개선 사례 본문

일하며 개발하며

application 이 out of memory 로 죽을 때 개선 사례

devmoons 2024. 2. 19. 00:40

책을 읽던 중 사례 연구를 다루는 부분을 읽다가 생각이 나서 작성해 본다.

 

평화롭던 어느 날 서버 애플리케이션이 내려가기 시작했다.

동일한 어플리케이션이 수십대 서버에서 돌아가고 있었는데 하나씩 차례대로 내려갔다.

 

우선은 서비스 복구가 먼저이므로 한 명은 애플리케이션을 재시작하기 시작했고, 다른 팀원들은 원인 분석에 들어갔다.

원인은 너무 큰 데이터가 들어왔고, 이 데이터를 읽어 객체로 변환하는 과정에서 발생한 것이었다.

다만, 무조건 발생하는 건 아니었다. 

이 애플리케이션은 요청한 size 만큼 결과를 내어주는데, 요청 size 가 작으면 버틸만했다.

 

원인을 알아냈으니 이제 개선을 해야 한다.

어떻게 개선을 할 수 있을까? 생각해 보자.

 

너무 큰 데이터를 읽으려고 하면 에러를 발생시켜 에러 응답이 나가도록 할 수도 있다.

적어도 서버가 죽어나가는 것보다는 나은 방법일 것이다.

 

하지만 정말 좋은 방법일까?

이 서비스로 요청을 보내는 사용처에서 감내해야 할 귀찮음을 생각해 보자.

아마도 에러 응답을 받으면, size 를 줄여 다시 요청을 보내야 할 것이다.

그래도 에러 응답을 받으면 다시 줄여서 보내야 한다. 한마디로 귀찮아진다.

 

적당한 개수를 결과로 내어주는 방법은 어떨까?

size=10 으로 요청을 하더라도 데이터의 크기가 너무 크면 5 정도만 내어주는 것이다.

이 방법으로 접근하면 사용처의 귀찮음도 없을 것이다.

가능한 방법인지 살펴보니, 가능해 보였다. 

데이터를 kafka 에서 읽어오고 있었는데, kafka 에서 읽어올 데이터의 양을 지정할 수 있었던 것이다.

byte 단위로 읽어와서 이를 응답용 객체로 만드는 부분을 개선하면 될 것 같았다.

 

여기서 다시 고민되는 부분이 있었다.

size=10 으로 요청했는데 5개만 내어주는 게 맞는 것일까? 

잘 모르는 사용자가 이와 같은 결과를 얻는다면 의아해할 것이다.

(일반적인 DB를 보라. 10개를 달라는데 5개만 내어놓는 제품이 있던가.)

물론, 내부용 서비스라 사용처에 설명하면 되는 문제이긴 하다.
하지만, 설명을 해야만 하는 설계는 좋은 설계가 아니라는 게 내 생각이다. 
대체로 "A로 요청하면, B가 나온다" 는 관례가 있다면, 그렇게 설계하는 게 좋다.

 

생각 끝에 sizeHint 라는 새로운 파라미터를 생각해 냈다.

sizeHint 로 지정한 만큼 내어주려고 하되, 꼭 그렇게 되진 않는다는 의미를 담고 싶었다.