레디스 데이터 영속성 방식
2025. 4. 1. 15:05

이 글을 쓰게 된 배경

성능과 데이터 저장의 효율이 좋다는 이유로 레디스를 주로 쓰는데, 레디스가 어떤식으로 데이터를 저장하고 내부적으로 어떻게 관리하는지에 대해 지식이 부족하다고 생각되어 레디스 서버에 대해서 더 자세히 학습했습니다. 이번 포스팅에서는 레디스의 데이터 영속성 방식과 제가 선택한 레디스 데이터 영속성 방식에 대한 글을 써보겠습니다.

다룰 내용

  • 레디스의 데이터 영속성 방식
  • 데이터 영속성 방식의 장단점
  • 구체적인 문제
  • 정리

레디스의 데이터 영속성 방식

제가 찾아본 레디스의 데이터 영속성 방식은 두가지입니다. 바로 AOF와 RDB 입니다. AOF 방식의 개념은 레디스를 실행하면서 수행한 모든 연산을 로그 형태로 저장하는 것입니다.  RDB 방식은 스냅샷 형태로 저장하는 개념입니다. 스냅샷이란 사진 촬영하는 것처럼 데이터베이스의 특정 시점의 데이터 정보를 저장하는 것입니다.

두 방식의 장단점

위에서 설명한 데이터 영속성 방식의 특징 덕분에 두 개념의 장단점은 확실합니다.

AOF는 모든 연산을 순차적으로 저장하기 때문에 데이터 유실이 거의 없고, 레디스를 중간에 꺼버려도 마지막 연산 로그까지 남아있기 때문에 문제가 없습니다. 하지만, 백업 시에 AOF 파일에 있는 모든 로그들을 읽어들이면서 모든 연산을 수행해야하기 때문에 백업 시간이 오래걸린다는 단점이 있습니다. AOF 파일 또한 레디스가 연산되는 모든 순간에 한줄씩 늘어나게 되고 AOF 파일의 크기는 점점 늘어나게 됩니다.

RDB는 특정 시점을 스냅샷을 찍기 때문에 스냅샷을 찍는 주기를 설정해야 합니다. 스냅샷 주기를 5분으로 설정한 레디스에서 스냅샷을 찍고 3분뒤에 레디스가 비정상적으로 종료된다면 3분동안 변경되거나 추가된 데이터가 모두 날아가게 됩니다. 하지만 데이터 유실을 막기 위해서 스냅샷 주기를 짧게 해버리면 어플리케이션에 부담을 주게된다는 단점이 있습니다.

구체적인 문제

각각의 방식의 문제점을 해결하기 위해서는 구체적으로 어떤 문제가 왜 발생하고 어떻게 발생하는지를 알아야 대안을 마련하거나 단점을 최소화하는 방법을 찾을 수 있기 때문에 구체적인 문제에 대해 찾아봤습니다.

RDB 방식

  1. 스냅샷은 전체 데이터를 디스크에 저장하기 때문에 디스크 쓰기 작업이 많아집니다.
    하드디스크를 사용하는 경우 디스크 I/O 병목 현상을 야기할 수 있습니다.
    특히, Redis를 실행하는 서버가 다른 애플리케이션과 디스크를 공유하고 있다면 전체 시스템 성능에 영향을 미칠 수 있습니다.
  2. 스냅샷을 찍을 때 레디스는 Fork를 사용하여 백그라운드에서 새로운 프로세스를 생성합니다.
    새로운 프로세스는 현재 Redis 데이터를 복사하여 디스크에 저장하는데, 이 과정에서 메모리를 추가로 사용합니다.
    Redis가 10GB의 데이터를 저장 중이라면, fork()가 실행될 때 추가로 10GB의 메모리를 더 필요로 할 수도 있습니다.
    어플리케이션에 레디스만 실행되고 있는것이 아닐 가능성이 크기 때문에 램의 크기 계산을 잘 해봐야 할 것 같습니다.

AOF 방식

  1. AOF 파일이 너무 커지면 서버 재시작 시에 레디스 백업 시간이 오래걸립니다.
    실제로 운영중인 어플리케이션에서 장애발생 후 1분 1초가 급하게 복구를 해야하는 상황에서는 큰 문제가 됩니다.
  2. AOF 방식은 한 파일에 연속적으로 로그를 저장하므로 이 파일에 문제가 생기면 전체 데이터가 복구되지 않을 수 있습니다.
    파일이 손상되면 수동으로 복구해야 하기 때문에 서비스 중단 시간이 길어질 수 있습니다.

AOF Rewrite

AOF 파일 크기가 너무 커지면 Redis가 백그라운드에서 AOF Rewrite를 실행합니다. 이 작업에서는 로그들을 최적화해서 파일의 크기를 작게 만드는 작업을 수행합니다.
* 이 과정에서 CPU와 메모리를 많이 사용하므로, 트래픽이 많은 상황에서는 성능이 저하될 수 있기 때문에 트래픽이 적을 때 수동으로 실행하는 것이 좋습니다.

내가 선택한 방법

두가지 백업방식에 각각 장단점이 있기 때문에 각각의 장점만 골라서 사용할 수 있는 방법은 없을까? 라는 고민을 했습니다. 그러다 찾게된 것이 두가지 방법을 모두 사용하는 것이었습니다. 레디스 서버가 갑자기 중단되었을 때 먼저 RDB 방식으로 서버를 백업시키고 다음으로 AOF 방식으로 최신상태까지 복원하면 최대한 많은 데이터를 복구할 수 있습니다.

하지만 이렇게 하면 AOF와 RDB 방식의 장점도 같이 가져갈 수 있지만 단점 또한 같이 가져가게됩니다. 이 부분은 레디스에서도 알고있고 어느정도 보완할 수 있는 방법을 제공해줍니다. 앞서 설명한 AOF Rewrite와 RDB 데이터 저장 간격을 적당하게 조절하는 방법을 통해서 어느정도 완화할 수 있다고 생각합니다.

 

제가 현재 가장 이상적이라고 선택한 방법이지만 모든 프로젝트에서 정답이라고 생각하지는 않습니다. 저 또한 다음 프로젝트에서는 한가지 방식을 선택할 수도 있다고 생각합니다. 극단적으로 대기업같이 데이터가 엄청 많은 곳이라면 AOF 방식을 사용하는 것이 좋다고 생각합니다. (RDB를 사용하면 스냅샷할때 한 세월 걸릴 것)

추가(2025.04.08)

레디스를 사용하다가 keys * 명령어를 사용해서 키 목록을 봤는데 내가 예상한 key의 개수보다 확연하게 많았다. 나는 key의 TTL을 일주일로 설정하고 있었기 때문에 많아봤자 100개의 키를 예상했는데 1000개의 키가 저장되어있었다.

redis-cli --raw scan 0 match "*" count 1000 | while read key; do echo "$key : $(redis-cli ttl "$key")"; done

 

위 명령어를 사용하면 현재 키들의 TTL을 볼 수 있다

결과는 처참했다. 거의 모든 키들의 TTL이 -1 이었다. (-1은 영구저장 -> 원래 의도와 다름(비정상))

 

레디스에 토큰을 저장하는 로직에는 이상이 없었고 진짜 원인은 내가 로컬에서 레디스 서버를 자주 껐다가 킨 것이 문제였다. 레디스는 따로 설정을 하지 않으면 기본으로 RDB로 백업하는데 RDB는 TTL까지 백업하지 못한다. 그래서 껐다가 킬때마다 모든 키들이 영구저장 상태로 바뀐 것이었다. AOF 백업을 사용하면 TTL까지 복구 가능하다고 한다. 원래도 AOF가 더 좋다고 생각했지만 AOF를 써야할 이유가 하나 더 늘어난 듯 하다.

'Redis' 카테고리의 다른 글

레디스 설정 적용  (0) 2025.04.18
조회수 최적화(Redis Pipe + Batch)  (0) 2025.02.15