이전의 sports echo 프로젝트에서 Redis의 sorted set을 활용해 대기열 시스템을 구현하였다. 여기서 Redis를 채택한 이유는 Redis가 인메모리 데이터베이스이므로 삽입, 삭제, 조회 속도가 매우 빨라 많은 사용자들이 동시에 접속하는 대기열 시스템에 적합하다고 판단했기 때문이다.
또한, sorted set을 선택한 이유는 해당 set이 각 요소에 대해 점수(score)를 부여하고 이 점수를 기준으로 데이터를 자동으로 정렬된 상태로 저장하기 때문이다. 대기열 시스템에서는 점수를 사용자들의 접속 시간으로 설정하게 되면 sorted set은 접속 순서대로 데이터를 저장하게 된다. 뿐만 아니라 sorted set은 데이터 삽입 삭제에 O(log N)의 시간 복잡도를 가지기 때문에 대기열에 사용자를 추가하거나 순서를 확인하는 작업도 빠르게 처리될 수 있다.
그러나 인메모리 데이터베이스의 가장 큰 특징은 서버가 다운되면 데이터가 손실된다는 것이다. 즉 대기열에 접속한 사용자가 너무 많아 서버가 죽게되면 sorted set에 저장된 사용자들의 접속 순서 또한 사라질 수 있다. 이 문제를 어떻게 해결할 수 있을까?
Redis는 데이터 영속성을 보장하기 위해 몇 가지 백업 및 복구 매커니즘을 제공한다. 그 방법에는 RDB와 AOF가 있다.
RDB(Redis Database Bachup)은 특정 시점의 메모리 데이터를 스탭샷으로 찍어서 디스크에 저장하는 백업 방식이다. 이 스냅샷 파일(.rdb)을 통해 데이터베이스의 상태를 일정 시점으로 복구할 수 있다.
스냅샷 파일은 SAVE
, BGSAVE
등의 명령어를 통해 수동으로 생성할 수도 있고, redis.conf
파일에서 설정한 규칙에 따라 자동 생성도 가능하다.
SAVE
: 메인 프로세스가 직접 파일을 작성하여 스냅샷 생성 도중 모든 클라이언트의 요청을 처리하지 못함BGSAVE
: 백그라운드에서 비동기적으로 스냅샷을 생성하여 요청 처리와 스냅샷 생성을 동시에 처리 가능RDB의 장점으로는 디스크 I/O에 큰 부하를 주지 않는다는 점, .rdb 파일 하나로 전체 DB를 복구할 수 있어 속도가 빠르다는 점, 압축 파일이므로 파일 사이즈가 작다는 점 등이 있다.
단점으로는 .rdb 파일은 특정 시점에만 데이터를 저장하므로 해당 시점 이후에 발생한 데이터 변경은 손실될 수 있다는 점, 스냅샷이 생성되는 동안 대규모 데이터 세트가 존재하는 경우 I/O 부하가 일시적으로 증가할 수 있다는 점 등이 있다.
AOF(Append-Only File)는 Redis에서 발생하는 모든 쓰기 명령을 로그 파일(.txt)에 차례대로 기록하는 방식이다. Redis는 서버 재시작시 로그를 재생하여 데이터를 복원한다.
AOF는 fsync
옵션에 따라 로그 파일에 기록되는 빈도가 결정된다. 또한 AOF 파일은 시간이 지남에 따라 파일 크기가 커지는데 Redis에서는 BGREWRITEAOF
명령어를 통해 AOF 파일을 더 작은 파일로 압축할 수 있다.
AOF의 장점은 AOF는 모든 쓰기 명령을 기록하므로 RDB보다 더 높은 데이터 무결성을 지원한다는 점, 옵션을 통해 성능과 안정성을 사용자의 요구에 맞게 조정할 수 있다는 점 등이 있다.
단점으로는 계속해서 파일 크기가 커지므로 주기적인 rewrite 작업이 필요하다는 점, RDB보다 복구 속도가 느리다는 점 등이 있다.
RDB와 AOF를 조합하여 같이 사용할 수 있다. 기본적으로 RDB로 데이터를 백업하고 AOF를 옵션으로 사용하여 가장 최근 데이터를 복원한다. 이 방법은 복구 속도와 무결성을 모두 고려한 최적의 방법이라고 할 수 있다.