오늘은 Redis 서버가 재시작될 때 발생하는 데이터가 삭제되는 문제를 다룰려고 한다. 실제로 redis로 조회수 구현 로직을 작성했을 때 조회수이기 때문에 유지가 되어야하는데 서버를 재시작할 때마다 리셋이 되서 조금 당황했던 경험이 있다. 왜 데이터가 삭제되는지, 해결방법에는 어떤 것이 있는지 정리해보겠다.
1. 문제점: 서버 재시작 시 데이터 삭제
Redis는 메모리 기반의 데이터 스토어로서, 기본 설정 상태에서는 서버가 재시작되면 메모리에 저장된 모든 데이터가 삭제된다. 이는 내가 사용했던 Sorted Set뿐만 아니라 모든 자료형의 데이터에 적용되는 문제이다.
2. 해결 방법: Redis 설정 변경을 통한 데이터 영속성 확보
데이터를 디스크가 아닌 메인 메모리에 저장하고 관리하는 "In-memory DB"인 Redis. 이 문제를 해결하기 위한 가장 간단한 방법은 Redis의 데이터 영속성 설정을 활성화하기! 영속성 설정을 활성화 하게 되면 메모리에 저장된 데이터를 디스크에 저장하게 된다. 이렇게 하면, 서버가 종료되거나 재시작되더라도 데이터가 사라지지 않고 보존될 수 있다.
Redis는 영속성을 확보하기 위해 RDB(Redis Database Backup)와 AOF(Append Only File) 두 가지의 데이터 영속성 방법을 제공한다.
3. Redis 영속성 확보하는 방법 : RDB vs AOF 특징과 예시
RDB
- 특정 시간 간격으로 메모리의 데이터를 디스크에 스냅샷으로 저장하는 방법
- 스냅샷 사이의 데이터를 잃을 가능성이 있지만, 파일 크기가 작고 성능이 좋다
- 빠른 복구 시간과 디스크 공간의 효율성이 필요한 경우
- 예시) 대형 온라인 쇼핑몰의 장바구니 시스템 : 장바구니 데이터는 사용자의 편의를 위한 일시적인 데이터로, 일정 시간이 지나면 자동으로 삭제되기도 한다. 장바구니 데이터는 일부 손실이 허용될 수 있으며, 빠른 서비스 복구 시간과 디스크 공간의 효율성이 더 중요하기 때문
AOF
- 모든 데이터 변경 명령을 로그로 기록하는 방법
- 파일 크기가 크고, 디스크 I/O 부하가 높을 수 있지만, 모든 데이터 변경을 기록하기 때문에 데이터 손실 없이 서버를 복구할 수 있다.
- 데이터의 완전성이 중요하고, 최근 데이터의 손실이 허용되지 않는 경우
- 예시) 실시간 금융 거래 시스템 : 거래 데이터가 중요하며, 거래가 완료되면 즉시 데이터베이스에 반영되어야 한다. 거래 데이터의 손실은 금융적 손해를 초래할 수 있으므로, AOF 방식을 사용하여 모든 거래 데이터를 안전하게 보관이 필요
RDB와 AOF를 같이 사용 하는 경우
- 두 가지 방식의 장점을 모두 활용 가능. AOF를 사용하여 데이터의 완전성을 보장, RDB를 사용하여 빠른 복구를 지원
- 예시) 소셜 네트워크 서비스
- 사용자의 게시물, 댓글, 좋아요 등의 데이터가 계속 생성
- 해당 데이터는 사용자의 활동 내역을 표현하므로 중요, 서비스의 대규모 트래픽 때문에 빠른 복구 시간도 중요
- RDB와 AOF를 함께 사용하여 데이터의 완전성과 빠른 복구 시간을 동시에 확보
- 주의점
- Redis 서버가 재시작될 때 AOF 파일이 있으면 AOF 파일을 우선적으로 데이터 복구. AOF 파일이 더 최신의 데이터 변경 사항을 반영하고 있기 때문.
- AOF 파일이 관리되지 않아 불필요하게 커져 디스크 공간을 많이 차지할 경우 복구 시간이 오래걸리 때문에 RDB와 AOF를 같이 사용하는 경우 AOF의 정기적인 *리라이트 관리가 필요
"리라이트(rewrite)"는 AOF(Append Only File) 파일의 크기를 줄이기 위한 작업
Redis에서 데이터 변경 명령이 있을 때마다 AOF 파일에 기록되므로, 시간이 지나면서 AOF 파일의 크기가 계속 커진다. 또한, 같은 키에 대한 여러 개의 변경 명령이 AOF 파일에 순서대로 기록되므로, 이러한 변경 명령 중 최신의 명령만 유효된다.
이런 경우, AOF 파일에 저장된 명령들을 처음부터 끝까지 순서대로 재실행하는 것은 비효율적이다. 따라서 Redis는 'bgrewriteaof'라는 명령어를 제공하여, 현재의 데이터 상태를 반영하는 최소한의 명령들만을 포함하는 새로운 AOF 파일을 생성한다. 이 작업을 '리라이트'라고 한다.
예시) 'key1'에 대해 'set key1 value1', 'set key1 value2', 'set key1 value3' 순서대로 명령이 실행되었다면, 이 세 개의 명령을 모두 재실행하는 대신 'set key1 value3'만 재실행
리라이트 작업을 통해 AOF 파일의 크기를 줄이고, 서버 재시작 시의 복구 시간을 단축할 수 있다.
AOP 리라이트 설정하기: redis cli에서 BGREWRITEAOF 명령어 입력
redis-cli BGREWRITEAOF
* 현재 AOF 리라이트가 진행 중이거나 RDB 저장이 진행 중인 경우, BGREWRITEAOF 명령은 예약만 되고 즉시 실행되지 않음
자동으로 AOF 리라이트 설정하는 방법
AOF 파일의 크기가 특정 비율 이상 커졌을 때 자동으로 AOF 리라이트를 수행하도록 설정. redis.conf 파일에서 설정
<예시>auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb
* AOF 파일의 크기가 최초 파일 크기의 100% 이상, 파일의 크기가 64mb 이상일 때 AOF 리라이트를 자동으로 수행
* 두 조건 중 하나라도 만족하면 리라이트 진행
4. 설정방법
RDB
RDB를 활성화하려면 redis.conf 파일(redis 설정파일)에서 'save' 옵션을 설정. 아래코드 블럭 참고.
save 900 1 # 900초(15분) 동안 1회 이상의 데이터 변경이 발생하면 스냅샷 생성
save 300 10 # 300초(5분) 동안 10회 이상의 데이터 변경이 발생하면 스냅샷 생성
save 60 10000 # 60초(1분) 동안 10000회 이상의 데이터 변경이 발생하면 스냅샷 생성
AOF
AOF 설정을 활성화하려면 redis.conf 파일(redis 설정파일)에서 'appendonly' 항목을 'yes'로 변경
appendonly yes # AOP 활성화
5. 마치며
redis에서 데이터 영속성을 확보 할 수 있는 방법을 알아보았다. 설정자체가 어렵지는 않아서 조회수 구현할때 RDB랑 AOF를 같이 사용하는 방법을 선택했다. 리라이트도 필수 설정! 처음 레디스로 기능구현했다가 서버재시작시 데이터가 초기화 됬던 때가 생각난다. 엄청 당황스러웠는데 이렇게 간단한 설정만으로 데이터를 계속 가져갈 수 있다니..
이번글을 쓸려고 RDB와 AOF에 대한 예시는 추가적으로 찾아봤는데 말로만 들었을 때보다 더 와닿는다. RDB와 AOF 각각의 장단점을 이해하고 상황에 따라 적절한 방법을 선택할 수 있도록 잘 인지 하고 있어야겠다.
[reference]
'개발 하나둘셋 > Java & Spring' 카테고리의 다른 글
FFmpeg로 자막(srt) 삽입하여 영상 인코딩 시 자막이 깨지는 문제! Troubleshooting (0) | 2024.06.23 |
---|---|
Spring Boot 3.x 주요 변경 사항과 마이그레이션 방법 (0) | 2024.02.04 |
Redis를 활용한 효율적인 조회수 관리 방법 (2) | 2024.01.04 |
Java 'MultipartFile'에서 파일 이름 가져오기 문제와 해결방법, 유니코드 (0) | 2023.12.21 |
AWS SDK for Java V1, V2 차이 / s3객체 업로드, 복사, 삭제 구현하기 (0) | 2023.06.26 |