[입 개발] Redis, vm.overcommit_memory 을 아시나요?

혹시 Redis를 시작했을 때 나오는 Warning 에 대해서 보신적이 있는지 모르겠습니다.


[9063] 23 Jan 20:55:09.781 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.

“이것만 보셔도, 아 남들 다 아는 얘기를 이제서야 하는거야?” 라는 얘기를 하실분들이 꽤 계실겁니다. 하지만, 전 까먹고 있었고, 잘 모르고 있었다는 ㅎㅎㅎ

 

이 얘기를 하기전에 잠시 가상 메모리라는 넘에 대해서 얘기를 해야 합니다. 뭐, 간단하게 말하면, 우리의 OS군은 가상메모리라는 것을 이용하고 있습니다. 이건 뭐냐 하면 원래 Physical Memory 가 4G가 안될 때, 4G 라는 가상적인 메모리 공간을 주고 이를 이용할 수 있도록 한 기술인데, 요새 4G 안넘는 장비가 어디 있어요라고 물어보신다면, 64bit로 넘어가면서 부터는 제한이 거의 없어져서, 이런 메모리 주소를 충분히 사용하게 해주기 위해서 OS가 실제 물리메모리와 가상 메모리간에 적절히 커플 매칭을 시켜주고, 깨지게 만드는 기술입니다. 이럴 때, 실제 사용하는 물리메모리보다 많이 할당하게 되면, 어떻게든 사용할 메모리를 만들어주기 위해서, 기존에 있던 메모리를 디스크에 쓰고 이 메모리를 할당해주게 됩니다. 다시 필요해지면 다른 메모리를 디스크에 써주고 다시 읽어드려서, 실제로 있는 거 보다 많은 메모리를 쓸 수 있게 해주는 거죠. 이를 swapping이라고 합니다.

 

그런데 Redis 나 이런 메모리를 쓰는 MMDB 같은 경우, 하드 디스크에 접근하는 순간 하드가 무지막지하게 개기기 때문에, 느려집니다. 그런데 위와 같은 경우라면 모자라는 메모리를 위해서 디스크에 접근하게 되면, 그 때부터, 미친듯이 달리던 아우토반에서 부산 자갈치 시장을 차로 돌아다녀야 하는 상황이 벌어집니다.

 

그런데 sysctl.conf 에 있는 이 vm.overcommit_memory 값은 이를 어떻게 제어할 것인지에 대한 커널 설정값입니다.

  • 0 – 적당히 휴리스틱하게 처리
  • 1 – 항상 허용
  • 2 – vm.overcommit_memory_ratio 에 적용된 범위까지만 허용

또는 다음과 같이 하시면 됩니다.

sysctl vm.overcommit_memory=1

자세한 설정에 대해서는 http://www.novell.com/support/kb/doc.php?id=7002775 다음 페이지를 보시면 됩니다. 즉 이 값이 0이거나 2면 BGSAVE시에 메모리를 최대 2배까지 먹으면 실패할 수도 있으니, 이를 1로 설정하라는 뜻입니다. 그런데, 문제는 이게 1로 셋팅하면 메모리를 많이 사용할 때, 스왑이 생겨서 성능에 큰 문제가 발생할 수 있습니다.  결국 서버 개발자는 어느 정도 커널 셋팅 부터, 커널을 이해하지 않고서는 여러가지 문제를 경험하게 된다는 것이 오늘의 핵심입니다. 항상 경고도 조심해서 보면 재미난게 많다는 것도.

 

다음 글들도 읽어보시면 꽤 도움이 되실껍니다.