Redis) 이것이 레디스다 14 - 메모리 설정

fork 함수는 부모의 프로세스와 동일한 크기의 메모리를 사용하는 프로세스를 생성한다.
부모 프로세스 만큼의 메모리가 남아있지 않으면 fork 함수가 실패한다.
레디스의 AOF이나 스냅샷을 위해 호출한 fork 함수가 실패한 이후 레디스의 모든 쓰기 연산은 실패를 응답한다.

레디스의 fork 함수에 의해 생성된 자식 프로세스는 쓰기 연산이 발생하지 않으면 부모 프로세스의 메모리를 공유하기 때문에 복사할 필요가 없다. 현재 부모 프로세스의 메모리를 읽어서 디스크에 저장하기 때문이다.
하지만 그럼에도 할당된 메모리의 크기만큼 추가 메모리가 존재하지 않으면 fork 함수가 실패한다.
이를 방지하기 위해서 /etc/sysctl.conf 파일에 vm.overcommit_memory=1 옵션을 추가해야한다.


  • vm.overcomit_memory 설정
    • 0: (기본값) 메모리 할당 요청 malloc 함수의 요청이 들어오면 요청된 크기만큼의 물리 메모리가 있을 때에만 메모리를 할당한다.
    • 1: malloc 함수의 요청이 들어오면 남은 물리 메모리가 없어도 입력된 크기 만큼 스왑 메모리가 있을 때 성공을 응답한다.
    • 2: 사용 중인 메모리 크기가 스왑공간 크기 + vm.overcommit_ratio * 물리 메모리 크기 이내일 때 메모리를 할당한다.

vm.overcommit_memory=1 설정을 한 상태에서
자식 프로세스는 Copy On Write에 의해 부모 프로세스의 메모리 페이지 테이블을 복사하여 스왑영역에 저장하게 된다.
이때 쓰기 연산이 들어오면 부모 프로세스가 현재 프로세스의 메모리 만큼의 메모리 할당을 요청하게 되고 운영체제는 부족한 메모리는 스왑영역을 사용하게 된다.
스왑 메모리를 사용하게 되면 응답시간이 물리 메모리를 사용할 때에 비해 길어지게된다.

그렇기 때문에 운영하는 서비스가 응답시간에 민감하다면 maxmemory를 (운영체제나 기타 프로세스를 제외한) 사용 가능한 메모리의 50% 이하로 설정하는 편이 안전하다.

Share