레디스가 메모리에만 데이터를 저장한다면, 레디스가 다운되어 재실행될 때 데이터를 잃어 버릴 것이다. 다행히도 레디스는 데이터를 디스크에도 저장하여 영속성(persistence) 을 보장한다. 레디스가 영속성 보장을 위해 제공하는 두가지 방법에 대하여 알아보자
RDB는 특정 시점의 레디스 데이터(스냅샷)를 나타내는 여러개의 데이터 파일을 생성하는 방식이다.
AOF 는 각 쓰기 명령을 로그로 간주하고 log 파일에 저장한다. 해당 로그 파일은 append-only
모드로 쓰여진다. 레디스가 다시 시작되면 AOF 로그에 저장된 명령을 재실행하여 기존 데이터를 복구한다.
RDB 또는 AOF를 통해 보관된 데이터를 클라우드 서비스와 같은 다른 위치에 백업할 수 있다. 이 데이터를 복사하여 지정된 디렉터리에 넣은다음 레디스를 다시 시작하면 레디스가 자동으로 데이터를 다시 저장한다.
RDB와 AOF 을 동시에 사용하는 경우 레디스가 다시 시작될 때 AOF 데이터가 더 완전하다고 판단하여 AOF 를 사용해 데이터를 다시 저장한다.
BGSAVE
라는 옵션을 통해 해당 방식을 적용할 수 있다. 단, 이때 fork 를 통해 자식프로세스를 생성하는 과정에서 메모리 사용량이 2배가 되므로 주의해야 한다. fsync
명령을 수행한다.fsync
주기 에 따라 쓰기명령 qps 에 영향을 줄 수 있다.always
: 매 쓰기 명령이 실행될 때마다 fsync
를 실행한다. 성능이 매우 저하된다.everysec
: 1초 동안의 데이터를 모아서 별도의 쓰레드가 fsync
를 실행한다. 일반적으로 성능에 거의 영향을 주지 않는다.no
: 레디스가 fsync
를 실행하지 않는다. OS가 주기적(30초)으로 fsync
를 실행해서 데이터를 디스크에 저장한다. 성능은 좋을 수 있지만 데이터 유실의 가능성이 있다.rewrite
를 실행하여 현재 메모리 정보를 로그파일로 재기록하는데, 이를 통해 로그파일의 사이즈를 줄일 수 있다.rewrite
는 fork 를 통해 자식 프로세스에서 수행한다.flushall
명령으로 데이터를 날려버렸다면 AOF 파일에서 flushall
만을 제거하여 복구할 수 있다.rewrite
가 실행된적이 있다면 복구 불가..만약, 레디스를 캐시 용도가 아닌 persistnce repository 용도로 사용할꺼라면 AOF, RDB 방식을 꼼꼼하게 따져보고 잘 적용하는것이 중요하겠다!
참고
https://sangchul.kr/576?category=961091
https://github.com/doocs/advanced-java/blob/main/docs/high-concurrency/redis-persistence.md