Redis 정복기 1편 : 백업

한솔·2023년 5월 24일
1

OOO정복기

목록 보기
2/2
post-thumbnail

📌Redis의 백업

In-memory DB

  • Redis는 In-memory 데이터 저장소이므로 서버를 재시작하면 모든 데이터가 사라진다.
  • Redis를 캐시 이외에도 용도로 사용할 경우, 데이터를 미리 백업해 두어야 한다.

Redis Persistence

  • 메모리의 데이터를 디스크에 저장하여 영속화하는 기능
  • 방식
    • RDB (Redis Database) : 주기적으로 특정 시점의 스냅샷을 남기는 방식
    • AOF (Append Only File) : 모든 쓰기 명령에 대한 로그를 남기는 방식

📌RDB : 주기적으로 특정 시점의 스냅샷을 남기는 방식

특징

  • 특정 시점의 데이터 전체를 바이너리 파일로 저장한다.
  • 기본적으로 dump.rdb 파일에 저장된다.

장점

  • 비교적 파일 사이즈가 작다.
  • 대량의 데이터를 빠르게 로드할 수 있다.
    • AOF 가 10초 걸린다면, RDB는 7초 정도로 생각하면 된다.
  • bgsave를 활용하면, fork()로 자식 프로세스를 이용해 디스크에 영속화할 수 있다.
    • 메인 프로세스는 디스크 I/O를 하지 않고, 클라이언트의 요청을 계속 처리할 수 있다.

단점

  • 갑자기 Redis가 중지되는 경우, 가장 최근 스냅샷 이후의 데이터가 손실된다.
  • save를 활용하면, 데이터가 너무 큰 경우에 fork()에 소요되는 시간이 길어져서 클라이언트의 요청을 처리하지 못하는 상황이 발생한다.

save, bgsave

# redis.conf
save 900 1
bgsave 900 1

# cli
$ config get save
$ config get bgsave
$ config set save 900 1
$ config set bgsave 900 1
  • 둘 다 RDB 파일을 생성하는 설정이다.
  • save : 파일 쓰기 작업을 메인 프로세스가 직접 하기 때문에, 작업이 종료될 때까지 클라이언트의 명령을 처리할 수 없다.
  • bgsave : 파일 쓰기 작업을 자식 프로세스에서 수행하기 때문에, 작업 중에도 클라이언트의 명령을 처리할 수 있다.
  • save 동작
    1. 메인 프로세스가 데이터를 임시 RDB 파일에 쓴다.
    2. 쓰기가 끝나면 현재 RDB 파일을 삭제하고, 임시 RDB 파일로 교체한다.
  • bgsave 동작
    1. 자식 프로세스를 fork() 한다.
    2. 자식 프로세스는 데이터를 임시 RDB 파일에 쓴다.
      • 그 동안에 메인 프로세스는 클라이언트의 요청을 처리할 수 있다.
    3. 쓰기가 끝나면 현재 RDB 파일을 삭제하고, 임시 RDB 파일로 교체한다.

📌AOF : 모든 쓰기 명령에 대한 로그를 남기는 방식

특징

  • AOF파일은 Redis에서 발생한 모든 데이터의 변경 이력을 저장한다.
  • 입력/수정/삭제 명령이 실행될 때마다 AOF 파일에 명령과 데이터를 기록한다.
  • AOF 파일을 rewrite하여 데이터를 복원할 수 있다.

장점

  • 손실 없이 데이터를 복구할 수 있다.

단점

  • AOF에 데이터가 계속 추가되기 때문에 파일 사이즈가 커진다.
  • 사이즈가 크기 때문에 서버 시작시 로딩 속도가 느리다.
    • 이 경우, rewrite를 통해 파일 데이터를 다시 써서 사이즈를 줄인다.

rewrite

  • AOF 파일은 text 파일이므로 수정 가능하다.
  • rewrite를 통해 불필요한 데이터를 제거하여 파일 사이즈를 줄인다.
  • ex) set 명령으로 동일한 key의 value를 5번 변경하면 메모리에는 수행된 값만 남아있다. 하지만 AOF에는 5번이 모두 남아있기에, 이전 기록은 모두 지우고 최종 데이터만 기록하여 파일 사이즈를 줄일 수 있다.
  • ex) 실수로 flushall 명령을 수행한 경우, 서버를 종료한 후, AOF파일을 열어서 flushall 명령을 삭제하고 재시작하면 된다.
  • 동작 순서
    1. 자식 프로세스가 fork()를 수행한다.
    2. 자식 프로세스는 기존 데이터를 새로운 임시 AOF 파일에 쓴다.
    3. 동시에, 메인 프로세스는 새로운 명령을 처리하면서, 현재 AOF 파일에 쓴다.
      • rewrite 작업이 실패해도 데이터를 안전하게 보존하기 위함이다.
    4. rewrite 작업 실패 시 데이터 보존을 위해..
    5. 자식 프로세스가 fork()된 시점의 데이터 쓰기가 완료 되면 메인 프로세스에게 stop 시그널을 보낸다. (1차 쓰기)
    6. 메인 프로세스가 stop 시그널을 받으면, 1차 쓰기 동안 추가로 발생한 데이터를 자식 프로세스에게 전송한다.
    7. 자식 프로세스는 해당 데이터를 받아 임시 AOF파일에 쓰고, 완료되면 메인 프로세스에게 완료 시그널을 보낸다. (2차 쓰기)
    8. 메인 프로세스는 임시 AOF 파일을 열고, 2차 쓰기 동안 추가로 발생한 데이터를 쓴다. (3차 쓰기)
    9. 3차 쓰기가 완료되면 현재 AOF 파일을 삭제하고, 임시 AOF 파일로 교체한다.

📌 복구

redis.conf의 appendonly

  • 별도의 명령 없이, Redis를 재시작할 때 appendonly 속성에 따라 복구가 이루어진다.
  • appendonly 설정이 yes인 경우, AOF 파일을 먼저 읽는다.
    • AOF 파일이 없다면 RDB 파일이 있어도 읽지 않는다.
  • appendonly 설정이 no인 경우, RDB 파일을 먼저 읽는다.
    • RDB 파일이 없다면, AOF 파일이 있어도 읽지 않는다.

AOF를 ‘기본’으로 하고, RDB를 ‘옵션’으로

  • AOF는 최근의 데이터까지 복구할 수 있다.
  • AOF를 사용해도 성능에 성능에 거의 영향을 미치지 않는다.
  • AOF 시간 설정은 매초 fsync로 하고, AOF Rewrite를 사용한다.
  • 빠른 재시작을 위해 데이터베이스 백업으로 RDB 스냅샷을 저장하여 바로 복구하는 방식을 추가로 사용할 수 있다.

RDB를 ‘기본’으로 하고, AOF를 ‘옵션’으로

  • 장애가 났을 때, 데이터 유실이 생겨도 괜찮은 경우에 사용한다.
  • 최근의 데이터가 유실될 가능성이 있다.

📌 실습

AOF를 적용하기 위해, redis.conf의 appendonly 속성을 yes로 설정하였다.

나머지 속성들은 기본값을 사용하였다.

변경 사항을 저장하고, Redis를 재시작한다.

# redis.conf 

############################## APPEND ONLY MODE ###############################

appendonly yes
appendfilename "appendonly.aof"
appendfsync everysec
no-appendfsync-on-rewrite no
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb
aof-load-truncated yes
aof-use-rdb-preamble yes

...

GASOMANN의 경우, Redis의 Sorted Set 자료구조를 이용해 랭킹 시스템을 구축하였다.

테스트를 위해 dev-server에 더미데이터를 생성하는 API를 추가하였는데, 이것을 호출하면 Redis-server에 랭킹 데이터가 저장된다.

아래는 API를 호출한 결과이다.

앞서 AOF를 적용하였기 때문에, 모든 쓰기 동작이 appendonly.aof에 기록되어 있다.


따라서, Redis를 재시작해도 데이터가 그대로 있는 것을 확인할 수 있다.


📌Redis 환경 설정

설정 방법

  1. redis.conf 파일 변경
  2. 실시간 명령 (config set)
    • Redis가 운영되는 중에만 적용된다.
    • 영구 적용을 위해서는 redis.conf 파일을 변경해야 한다.
    • config rewrite 명령으로 현재의 설정을 redis.conf 파일에 저장할 수 있다.

redis.conf 주요 설정

  1. 기본 설정
    • port: 인스턴스가 사용할 서비스 포트 (default : 6379)
    • bind: 인스턴스가 사용할 네트워크 설정. 사용할 아이피 설정. bind 192.168.10.100
    • timeout: 연결된 클라이언트의 유휴 대기 시간
      • 해당 시간동안 송/수신이 발생하지 않으면 클라이언트의 연결을 끊는다.
      • 0으로 설정하면 사용하지 않을 수 있다.
    • loglevel: 인스턴스 동작 중에 출력되는 로그의 레벨을 지정
    • logfile: 로그가 저장되는 경로와 파일명을 지정
    • database: 레디스에서 제공하는 논리적으로 분리된 데이터 저장공간
      • RDBMS의 스키마 개념과 동일하다.
      • 각각의 데이터베이스는 숫자로 구분된다.
      • 기본값으로 16이 사용되며, 16개의 분리된 데이터 저장 공간을 사용한다.
      • 레디스에 연결된 클라이언트는 기본적으로 database 0에 접속하게 된다.
      • 0번 이외의 데이터베이스에 접속 시 명령창에 [index] 가 출력되어 접속 중인 데이터베이스를 확인 할 수 있다.
  2. 백업 - RDB (스냅샷)
    • save: 스냅샷을 찍는 주기를 설정한다.
      • 시간/키 변경회수의 쌍으로 설정한다.
        • save 300 10 : 300초 경과 혹은 키 변경이 10개 발생 시 스냅샷
        • save 900 1 : 900초 경과 혹은 키 변경이 1개 발생 시 스냅샷
      • save 설정이 여러 개인 경우, 하나라도 만족하면 스냅샷이 작동한다.
      • save “” 로 설정하면 스냅샷을 사용하지 않는다.
    • stop-writes-on-bgsave-error: 스냅샷에 의해 dump.rdb에 내용을 저장하는 도중쓰기 오류가 발생할 경우 행동을 설정한다. save에만 해당하고, bgsave에는 해당하지 않는다.
      • no : 쓰기 요청에 실패해도, 에러 없이 이후 동작을 정상 처리한다.
        • 서비스를 계속 유지하는 것이 중요할 경우 권장된다.
      • yes : 쓰기 오류가 발생하는 것을 감지하고, 모든 쓰기 요청을 거부한다.
    • rdbcompression: 스냅샷 파일을 저장할때 파일의 압축 여부를 설정.
      • 압축 시, dump.rdb 파일의 크기는 줄어 들지만, 작업할 때 CPU 사용률이 높아진다.
      • 압축률이 그다지 높지 않아 보통은 사용하지 않는다.
    • dir: 레디스의 작업 디렉토리를 지정한다.
      • 레디스가 생성하는 파일의 기본 위치로 사용된다.
      • dump.rdb, aof 파일, 로그파일 등이 저장된다.
    • dbfilename: 스냅샷 파일의 이름을 설정한다. (default : dump.rdb)
  3. 백업 - AOF
    • appendonly: AOF 기능의 사용 여부를 설정한다. (default : no)
      • on : AOF 파일을 읽는다.
      • off : RDB 파일을 읽는다.
    • appendfilename: AOF 파일명을 지정한다. (default : appendonly.aof)
      • 해당 위치에 파일이 없거나 생성에 실패하면 오류 메세지를 출력하고 종료한다.
    • appendfsync: 데이터를 dump.rdb 또는 AOF 파일에 쓸 때, fsync() 함수를 호출해 버퍼의 내용을 디스크에 즉시 기록할지 여부를 결정한다.
      • 데이터가 유실될 위험은 줄어들지만, 파일 기록 성능이 저하 될 수 있다.
      • no : fsync() 함수를 호출 하지 않는다.
        • OS로 쓰기 명령을 전달하고, OS에서 알아서 파일에 저장하도록 한다.
        • 빠른 성능을 제공하지만 , OS에 쓰기 명령을 전달하고 완료되기 전에에 문제가 생기면 데이터 손실이 발생할 수 있다.
      • always : 각 명령어를 AOF 파일에 기록하고 나서 항상 fsync()함수를 호출한다.
        • 느린 성능을 제공하지만 안전하게 데이터를 저장할 수 있다.
      • everysec : 매 초마다 fsync() 함수를 호출한다. (default)
    • no-appendfsync-on-rewrite : appendfsync 값이 always나 everysec으로 되어 있을 경우, 대량의 AOF 또는 스냅샷을 쓸 때 디스크의 성능에 따라 성능 이슈가 발생 할 수 있다. 이 때, fsync() 함수 호출을 하지 않도록 할 수 있다.
      • no : 기존대로 fsync()를 호출한다.
      • yes : fsync()를 사용하지 않는다.
      • 이럴 경우 fsync() 함수 호출을 하지 않게 한다.  NO로 설정하면 기존대로 fsync()함수를 호출하고, YES로 설정해야 fsync()를 사용하지 않는다.
    • auto-aof-rewrite-percentage : AOF 파일 사이즈가 특정 퍼센트 이상 커지면 rewrite하는 설정 (default : 100)
      • 레디스 서버가 시작할 시점의 AOF 파일 사이즈를 기준으로 퍼센트를 측정한다.
    • auto-aof-rewrite-min-size : AOF 파일 사이즈가 특정 사이즈 이하면 rewrite를 하지 않도록 하는 설정
      • 파일 크기가 작을 때, auto-aof-rewrite-percentage 에 의해 rewrite가 자주 발생하는 것을 막아준다.
  4. 제한 설정
    • maxclient: 인스턴스에 접속 할 수 있는 최대 클라이언트 수를 지정한다. (default : 1024)
      • OS의 ulimit 값과도 연관이 있기 때문에 ulimit 제한도 함께 변경해야 한다.
        • /etc/limits.conf , /etc/security/limits.conf
    • maxmemory: 인스턴스가 데이터 저장에 사용할 메모리 크기를 지정한다.
      • 이 값보다 많은 데이터를 저장하면 maxmemory-policy 설정에 지정된 값에 따라서 레디스의 동작이 달라 진다.
    • maxmemory-policy : 레디스에서 저장한 데이터가 maxmemory를 넘을 경우, 수행할 정책을 지정한다.
      • volatile-lru : 만기시각이 설정된 key 들 중에서 LRU에 의해 key 삭제 (default)
      • allkeys-lru : LRU에 의해 key 를 골라 삭제
      • volatile-random : 만기시각이 설정된 key 들 중에서 랜덤하게 key 삭제
      • allkeys-random : 랜덤하게 key 삭제
      • volatile-ttl : 만기시각이 설정된 key 들 중에서 만기가 가장 임박한 key 삭제
      • noeviction : 어떤 key 도 삭제하지 않고 error on write operations 를 돌려준다.
    • maxmemory-samples : maxmemory-policy를 적용하기 위해 레디스가 조회 할 키의 개수를 지정한다.
      • 전체 키를 읽어서 삭제 policy에 해당하는 키를 찾는게 아니라, 지정한 값 만큼의 임의의 키를 읽어서 그 중에서 삭제 대상인 키가 있는지 확인 한다.
      • 이때 임의로 읽어 들일 키의 개수를 지정한다.
profile
나는 N번째 다시 태어났다.

0개의 댓글