레디스를 캐시로 사용하기

Posted by yunki kim on October 27, 2025
  • 가용성은 일정 기간 동안 서비스를 정상적으로 사용할 수 있는 시간의 비율이다.
  • 레디스는 고가용성을 위해 두 가지 기능이 필요하다.
    • 복제: 마스터 노드 데이터를 복제본 노드로 실시간 복사한다.
    • 자동 fail-over: 마스터 노드에 장애 발생 시 자동감지해 클라이언트 연결을 복제본 노드로 리다이렉트한다.

1. 레디스에서의 복제 구조

  • 운영 중인 서비스에 복제본을 추가하는 이유는 다음과 같다.
    • 마스터 장애 시 대신 사용할 여분 확보
    • 마스터 노드에 대한 트래픽 분산
    • 백업 실행 시 마스터에 대한 부하를 줄여서 서비스 영향 최소화
  • MySQL, Postgresql은 멀티 마스터 복제 구조를 제공하기 때문에 모든 노드가 마스터이자 복제본이 될 수 있다.
  • 레디스는 마스터가 복제본이 될 수 없다. 2.6 버전 이상부터는 복제본이 기본적으로 read-only이다.

1.1 복제 구조 구성하기

  • 복제본이 될 레디스에 다음과 같은 커맨드를 입력하면 된다.
1
REPLICAOF <master-ip> <master-port>
  • 마스터가 여러개의 복제본을 갖거나, 복제본이 또 다른 복제본을 가질 수 있다. 하지만 복제 그룹에서는 한 개의 마스터 노드만 존재해야 한다. redis replication structure

    1.2 패스워드 설정

  • 레디스 6.0 이상부터 패스워드를 이용해 데이터를 복제할 때는 masteroauth 옵션에 패스워드를 입력해야 한다.
  • 패스워드 설정은 requirepass 옵션을 사용한다. 복제본은 masterauth라는 옵션에 마스터에 requirepass 값을 설정해서 마스터와 연결한다.
  • 복제본 인스턴스 수정 후 재시작 외에 아래 방법으로 설정 파일을 다시 적용할 수 있다.
1
2
3
CONFIG SET masterauth mypassword

CONFIG REWRITE

2. 복제 매커니즘

  • 버전 7 이전에는 repl-diskless-sync 옵션이 no이며 다음과 같이 복제 연결되었다. redis replication structure
  • 동작 과정
    1. 복제 연결 시도
    2. 마스터 노드가 fork()로 자식 프로세스 생성 후 RDB 파일 생성
      1. 이 과정에서 새로운 노드에서 복제 요청이 들어오면 요청을 큐에 저장한다. RDB 파일 생성 완료 후 한 번에 복제 연결을 시작한다.
    3. 2번 과정 중 실행된 모든 데이터 변경은 레디스 프로토콜 형태로 마스터의 복제 버퍼에 저장한다.
    4. 생성 완료된 RDB 파일을 복제본 노드에 복사한다.
    5. 복제본에 저장된 모든 내용을 삭제한 뒤 RDB파일을 이용해 데이터를 로딩한다.
    6. 마스터 복제 버퍼에 있던 커맨드를 복제본에서 실행시킨다.
  • 위 방식은 디스크를 사용하기 때문에 disk IO에 영향을 받는다.
  • 버전 7 이후부터는 repl-diskless-sync 옵션이 yes이다. diskless 복제 방식은 다음과 같다. redis replication structure
  • 동작 과정
    1. 복제 연결 시도
    2. 소켓 통신을 이용해 마스터와 복제본이 연결해서 RDB 파일을 생성됨과 동시에 복제본 소켓에 전송
    3. 2 과정 중 변경된 데이터는 레디스 프로토콜 형태로 마스터의 복제 버퍼에 저장
    4. RDB 파일을 복제본 디스크에 저장한다
    5. 복제본은 데이터를 모두 삭제하고 RDB 파일 내용을 메모리에 로딩한다.
      1. 소켓 통신으로 받은 RDB가 정상인지를 확인하지 못하기 때문에 데이터 안정성을 위해 우선 자신의 데이터를 디스크에 저장한다.
    6. 마스터의 복제 버퍼에 있던 커맨드를 복제본에서 실행시킨다.
  • diskless 방법에서는 복제 연결이 끝날떄 까지 새로운 복제 연결을 할 수 없다. 복제 연결 중 새로운 연결이 들어오면 큐에서 대기한다. 이를 방지하기 위해 ‘repl-diskless-sync-delay n’ 옵션을 사용한다. n은 초다. 기본값은 5초로, 새로운 복제 연결이 들어오면 n초간 대기 후 복제 연결을 시작한다. 이 기간 내 들어온 요청에 대해 소캣 통신을 한 번에 연결해 RDB 파일을 전송한다.

2.1 비동기 방식으로 동작하는 복제 연결

  • 마스터-복제본 간 데이터 전달은 비동기로 동작한다.
  • 클라이언트가 마스터 노드에게 데이터 입력 후, 복제본에 데이터 입력 성공 여부와 상관 없이 클라이언트에게 OK 응답을 보낸다.
    • 이 때문에 성능은 높지만 복제본에 데이터가 전달되지 않을 수도 있다. 데이터가 전달되는 속다는 매우 빠르기에 대체로 유실되지는 않는다.

2.2 복제 ID

  • 모든 레디스 인스턴스는 복제 사용 여부와 상관 없이 replication id를 가진다. offset 값은 매 수정 커맨드 실행 마다 1씩 증가한다. 두 레디스가 같은 replication id를 갖는다면, 이들은 동일한 데이터셋을 갖는다는 의미이다.
  • 두 값은 INFO REPLICATION이라는 커맨드로 확인 가능하다.
  • offset값을 master, slave에서 각각 확인했을 때 값이 다르다면 slave에서 그 만큼의 커맨드를 실행해야 마스터와 값이 일치한다는 의미이다. 아래 예시에서는 802 ~ 807 커맨드를 실행해야 한다. redis replication structure

    2.3 부분 재동기화

  • 레디스는 네트워크 환경에 상관 없이 빠른 동기화를 부분 재동기화를 제공한다.
    • 재연결 마다 RDB 파일을 새로 전달하면 네트워크가 안좋은 환경에서는 레디스 성능이 저하된다.
  • 재동기화 과정
    • 마스터는 백로그 버퍼라는 메모리 공간에 복제본에 전달한 커맨드를 저장해둔다. (기본 크기: 1MB, repl-backlog-size로 설정)
      • 백로그는 repl-backlog-size가 다 차거나 repl-backlog-ttl만큼 지나면 삭제
    • 복제본 재연결 후 PSYNC 커맨드 호출 후 자신의 replication id와 offset을 전달
    • 마스터가 자신의 offset과 차이 비교 후 차이나는 offset 내용을 전달해서 부분 재동기화(partial resynchronization)
      • 커맨드가 없거나 전달받은 replication id가 없다면 전체 재동기화(full resync)

2.4 Secondary 복제 ID

  • 레디스는 4.0 부터 복제본이 마스터로 승격될 때를 대비해 복제 ID를 2개 가진다.
  • master_replid는 마스터가 바뀔 때 같이 변경되며 기존 master_replid 값은 master_replid2에 저장된다.
  • 이렇게 되면 새로운 마스터 노드에 slave들이 재연결할 때 master_replid가 다름으로 인해 전체 재동기화를 할 필요가 없어진다. master_replid2가 같다면 부분 재동기화를 진행한다.

2.5 읽기 전용 모드로 동작하는 복제본 노드

  • 레디스 2.6 부터 복제본은 모두 read-only가 기본값이다. 이는 replica-read-only 옵션으로 제어된다.
  • 이 때, replica-read-only 옵션을 변경해서 복제본 데이터를 변경했더라도, 변경은 로컬에서만 반영된다.

2.6 유효하지 않은 복제본 데이터

  • 마스터와 복제본 데이터가 일치하지 않으면 유효하지 않은 상태이다.
  • 마스터와 복제본 간 연결 유실, 복제 연결 미완료 등 상황에서 복제본 데이터가 유효하지 않다.
  • 복제본 데이터가 유효하지 않을 때 동작을 replica-serve-stale-data 파라미터로 제어할 수 있다.
    • yes: 기본값, 데이터가 유효하지 않아도 모든 읽기 요청을 실행한다
    • no: INFO, CONFIG 등 일부 커맨드를 제외하고 모두 SYNC with in progress 에러를 반환한다.

2.7 백업을 사용하지 않는 경우에서의 데이터 복제

  • 복제본 사용 시 데이터 안전성을 위해 백업 기능을 같이 사용하는 것이 좋다.
  • 만약 백업을 사용하지 않는다면 마스터 레디스 자동 재시작 옵션을 사용하지 않는 것이 좋다. 그래야 복제본을 마스터로 변경해서 데이터가 사라지지 않는다.
  • 만약 마스터의 자동 재시작이 실행되면 다음과 같은 상황이 발생한다.
    • 백업을 사용하지 않는 마스터와 복제본이 존재한다.
    • 마스터 노드가 장애로 종료되고, 마스터 레디스가 자동 재시작한다. 메모리는 초기화된다.
    • 복제본 노드에 데이터가 존재하지만, 마스터 노드에 복제 연결을 시도한다.
    • 마스터 노드는 빈 데이터셋을 전달한다.

출처 - 개발자를 위한 레디스