지속성
Redis는 인메모리 데이터베이스입니다. 만약 메모리 내 데이터를 디스크에 저장하지 않으면, 서버가 종료될 때 저장된 모든 상태가 사라집니다. 따라서 Redis는 두 가지 지속성 전략을 제공합니다.
RDB(Redis DataBase) 지속성
RDB 파일은 특정 시점의 서버 메모리에 있는 데이터셋 스냅샷입니다. 이 파일을 사용하여 서버가 시작될 때 데이터를 복원할 수 있습니다. 원리는 데이터베이스를 비운 후 스냅샷 파일을 메모리에 직접 읽어들이는 것입니다.
지속성 흐름
메인 프로세스가 자식 프로세스를 포크하여 백그라운드에서 지속성을 수행하므로, 메인 프로세스는 IO 작업을 전혀 수행하지 않습니다. 자식 프로세스와 메인 프로세스는 메모리를 공유합니다. 자식 프로세스는 먼저 데이터를 임시 파일에 쓰고, 지속성 과정이 모두 끝나면 이 임시 파일로 이전에 저장된 파일을 교체합니다.
활성화 방법
RDB 지속성을 활성화하는 방법은 두 가지입니다.
- 설정 파일에서 자동 RDB 지속성 조건 구성
- 수동으로 RDB 지속성 명령 실행
수동 실행
다음 두 가지 명령이 있습니다.
# 메인 프로세스를 차단하고, RDB 파일 생성이 완료될 때까지 기다린 후에야 다른 명령 처리 가능
save
# 위 흐름도에서 자식 프로세스를 포크하여 백그라운드에서 지속성을 수행하는 명령
bgsave
설정 파일
설정된 규칙 중 하나라도 충족되면 bgsave 지속성 작업이 한 번 실행됩니다.
################################ SNAPSHOTTING ################################
# 스냅샷: 지속성 수행 시 사용됩니다.
# 지정된 시간 내에 특정 횟수만큼 수정이 발생하면 .rdb 또는 .aof 파일이 생성됩니다.
# Redis는 인메모리 데이터베이스이므로, 지속성 없이는 데이터가 유지되지 않습니다.
# 지속성 규칙
# 3600초 내에 최소 1개의 키가 수정되면 지속성 작업 수행
save 3600 1
# 300초 내에 최소 100개의 키가 수정되면 지속성 작업 수행
save 300 100
# 60초 내에 최소 10000개의 키가 수정되면 지속성 작업 수행
save 60 10000
# 지속성 오류 발생 시에도 작업을 계속할지 여부
stop-writes-on-bgsave-error yes
# RDB 파일 압축 여부 (CPU 자원 소모)
# 하드 디스크는 비용이 적게 듭니다.
rdbcompression no
# RDB 파일 체크섬 검사 여부
rdbchecksum yes
# 지속성으로 생성되는 파일 이름
dbfilename dump.rdb
rdb-del-sync-files no
# 저장 디렉토리, 현재 디렉토리
dir ./
요약
RDB의 장점
- 효율성 높음
- 데이터 복구 속도 빠름
- RDB 파일을 분석 가능
RDB의 단점
- 특수 상황에서 지속성 수행 중 서버 메모리가 두 배로 증가할 수 있음
- 데이터 무결성이 낮음
대규모 데이터 복구가 필요하고 데이터 복구의 완전성에 민감하지 않다면, RDB 방식이 AOF 방식보다 더 효율적입니다.
AOF(Append Only File) 파일
이 전략은 로그 형태로 각 쓰기 작업을 기록합니다. Redis 서비스가 실행한 모든 쓰기 명령을 aof 파일에 추가합니다. Redis가 시작될 때 이 파일을 읽은 후 데이터베이스를 비우고, 로그 파일 내용에 따라 쓰기 명령을 처음부터 끝까지 한 번 실행하여 데이터를 복원합니다.
지속성 흐름

활성화 방법
AOF는 설정 파일에서 전략만 구성하면 됩니다.
############################## APPEND ONLY MODE ###############################
# 지속성 파일 aof 설정
# 기본적으로 aof는 비활성화되며, rdb 지속성이 기본입니다. 대부분의 경우 rdb로 충분합니다.
appendonly yes
# 지속성 파일 이름
appendfilename "appendonly.aof"
# appendfsync always # 매 수정 시 동기화
appendfsync everysec # 매 1초마다 동기화
# appendfsync no # 동기화 안 함, 운영체제가 자체적으로 동기화
aof 파일이 악의적으로 변조되면 Redis가 시작되지 않을 수 있습니다. 이 경우 Redis에서 제공하는
redis-check-aof도구를 사용할 수 있습니다.
AOF 다시 쓰기 (Rewrite)
쓰기 명령이 계속 누적되면 aof 파일이 계속 커집니다. 이를 방지하기 위해 특정 조건에 도달하면 메인 프로세스가 자식 프로세스를 생성하여 aof 파일을 다시 씁니다.
설정 예시
# 다시 쓰기 전:
# incrby view 10
# incrby view 20
# 다시 쓰기 후:
# incrby view 30
# bgaofrewrite와 메인 프로세스가 동시에 aof 파일을 쓸 때 메인 프로세스의 처리 방식
# no:
# 메인 프로세스는 명령이 aof에 성공적으로 기록될 때까지 차단되어 대기
# yes:
# appendfsync를 no로 설정한 것과 동일
# 메인 프로세스는 쓰기 명령을 운영체제 캐시에 기록하고, 운영체제가 데이터를 디스크에 기록하도록 함
no-appendfsync-on-rewrite no
# 원래 aof 파일 크기의 100%일 때 다시 쓰기 실행
auto-aof-rewrite-percentage 100
# aof 파일이 64MB에 도달하면 다시 쓰기 실행
auto-aof-rewrite-min-size 64mb
자식 프로세스는 현재 서버의 모든 키-값 쌍을 읽어 각 키-값 쌍을 Redis 프로토콜에 따라 임시 파일에 저장합니다.
왜 자식 스레드가 아니라 자식 프로세스인가요?
자식 프로세스는 서버 프로세스의 데이터 복사본을 가지므로, 자식 스레드 대신 자식 프로세스를 사용하면 잠금을 사용하여 데이터 안전성을 보장할 필요가 없습니다.
이 기간 동안 메인 프로세스가 새로운 쓰기 명령을 받으면 어떻게 되나요?
AOF 다시 쓰기가 시작될 때 Redis 서버는 AOF 다시 쓰기 버퍼를 설정합니다. 자식 프로세스가 AOF를 다시 쓰는 동안 메인 프로세스가 받는 각 명령은 AOF 버퍼와 AOF 다시 쓰기 버퍼에 모두 추가됩니다. 다시 쓰기가 완료되면 자식 프로세스가 메인 프로세스에 신호를 보냅니다. 메인 프로세스는 이 신호를 받은 후 차단되어 AOF 다시 쓰기 버퍼의 내용을 새로 쓰여진 AOF 파일에 추가합니다. 이렇게 하면 AOF 파일이 최신 데이터베이스 상태를 반영하게 됩니다 (차단 처리로 인해 이 시간 동안 새 클라이언트 명령은 실행되지 않으므로 AOF 버퍼와 AOF 다시 쓰기 버퍼의 내용은 모두 최신 상태입니다). 추가가 완료되면 원자적으로 이전 AOF 파일을 덮어쓰며 AOF 다시 쓰기가 완료됩니다.
AOF 다시 쓰기 중에 메인 프로세스가 받은 명령을 AOF 버퍼와 AOF 다시 쓰기 버퍼에 모두 쓰는 이유는 무엇인가요? 두 버퍼에 같은 데이터가 저장되는데?
첫째, AOF 버퍼에 쓰는 것은 기존 AOF 파일의 정확성을 계속 유지하기 위함입니다. 만약 AOF 다시 쓰기 자식 프로세스가 실패하면 이 기간 동안의 데이터가 손실되기 때문입니다. 이를 이해하면, AOF 다시 쓰기 버퍼에만 쓰면 데이터 손실 문제가 발생할 수 있다는 것을 알 수 있습니다 (물론 해결할 수 있지만, 자식 프로세스 실패 시 AOF 다시 쓰기 버퍼 내용을 AOF 버퍼에 추가하면 되지만 필요하지 않습니다). 둘째, AOF 버퍼에만 쓰고 AOF 다시 쓰기 버퍼에는 쓰지 않으면, AOF 다시 쓰기 조건이 충족되어 메인 프로세스가 자식 프로세스를 생성하여 AOF 다시 쓰기 작업을 수행할 때 문제가 발생합니다. 자식 프로세스 생성은 차단 작업이므로 클라이언트 명령이 실행되지 않습니다. 메인 프로세스가 자식 프로세스를 생성한 후에는 클라이언트 요청을 수신하고 명령을 처리한 후 AOF 버퍼에 저장합니다. AOF 다시 쓰기 중에 AOF 버퍼는 디스크 동기화 정책에 따라 디스크에 기록되어 비워질 수 있습니다. AOF 다시 쓰기가 완료된 후, AOF 버퍼의 데이터는 새로 쓰여진 AOF 파일의 데이터와 연결되지 않을 수 있습니다. 즉, 자식 프로세스 생성 이후부터 마지막 AOF 디스크 동기화 전까지의 데이터가 손실됩니다.
요약
AOF의 장점
- 데이터 무결성이 더 좋음
AOF의 단점
- 파일 크기가 RDB보다 훨씬 큼
- 복구 속도가 RDB보다 훨씬 느림
- 생성 효율이 RDB보다 낮음
최종 요약
Redis는 RDB와 AOF라는 두 가지 지속성 방식을 제공합니다.
- RDB 지속성 방식은 지정된 시간 간격으로 특정 시점의 서버 데이터를 스냅샷으로 저장합니다.
- AOF 지속성 방식은 클라이언트가 서버에 수행한 모든 쓰기 작업을 기록합니다.
- AOF의 업데이트 빈도는 일반적으로 RDB보다 높아 데이터 무결성이 더 좋으며, 데이터 복구 시 AOF 파일의 우선순위가 더 높습니다.
- AOF 파일의 데이터 복구 속도는 느리지만, AOF 다시 쓰기 기능이 있지만 파일 크기는 여전히 RDB 파일보다 큽니다.
- RDB 파일은 데이터 복구 속도가 더 빠르고 파일 크기가 작습니다.
Redis를 캐시로만 사용하고 서버 실행 중에만 데이터가 필요하다면, 어떤 지속성도 사용하지 않아도 됩니다.