[Redis] Copy On Write

Copy On Write

레디스 서버 메모리 사용량은 실 데이터 크기 + 관리 메모리 overhead + Copy-on-Write로 인한 추가메모리를 고려해서 산출해야한다.

리눅스를 기준으로 이야기를 해보자면 부모 프로세스에서 자식 프로세스를 fork할 경우 같은 메모리 공간을 공유하게 된다. 그런데 이 경우에서 부모 프로세스가 데이터의 변경을 시도하면 같은 메모리 공간을 공유할 수 없게 된다. 이 때 부모프로세스는 해당 페이지를 복사한 다음 변경을 수행하고 이를 Copy On Write라 한다.

COW 발생 시점

save 파라미터

redis.conf에 디폴트로 save 파라미터가 활성화 되어있다. save를 통해 RDB 파일을 새로 쓸 때 자식 프로세스가 생성되어 작업이 진행되는데 이 때 COW가 발생한다. 예를들어 물리적 메모리가 32GB인 시스템에서 레디스 서버 인스턴스가 30GB를 사용하던 중에 COW가 발생해서 3GB의 추가 메모리가 필요로 해진다면 real 메모리가 부족해서 Swap이 발생해 성능 저하가 일어난다.

BGSAVE 명령

BGSAVE도 동일하게 자식 프로세스가 생성되어 작업을 하기 때문에 COW가 발생한다. SAVE 명령은 레디스 프로세스가 직접 수행하기 때문에 COW가 발생하지 않는다.

Replication

자신이 Master이고 Slave가 연결되면 full resync가 발생하여 RDB 파일을 생성하기 때문에 COW가 발생한다. 이는 Replication시 파일을 디스크에 쓰지 않고 소켓으로 넘기는 옵션을 사용해도 동일하게 발생한다. Target이 Disk인지 Socket인지에 대한 차이만 있지 fork후 RDB데이터를 만드는건 동일하기 때문이다.

auto-aof-rewrite-percentage 파라미터

redis.conf에 auto-aof-rewrite-percentage 100이라는 파라미터가 존재하는데 이 파라미터는 appendonly 파일이 100% 커지면 rewrite하는 옵션이다. Rewrite는 AOF 자식 프로세스가 fork되어 실행되는데 이 때 COW가 발생한다.

BGREWRITEAOF 명령

BGREWRITEAOF 명령 또한 자식 프로세스가 생성되어 rewrite를 수행하기 때문에 COW가 발생한다.

Cow Avoid

  1. RDB save 파라미터 : 사용하지말고 AOF를 everysec로 설정하자
  2. RDB BGSAVE 명령 : 꼭 필요한 경우에만 서버 부하가 적을때 사용하자
  3. RDB Replication : 새 슬레이브 연결은 부하가 적은 시점에 연결하되 기존 슬레이브에 문제가 생겨 full resync가 일어나는것은 어쩔수 없다
  4. AOF auto-aof-rewrite-percentage 파라미터 : 사용하지말고 0으로 설정해 disable하자. 그리고 서버 부하가 적을 때 BGREWRITEAOF를 수행하자
  5. AOF BGREWRITEAOF 명령 : 서버 부하가 적을 때 사용하자.
Author: Song Hayoung
Link: https://songhayoung.github.io/2020/07/19/Redis/copy-on-write/
Copyright Notice: All articles in this blog are licensed under CC BY-NC-SA 4.0 unless stating additionally.