RPO、RTO、そして3-2-1
한국어 원문으로 표시합니다.
한 줄 요약
백업 설계의 모든 선택은 RPO(얼마나 잃어도 되는가) 와 RTO(얼마나 빨리 돌아와야 하는가) 두 숫자에서 나온다.
왜 이게 필요했나
"백업 주기를 어떻게 잡을까요?" 라는 질문에는 답이 없다. "데이터를 몇 분까지 잃어도 되나요?" 로 바꾸면 답이 나온다.
- RPO(Recovery Point Objective) — 장애 시점에서 얼마나 과거의 데이터까지 되살릴 수 있는가. 곧 허용 가능한 데이터 손실량이다. RPO 가 1시간이면 백업 주기도 1시간 이하여야 한다.
- RTO(Recovery Time Objective) — 장애부터 서비스 재개까지 허용되는 시간. 이건 백업 방식뿐 아니라 복구 절차 전체가 결정한다.
두 숫자는 비용과 직결된다. RPO 를 분 단위로 줄이려면 지속적 아카이빙이 필요하고, RTO 를 분 단위로 줄이려면 대기 시스템이 필요하다. 그래서 이 숫자는 기술이 아니라 사업이 정한다. 엔지니어의 일은 그 숫자를 받아 실현 가능한 설계로 옮기는 것이다.
어떻게 동작하나
세 가지 방식
| 방식 | 무엇을 담나 | 백업 시간 | 복구 시간 | 저장 공간 |
|---|---|---|---|---|
| 전체(Full) | 전부 | 김 | 짧음(하나만 풀면 됨) | 큼 |
| 증분(Incremental) | 마지막 백업 이후 변경분 | 짧음 | 김(전체 + 모든 증분 순서대로) | 작음 |
| 차등(Differential) | 마지막 전체 이후 변경분 | 중간 | 중간(전체 + 마지막 차등) | 중간 |
증분과 차등의 차이가 헷갈리기 쉬운데, 기준점이 다르다. 증분은 "직전 백업" 기준, 차등은 "마지막 전체" 기준이다. 그래서 차등은 날이 갈수록 커지지만 복구할 때 두 개만 있으면 된다.
실무에서 흔한 조합은 주 1회 전체 + 매일 증분 이다. 다만 이 조합의 위험은 증분 하나가 손상되면 그 이후 전부가 무효라는 점이다. 그래서 세대 보존 정책과 정기 검증이 짝으로 따라온다.
3-2-1 규칙과 현대적 보완
고전적인 규칙: 사본 3개, 서로 다른 매체 2종, 그중 1개는 오프사이트.
여기에 요즘은 두 가지가 더 붙는다.
- 1개는 오프라인이거나 변경 불가(immutable) — 랜섬웨어 대응. 백업 서버가 운영망에서 접근 가능하면 백업도 함께 암호화된다.
- 0 오류 — 정기적으로 복구를 검증해 오류가 0 임을 확인한다.
일관성 — 백업 도중 바뀌는 데이터
파일을 복사하는 동안 애플리케이션이 그 파일을 쓰고 있으면, 백업은 어느 시점의 상태도 아닌 잡탕이 된다. 데이터베이스에서 특히 치명적이다.
해법은 세 층위다.
- 애플리케이션 수준 덤프 —
pg_dump -Fc,mysqldump --single-transaction. 가장 확실하고 이식성이 좋다. - 파일시스템 스냅샷 — LVM/Btrfs/ZFS. 시점을 고정한 뒤 그것을 백업한다. 단 블록 수준 시점 고정일 뿐 애플리케이션이 메모리에 들고 있던 데이터는 반영되지 않는다. 그리고 스냅샷 볼륨이 가득 차면 스냅샷이 무효화되므로 크기를 넉넉히 잡아야 한다.
- 지속적 아카이빙 — WAL/바이너리 로그를 계속 아카이브해 임의 시점 복구. RPO 를 분 단위로 줄여야 할 때.
복구 훈련이 실제로 드러내는 것들
백업 전략에서 검증되지 않은 부분은 언제나 복구 쪽이다. 정기적으로 한 번씩 실제로 되살려 보면 대개 아래 중 몇 가지가 나온다.
복구할 곳이 없다. 백업은 있는데 그것을 풀어 놓을 디스크와 서버가 없다. 장애 상황에서 그 자원을 구하는 데 걸리는 시간이 곧 RTO 에 더해진다. 실제로 복구 시간을 재려면 빈 서버에서 시작해야 한다.
필요한 것이 백업에 없다. 데이터베이스는 받았는데 업로드 파일이 없거나, 설정 파일이 없거나, 인증서와 열쇠가 없다. 목록을 만들 때 "데이터" 만 생각하고 서비스를 다시 띄우는 데 필요한 것 전부를 세지 않아서 생긴다.
열쇠가 백업 안에 있다. 암호화한 백업의 복호화 열쇠를 그 백업과 같은 곳에만 두면 아무 소용이 없다. 반대로 열쇠를 아무도 모르는 곳에 두면 복구가 안 된다. 열쇠는 백업과 다른 곳에, 그러나 두 사람 이상이 닿을 수 있는 곳에 둔다.
순서를 모른다. 데이터베이스를 먼저 올려야 하는지, 캐시를 비워야 하는지, 큐에 남은 메시지를 어떻게 할지가 문서에 없다. 그래서 복구는 되는데 서비스가 정상으로 돌아오지 않는다.
백업이 조용히 멈춰 있었다. 성공 알림만 보내면 아무것도 안 오는 상태가 정상처럼 보인다. 최근 백업의 나이를 지표로 재고 그것에 경보를 건다. "24시간 안에 성공한 백업이 없으면 알린다" 가 "실패하면 알린다" 보다 강하다.
받은 것이 읽히는지 본 적이 없다. 파일 크기만 맞으면 성공으로 치는 경우가 많다. 최소한 압축을 풀어 보고, 데이터베이스라면 실제로 붙어 한 줄 조회해 본다. 복구를 시험하지 않은 백업은 백업이 아니라 파일이다.
현장에서 만나는 모습
백업이 조용히 망가지는 다섯 가지 방식을 기억해 두면 좋다.
- 대상에서 빠져 있다 — 새 볼륨을 추가했는데 백업 스크립트에 넣지 않았다.
- 성공 로그만 보고 실패를 못 본다 — cron 은 기본적으로 조용하다. 종료 코드를 확인하고 실패를 알리는 장치가 필요하다.
- 랜섬웨어가 백업까지 복제된다 — 최신 백업만 유지하는 구성은 이 상황에서 무력하다.
- 복원 대상 환경이 다르다 — UID/GID 매핑, SELinux 컨텍스트, 커널 버전이 다르면 복원은 되는데 서비스가 안 뜬다.
- 백업이 운영 성능을 해쳐 백업 창이 줄어든다 — 그러다 주기를 늘리고 어느 순간 RPO 를 못 지킨다.
2번에 대한 최소 방어선은 이것이다.
#!/usr/bin/env bash
set -euo pipefail
trap 'echo "backup FAILED at line $LINENO" >&2; exit 1' ERR
rsync -aHAX --numeric-ids --delete /srv/data/ /backup/prod/data/
echo "backup OK $(date -Is)"
그리고 성공 시각을 파일에 기록해 "최근 성공이 24시간 이내인가"를 감시하는 편이 로그를 읽는 것보다 훨씬 낫다.
다음 확인에서 볼 것
이어지는 퀴즈에서는 RPO·RTO, 전체·증분·차등, 오프사이트 사본을 어떤 조건에서 선택하는지 확인한다. 그 기준을 통과한 뒤 다음 모듈부터 tar 전체·증분 백업, rsync 세대 보존, 검증 스크립트와 시간 측정 복구 리허설로 이어진다.