-
[Redis] 백업을 통한 데이터 영속화DataBase/NoSQL 2023. 3. 12. 22:55
Redis는 인메모리 저장 방식으로 리부팅시 데이터가 휘발된다. 따라서 기존 데이터를 영속화하여 복구, 유지시키기 위해서는 디스크에 데이터 백업해주는 과정이 필요하다. 백업 방식에는 1) RDB snapshot, 2) AOF 2가지가 있다.
RDB snapshot은
특정 시점을 스냅샷으로 남겨 데이터를 저장하는 방식을 말한다. 여기서 "RDB"는 관계형 데이터베이스가 아니라 Redis DataBase를 의미한다. redis.conf 파일에서 스냅샷 저장에 대한 주기 설정을 할 수 있는데, save 60 10으로 설정하면 60초마다 10개 이상의 데이터 변경이 있을 때 데이터를 저장하겠다는 의미이다.
아래는 redis.conf에 기본으로 설정되어있는 # save 3600 1 300 100 60 10000에서 주석을 해제한 모습이다. 이처럼 조건이 여러 개 있을 때는 조건 중 하나라도 만족하면 save시킨다. 즉, 3600초 동안 1개 이상의 데이터가 변경되거나 300초 동안 100개 이상의 데이터가 변경되거나 60초 동안 10000개 이상의 데이터가 변경되면 dump.rdb 파일을 생성하며 디스크에 데이터를 백업한다. 리부팅시에는 dump.rdb 파일이 있으면 읽어서 복구시킨다.
redis-cli에서 bgsave 명령어로 수동으로 스냅샷을 저장할 수도 있다. 단, bgsave 방식은 fork로 생성한 자식 프로세스가 백업하기 때문에 메모리를 save의 두배 가량 사용하므로 주의해야 한다.
AOF는
"Append Only File"의 약자로 모든 쓰기 요청에 대한 로그를 저장하고 리부팅 시 AOF에 기록된 모든 동작을 재수행해서 데이터를 복구시킨다. Redis에 입력/수정/삭제 명령이 실행될 때 마다 appendonly.aof에 기록되며 조회 명령은 기록되지 않는다. 그런데 이렇게 모든 명령을 기록하다보면 파일 사이즈가 계속 커지게 된다.
이에 대한 대책으로 "Rewrite"라는 기능을 쓰면 특정 시점에 데이터 전체를 다시 써서 파일 사이즈를 줄일 수 있다. 예를 들어 같은 KEY에 대해서 SET 명령을 100번 수행했을 때 마지막에 수행된 값을 제외하고는 큰 의미가 없다. 이런 상황에서 Rewrite를 수행하면 99번의 명령은 삭제하고 100번째 명령만 기록한다.또, AOF 파일은 text 파일이므로 수정이 가능하다. 예를 들어 실수로 FLUSHALL 명령으로 메모리에 있는 모든 데이터를 삭제한 경우 Redis를 내리고 appendonly.aof 파일에서 FLUSHALL 명령을 제거한 후 리부팅시키면 삭제 전 데이터 상태로 돌아갈 수 있다.
참고한 사이트에서는 기본으로 AOF를 사용하고 RDB는 옵션으로 쓰기를 추천하고 있다. 각각의 장단점은 다음 표와 같다.
RDB AOF 장점 - 작은 파일 사이즈로 원격지 백업, 버전 관리 등 백업 파일 관리가 용이함
- bgsave를 이용하면 자식 프로세스가 작업하므로 메인 프로세스를 중단하거나 성능에 영향을 주지 않고 백업 가능
- 빠른 복구 가능- 모든 변경사항이 기록되므로 RDB 방식 대비 안정적으로 백업 가능
- 읽기모드이므로 백업 파일이 손상될 위험이 적음
- 실제 수행된 명령어가 저장되어 있으므로 사람이 보고 이해할 수 있고 직접 수정도 가능함단점 - 스냅샷을 저장하는 시점 사이의 데이터 변경사항은 유실 가능
- fork를 이용하는 경우 시간이 오래 걸릴 수 있고 CPU, 메모리 등 자원을 많이 사용함
- 마지막 백업 시 에러 발생 등의 문제가 있어 데이터 무결성이나 정합성이 요구되는 상황에서는 부적절함- RDB 방식 대비 파일 사이즈가 큼
- REB 방식 대비 백업 & 복구 속도가 느림
(백업 성능은 fsync 정책에 따라 조절 가능)아래는 RDB, AOF 방식으로 각각 백업해본 실습과정이다.
⚙️ 실습 환경
Mac OS
Docker 20.10.23
Redis 7.0.81. RDB를 사용한 백업
1) redis.conf SNAPSHOTTING 부분에서 60초 안에 10개 이상의 데이터 변경이 있을 때 백업하도록 "save 60 10" 설정한다.
2) 위 redis.conf를 마운팅하는 옵션(-v)으로 새로운 컨테이너를 실행한다.
$ docker run -v $(pwd)/redis.conf:/redis.conf --name my-redis-rdb redis redis-server /redis.conf
$ docker run -v {로컬 redis.conf가 위치한 경로}:/redis.conf --name {컨테이너 이름} redis redis-server /redis.conf
3) redis에 접속해 key를 두개만 만든다.
$ docker exec -it my-redis-rdb
# redis-cli
127.0.0.1:6379> set a 1
127.0.0.1:6379> set b 22
4) docker를 내린다.
$ docker stop my-redis-rdb
5) 다시 docker를 시작하고 redis에 접속한다. key를 확인한 결과 save 조건을 충족하지 않아 데이터가 저장되지 않은 것을 확인할 수 있다.
$ docker start my-redis-rdb
# redis-cli
127.0.0.1:6379> keys *
6) 이번에는 key를 10개 만든다.
7) docker를 리부팅시키고 redis에 접속해서 key를 확인해보면 save 조건을 충족해서 데이터가 백업된 것을 확인할 수 있다.
2. AOF를 사용한 백업
1) RDB snapshot 백업방식을 사용하지 않도록 redis.conf에서 SNAPSHOTTING 부분을 save ""로 지정하고
2) AOF방식으로 백업하기 위해서 appendonly yes로 변경한다. (default: appendonly no)
3) 위 redis.conf를 마운팅하는 옵션으로 새로운 컨테이너를 실행한다.
$ docker run -v $(pwd)/redis.conf:/redis.conf --name my-redis-aof redis redis-server /redis.conf
4) 생성한 컨테이너에 진입한다.
$ docker exec -it my-redis-aof /bin/sh
5) redis-cli에서 set command로 key-value를 저장한다.
$ redis-cli -p 9993
# set A 123
# set B 1234124
6) appendonlydir 폴더에 들어가보면 아래 세 가지 파일이 존재한다.
- appendonly.aof.1.base.rdb: 마지막 rewrite 시의 스냅샷을 저장
- appendonly.aof.1.incr.aof: 마지막으로 base file이 생성된 이후의 변경사항을 누적하여 저장
- appendonly.aof.mainfeast: 파일들을 관리하기 위한 메타 데이터를 저장
7) 그 중 cat 명령어로 확인 가능한 appendonly.aof.1.incr.aof의 내용을 출력해보면 내가 실행한 command가 전부 저장되어 있다.
# cat appendonly.aof.1.incr.aof
8) 컨테이너가 다운되어도 백업이 되는지 확인하기 위해 컨테이너를 재시작한다.
$ docker stop my-redis-aof
$ docker start my-redis-aof
9) 컨테이너 안에서 appendonlydir이 여전히 존재하고, keys command로 확인해보면 저장한 키들이 모두 살아있다.
참고:
http://redisgate.kr/redis/configuration/persistence.php
※ fast campus의 "백엔드 개발자를 위한 한 번에 끝내는 대용량 데이터 & 트래픽 처리 초격차 패키지"를 수강하고 정리한 글입니다.
'DataBase > NoSQL' 카테고리의 다른 글
[Redis] Sentinel을 이용한 자동 장애조치 (0) 2023.02.19 [Redis] 서비스 고가용성을 위한 Replica (0) 2023.02.19