1. AOF란 무엇인가?
Redis는 데이터를 메모리에 저장하는 인메모리 데이터베이스이기 때문에, 서버가 갑자기 종료되면 모든 데이터가 손실될 위험이 있습니다. 이를 방지하기 위해 Redis는 두 가지 영구 저장 방식을 제공합니다: RDB와 AOF.
RDB는 특정 시점의 데이터베이스 스냅샷을 파일로 저장합니다. 반면, AOF(Append Only File)는 Redis 서버가 수행한 모든 쓰기 명령을 로그 파일에 순차적으로 기록합니다.
예를 들어, 다음과 같은 명령들이 있다고 가정해보겠습니다:
SET str1 "hello"
SADD str2 "world"
LPUSH str3 "a" "b" "c"
- RDB:
str1,str2,str3키-값 쌍을 바이너리 스냅샷 파일에 저장합니다. - AOF:
SET,SADD,LPUSH명령 자체를 텍스트 파일에 저장합니다.
RDB는 일정 시간 간격으로만 백업되기 때문에, 예기치 않은 다운 시 마지막 스냅샷 이후의 모든 변경 사항이 손실될 수 있습니다. 데이터 무결성이 중요한 애플리케이션의 경우 AOF가 더 적합합니다.
2. AOF 설정 방법
Redis 설정 파일 redis.conf에서 APPEND ONLY MODE 섹션의 주요 옵션들을 살펴보겠습니다.
-
appendonly: 기본값은
no이며, Redis는 RDB 방식으로 작동합니다. AOF를 활성화하려면 이 값을yes로 변경합니다. -
appendfilename: AOF 파일의 이름입니다. 기본값은
appendonly.aof입니다. -
appendfsync: 데이터를 디스크에 동기화하는 정책을 결정합니다.
no: 운영체제에 동기화를 맡깁니다. 속도는 빠르지만 안전성이 낮습니다.always: 모든 쓰기 작업마다fsync를 호출합니다. 안전하지만 성능이 매우 떨어집니다.everysec: 1초에 한 번씩fsync를 수행합니다. 1초 분량의 데이터 손실 가능성이 있지만, 성능과 안전성 사이의 균형이 좋아 권장됩니다.
-
no-appendfsync-on-rewrite: AOF 재작성(rewrite) 중에는 많은 디스크 I/O가 발생할 수 있습니다. 이 옵션을
yes로 설정하면 재작성 중fsync를 생략하여 성능 저하를 막을 수 있습니다. 지연 시간에 민감한 애플리케이션에 유용하지만, 운영체제의 기본fsync정책(보통 30초)에 따라 데이터를 잃을 위험이 있습니다. 기본값은no입니다. -
auto-aof-rewrite-percentage: 자동 재작성 조건 중 하나입니다. 현재 AOF 파일 크기가 마지막 재작성 이후 설정된 백분율(
100은 100%)만큼 커지면 재작성이 트리거됩니다. 기본값은100입니다. -
auto-aof-rewrite-min-size: 재작성의 최소 파일 크기를 설정합니다. 이 값을 넘지 않으면 백분율 조건이 충족되더라도 재작성이 시작되지 않습니다. 기본값은
64mb입니다. -
aof-load-truncated: 서버 시작 시 AOF 파일이 손상된 경우의 동작을 결정합니다.
yes로 설정하면 가능한 많은 데이터를 로드하고 로그를 남깁니다.no로 설정하면 로드에 실패하고 수동으로redis-check-aof명령을 사용해 복구해야 합니다. 기본값은yes입니다.
3. AOF 활성화
redis.conf 파일에서 appendonly yes로 설정한 후 Redis 서버를 재시작하면 AOF가 활성화됩니다. AOF 파일은 RDB 파일과 동일한 디렉토리에 저장되며, 이 디렉토리는 dir 설정으로 지정할 수 있습니다.
# redis.conf
dir /var/lib/redis
Redis CLI에서 CONFIG GET dir 명령을 사용해 저장 경로를 확인할 수도 있습니다.
4. AOF 파일을 이용한 복구
Redis 서버가 시작될 때 appendonly가 yes로 설정되어 있으면, 자동으로 AOF 파일을 읽어 데이터를 메모리에 복원합니다. 만약 AOF 파일이 손상된 경우, redis-check-aof --fix 명령을 사용하여 복구를 시도할 수 있습니다.
5. AOF 재작성 (Rewrite)
시간이 지나면서 AOF 파일은 계속해서 커집니다. 파일이 너무 커지면 디스크 공간을 많이 차지하고, 서버 재시작 시 데이터 로딩 시간이 길어집니다. Redis는 이 문제를 해결하기 위해 AOF 재작성 메커니즘을 제공합니다.
재작성은 bgrewriteaof 명령을 수동으로 실행하거나, 설정된 조건(파일 크기 증가율 및 최소 크기)이 충족되면 자동으로 시작됩니다.
예를 들어, 다음과 같은 일련의 명령이 있었다고 가정해봅시다:
SADD animals "dog"
SADD animals "tiger"
SADD animals "panda"
SADD animals "lion"
SADD animals "cat"
재작성을 수행하면, 위의 5개 명령이 다음과 같은 하나의 명령으로 압축됩니다:
SADD animals "dog" "tiger" "panda" "lion" "cat"
중요: AOF 재작성은 기존 AOF 파일을 수정하는 것이 아니라, 현재 메모리 상태를 기반으로 새로운 AOF 파일을 생성하는 방식입니다. 이 과정은 Redis의 메인 프로세스와 별도로 자식 프로세스에서 실행되므로, 서버 성능에 미치는 영향을 최소화합니다.
재작성 중에도 서버는 정상적으로 명령을 처리할 수 있습니다. 하지만 이때 발생하는 새로운 쓰기 명령은 AOF 재작성 버퍼에 임시로 저장됩니다. 자식 프로세스가 재작성을 완료하면 부모 프로세스에 신호를 보내고, 부모 프로세스는 버퍼의 내용을 새로운 AOF 파일에 추가한 후 기존 파일을 교체합니다. 이 설계 덕분에 재작성 중에도 데이터 일관성이 유지됩니다.
6. AOF의 장단점
장점
- 다양한
fsync정책을 제공하며,everysec사용 시 최대 1초의 데이터만 손실됩니다. - 파일 형식이 로그(명령어) 기반이므로, 잘못된 명령(예:
FLUSHALL)을 수동으로 제거하여 복구할 수 있는 유연성이 있습니다. - 손상된 파일은
redis-check-aof도구로 쉽게 복구할 수 있습니다.
단점
- 동일한 데이터에 대해 AOF 파일은 RDB 파일보다 크기가 더 큽니다.
- 고부하 상황에서는 RDB가 AOF보다 더 나은 성능을 보여줍니다.
- RDB는 스냅샷 방식으로 데이터를 저장하기 때문에 더 견고하다고 알려져 있습니다. 또한, AOF 방식에는 몇 가지 알려진 버그가 존재합니다.
RDB vs AOF 선택 가이드
짧은 시간의 데이터 손실을 감수할 수 있다면, RDB가 백업 및 복구 속도 면에서 유리합니다. 데이터 손실을 최소화해야 한다면 AOF를 사용하는 것이 좋습니다. 실제 운영 환경에서는 두 방식을 모두 활성화하여 사용하는 것이 가장 안전합니다. Redis 재시작 시 AOF 파일이 RDB 파일보다 우선적으로 로드되며, AOF가 더 완전한 데이터 세트를 제공할 가능성이 높습니다.
7. Redis 4.0: RDB-AOF 혼합 영구 저장
Redis 4.0부터는 RDB와 AOF의 장점을 결합한 혼합 영구 저장 모드를 지원합니다. 이 모드를 활성화하려면 redis.conf에서 다음 설정을 추가합니다:
aof-use-rdb-preamble yes
혼합 모드에서 재작성이 발생하면, 먼저 메모리의 전체 스냅샷을 RDB 형식으로 AOF 파일의 첫 부분에 기록합니다. 그 후, 재작성 중 발생한 증분 명령을 AOF 형식으로 파일 뒤에 추가합니다. 결과적으로 생성된 AOF 파일의 앞부분은 RDB 스냅샷이고, 뒷부분은 AOF 명령 로그인 구조를 가지게 됩니다.
이 방식은 RDB의 빠른 로딩 속도와 AOF의 데이터 완전성을 모두 제공합니다. 단, Redis 4.0 이전 버전과의 호환성은 보장되지 않는다는 단점이 있습니다.