Data Backup
레디스는 모든 데이터를 메모리에 저장하므로, 예기치 않은 서버 장애나 재시작 시 데이터가 유실될 수 있어, 영속성을 확보하기 위한 데이터 백업 메커니즘이 필요하다.
RDB(Redis DataBase)
섹션 제목: “RDB(Redis DataBase)”RDB는 특정 시점의 메모리 상태 전체를 하나의 바이너리 파일(dump.rdb)로 저장하는 스냅샷 방식이다.
스냅샷 명령어: SAVE vs BGSAVE
섹션 제목: “스냅샷 명령어: SAVE vs BGSAVE”스냅샷을 만드는 방법은 두 가지로, 메인 스레드 블로킹 여부가 핵심 차이다.
| 명령어 | 실행 방식 | 메인 스레드 | 운영 권장 |
|---|---|---|---|
SAVE | 메인 스레드가 직접 디스크 기록 | 동기 수행, 블로킹 | 사용 지양 |
BGSAVE | fork()로 자식 프로세스 생성 후 자식이 기록 | 비블로킹, 요청 계속 처리 | 표준 방식, 자동 트리거 동일 |
SAVE(Save): 메인 스레드가 모든 키를 순회하며 직접 디스크에 쓰는 동기 명령으로, 데이터셋이 큰 경우 수 초~수십 초 동안 모든 클라이언트 요청 블로킹BGSAVE(BackGround Save): 메인 프로세스를fork()해 자식 프로세스가 디스크 기록을 담당, 메인 스레드는 그동안에도 정상적으로 클라이언트 요청 처리
운영 환경에서는 사실상 모든 스냅샷이 BGSAVE 또는 그와 동일한 메커니즘으로 동작한다.
- 자동 스냅샷:
redis.conf의save옵션에 설정된 조건이 충족되면 내부적으로BGSAVE호출 - 수동 스냅샷: 관리자가 CLI로
BGSAVE직접 실행 - 복제 동기화: 레플리카 노드가 마스터와 최초 동기화 시작 시 마스터가
BGSAVE로 RDB 생성 후 전송
BGSAVE 동작 원리: fork() + Copy-on-Write
섹션 제목: “BGSAVE 동작 원리: fork() + Copy-on-Write”BGSAVE는 OS의 fork()와 Copy-on-Write 메커니즘을 활용해 메인 스레드를 블로킹하지 않는다.
- 메인 프로세스가
fork()시스템콜로 자식 프로세스를 생성 → 자식은 부모와 동일한 페이지 테이블을 공유하고, 양쪽의 모든 페이지는 읽기 전용으로 마킹됨(물리 페이지는 복사되지 않음) - 자식 프로세스는
fork()시점의 데이터 스냅샷을 디스크에 쓰는 동안, 부모는 클라이언트 요청을 블로킹 없이 계속 처리 - 부모가 공유 페이지에 쓰기를 시도하면 MMU가 읽기 전용 위반을 감지해 페이지 폴트 발생 → 커널이 새 물리 페이지를 할당해 원본을 복사한 뒤 부모의 페이지 테이블만 새 페이지를 가리키도록 갱신
- 부모는 그제서야 쓰기 성공(Copy-on-Write)
- 자식의 페이지 테이블은 여전히 원본을 가리키므로
fork()시점 스냅샷이 그대로 유지
- 자식이 디스크 기록을 마치면 종료, 새 RDB 파일이 기존 파일을 원자적으로 교체
BGSAVE를 사용할 때, 다음과 같은 주의점이 있다.
- 메모리 사용량 폭증 가능성: 쓰기 트래픽이 많으면 CoW로 복사되는 페이지가 늘어나 메모리 사용량이 순간적으로 최대 2배까지 증가 →
vm.overcommit_memory=1권장 fork()자체의 블로킹: 거대한 메모리 공간(수십 GB)을 가진 프로세스에서는 페이지 테이블 복사 비용으로fork()호출 자체가 수십~수백 ms 블로킹
RDB 장단점
섹션 제목: “RDB 장단점”- 장점
- 데이터 전체가 하나의 파일에 담겨있어 파일 크기가 작고 관리 용이
- 서버 재시작 시 RDB 파일을 읽는 속도가 AOF보다 빨라 대용량 데이터 복원에 유리
- 단점
- 스냅샷은 특정 시점에만 생성되므로, 마지막 스냅샷 이후 발생한 데이터 변경분은 장애 시 유실 가능
- 큰 데이터셋에서
fork()비용으로 수십~수백 ms 블로킹 가능
AOF(Append Only File)
섹션 제목: “AOF(Append Only File)”AOF는 레디스 서버에서 실행된 모든 쓰기(write) 명령을 로그 파일에 순차적으로 기록하는 방식이다.
-
동작 원리
- 클라이언트로부터 쓰기 요청이 들어올 때마다 해당 명령어를 AOF 파일의 끝에 추가
- 정확히는
write()시스템콜로 커널 페이지 캐시에 먼저 기록되고, 실제 디스크 동기화(fsync())는appendfsync정책에 따라 별도 타이밍에 수행 - 서버 재시작 시, 이 파일에 기록된 모든 명령어를 처음부터 순서대로 재실행하여 데이터 복원
-
fsync정책:appendfsync옵션으로 조절하며, 이는 데이터 내구성과 성능 간의 트레이드오프를 결정always: 모든 쓰기 명령마다fsync수행(가장 안전하지만 성능 저하 심함)everysec(기본값): 1초에 한 번씩 백그라운드 스레드에서fsync수행. 장애 시 최대 1초 분량만 유실되고 메인 스레드는 블로킹되지 않아 대부분의 프로덕션에서 기본으로 채택no:fsync를 OS 페이지 캐시 플러시에 맡김(가장 빠르지만 유실 위험 최대)
-
AOF 재구성(Rewrite)
- AOF 파일은 시간이 지남에 따라 계속 커지므로,
BGREWRITEAOF명령어나auto-aof-rewrite-percentage조건으로 파일 크기를 최적화 - 해당 과정은 현재 메모리 상태를 기반으로 가장 짧은 명령어 조합을 만들어 새로운 AOF 파일을 생성(기존 로그를 읽지 않음)
- 동시 쓰기 누락 방지 흐름
- 부모가
fork()로 자식 생성 → 자식은 현재 메모리 스냅샷 기반으로 새 AOF 파일을 작성 - 자식이 새 파일을 쓰는 동안, 부모는 기존 AOF 파일에 계속 기록하면서 “AOF rewrite buffer”에도 같은 명령을 별도 누적
- 자식이 새 파일 작성을 완료하면, 부모는 rewrite buffer에 쌓인 명령을 새 파일 끝에 이어 붙여 일관성 확보
- 기존 AOF 파일을 새 파일로 원자적 교체(
rename)
- 부모가
- Redis 7의 MP-AOF(Multi-Part AOF): 단일 파일 대신
base + incremental + manifest다중 파일로 운영- base는 rewrite 시점의 RDB 바이너리로 저장되어 rewrite 재시작·디스크 사용량·내구성 모두 개선
- AOF 파일은 시간이 지남에 따라 계속 커지므로,
-
장점
fsync정책에 따라 데이터 유실을 최소화할 수 있어 RDB보다 높은 내구성 제공
-
단점
- 동일한 데이터라도 RDB 파일보다 파일 크기가 더 클 수 있음
- 서버 재시작 시 모든 명령어를 재실행해야 하므로 RDB보다 복원 속도가 느릴 수 있음
데이터 복원 과정
섹션 제목: “데이터 복원 과정”레디스 서버는 오직 재시작될 때만 데이터를 복원한다.
- 서버가 시작되면 먼저 AOF 파일(
appendonly.aof)의 존재 여부를 확인 - AOF 파일이 존재하면, 해당 파일을 로드하여 데이터를 복원(AOF 파일이 RDB 파일보다 우선)
- AOF 파일이 없고 RDB 파일(
dump.rdb)만 존재하면, RDB 파일을 로드
권장 구성
섹션 제목: “권장 구성”데이터의 안정성을 극대화하기 위해 두 가지 방식을 모두 활성화하는 것이 강력하게 권장된다.
- 평상시 내구성: AOF가 데이터의 실시간 변경 사항을 기록하여 데이터 유실 최소화
- 주기적 백업 및 빠른 복원: RDB는 주기적으로 전체 데이터의 스냅샷을 만들어두어, 재해 발생 시 특정 시점으로의 빠른 복구 지원
- 시너지 효과: AOF 재구성 시, 레디스는 가장 최근의 RDB 스냅샷을 활용하여 재구성 속도를 높이고 효율성 극대화