가용성
- 서비스의 안정성을 측정하는 데 사용되는 지표
- Availability = Available for Use Time / Total Time
- 일정 기간 동안 서비스를 정상적으로 사용할 수 있는 시간 비율
- 고가용성 시스템: 가용성이 높은 시스템
고가용성 확보를 위한 기능
- 복제: 마스터 노드의 데이터를 복제본 노드로 실시간 복사하는 기능
- 자동 페일오버: 마스터 노드에서 발생한 장애를 감지해 레디스로 들어오는 클라이언트 연결을 자동을 ㅗ복제본 노드로 리다이렉션 하는 기능
1. 레디스에서의 복제 구조
- 운영 중인 서비스에서 복제본 노드를 추가하는 이유
- 서비스를 안정적으로 운영하기 위해서는 마스터 DB가 다운됐을 때 대신 사용할 여분의 복제본 필요
- 마스터 노드에 접근하는 서비스가 많을 때, 일부 트래픽이 복제본을 바라보게 해 부하 분산
- 백업을 복제본에서 수행해 백업 작업이 서비스에 미치는 영향도 최소화
- 레디스는 복제본 노드가 기본으로 읽기 전용으로 동작. 모든 데이터 입력은 마스터 노드에서 이루어짐
복제 구조 구성하기
REPLICAOF <master-ip> <master-port>
- 한 개의 복제 그룹에서는 항상 한 개의 마스터 노드만 존재
- 복제본 노드에 새로운 복제본 추가 가능
패스워드 설정
- requirepass 옵션을 이용해 패스워드 설정
- 복제본 노드는 masterpass 옵션에 마스터의 requirepass에 설정된 패스워드 값 입력
- 하나의 복제 그룹에 속한 마스터와 복제본 노드는 같은 패스워드로 설정하는 것이 일반적(다른 패스워드도 가능)
2. 복제 메커니즘
- 버전 7 이전
- repl-diskless-sync 옵션 기본값 no(디스크 사용 방식)
- 디스크 사용하는 방식에서의 복제 연결 메커니즘
- REPLICAOF 커맨드로 복제 연결 시도
- 마스터 노드에서는 fork로 자식 프로세스를 새로 만든 뒤 RDB 스냅샷 생성
- 2번 과정 동안 마스터 노드에서 수행된 모든 데이터셋 변경 작업은 레디스 프로토콜(RESP) 형태로 마스터의 복제 버퍼에 저장
- RDB 파일이 생성 완료되면 파일은 복제본 노드로 복사
- 복제본에 저장됐던 모든 내용을 삭제한 뒤 RDB 파일을 이용해 데이터 로딩
- 복제 과정 동안 버퍼링됐던 복제 버퍼의 데이터를 복제본으로 전달해 수행시킴

- 복제 속도는 디스크 I/O 처리량에 영향 받음
- RDB 파일이 생성되는 도중 다른 노드에서 복제 연결 요청이 들어오면 큐에 저장하고 기존 RDB 저장이 완료된 후 여러 복제본이 한 번에 복제 연결 시작
- 버전 7 이후
- repl-diskless-sync 옵션 기본값 yes(디스크 사용하지 않는 방식)
- 디스크 사용하지 않는 방식에서의 복제 연결 메커니즘
- REPLICAOF 커맨드로 복제 연결 시도
- 마스터 노드는 소켓 통신을 이용해 복제본 노드에 바로 연결하며, RDB 파일은 생성됨과 동시에 점진적으로 복제본의 소켓에 전송됨
- 2번 과정 동안 마스터 노드에서 수행된 모든 데이터셋 변경 작업은 레디스 프로토콜(RESP) 형태로 마스터의 복제 버퍼에 저장
- 소켓에서 읽어온 RDB 파일을 복제본의 디스크에 저장
- 복제본에 저장된 모든 데이터를 삭제한 뒤 RDB 파일 내용을 메모리에 로딩
- 복제 버퍼의 데이터를 복제본으로 전달해 수행시킴

- 복제본 노드는 마스터에서 가져온 데이터를 모두 삭제하는 과정을 거치는데, 소켓 통신으로 받아온 RDB 데이터가 정상적인지 미리 확인할 수 없어 삭제 전 자신의 디스크에 데이터를 저장하는 과정을 선행해 데이터의 안정성 확보
- 디스크의 I/O가 느리고 네트워크가 빠른 경우 디스크를 사용하지 않는 복제 방식을 사용하는 것이 더 빠르게 복제 연결을 완료할 수 있는 방법
- 하나의 복제본으로 복제 연결이 시작된 경우 복제 과정이 끝나기 전까지 다른 복제본과의 연결 수행 불가. 다른 복제본들은 하나의 복제 연결이 끝날 때까지 큐에서 대기
- repl-diskless-sync-delay 설정을 통해 설정 시간 만큼 기다린 뒤 복제 연결 시작
- 네트워크가 유실되어 재동기화를 요청할 경우 마스터에는 한 번에 여러 개의 복제본에서 복제 연결이 들어오는 것이 일반적이기 때문에 repl-diskless-sync-delay 옵션 활성화 하는 것이 좋음
비동기 방식으로 동작하는 복제 연결
- 정상적으로 복제 연결이 된 상태에서 마스터에서 복제본으로의 데이터 전달은 비동기 방식으로 동작
- 클라이언트는 데이터 입력할 때 마다 복제본에 데이터가 정확하게 전달 되었는지 확인하지 않기 때문에 복제 구조를 사용해도 짧은 지연 시간과 높은 성능 가짐
복제 ID
- 모든 레디스 인스턴스는 복제 ID(랜덤 스트링) 가짐
- 복제 ID는 오프셋과 쌍으로 존재
- 레디스 내부의 데이터가 수정되는 모든 커맨드를 수행할 때마다 오프셋 증가
- INFO REPLICATION: 복제 연결 상태 확인
- INFO REPLICATION을 통해 확인한 복제본의 replication id는 마스터의 replication id이고, 오프셋은 복제본에서 마지막으로 수행된 마스터의 오프셋
- replication id와 오프셋이 같을 때 두 노드는 정확히 일치된 상태
부분 재동기화
-
레디스는 부분 재동기화 기능을 사용해 안정적으로 복제 연결 유지
-
마스터는 커넥션 유실을 대비해 백로그 버퍼라는 메모리 공간에 복제본에 전달한 커맨드 데이터 저장
-
PSYNC: 복제본이 자신의 replication id와 오프셋을 마스터에 전달해 복제 재연결 시도

-
복제본이 보낸 repliation id가 현재의 마스터와 일치하지 않다면 전체 재동기화 시도
-
복제본은 언제든지 마스터로 승격될 가능성을 갖고 있기 때문에 복제본에 직접 연결된 복제 연결이 따로 없더라도 백로그 버퍼를 해제하지 않음
Secondary 복제 ID
- 한 개의 복제본 그룹 내의 모든 레디스 노드는 동일한 복제 ID 가짐
- 마스터 노드와의 복제가 끊어짐과 동시에 복제본은 새로운 복제 ID 가짐
- 기존의 복제 ID는 master_replid2에 저장

- 노드 C가 B에 복제 연결이 될 때, 두 노드의 master_replid2가 같기 때문에 C 노드는 B 노드에 부분 재동기화 시도
레디스가 2개의 복제 ID를 갖는 이유는 마스터로 승격되는 복제본 때문이며, 같은 복제 그룹 내에서 페일오버 이후 승격된 새로운 마스터에 연결된 복제본은 전체 재동기화를 수행할 필요가 없을 수 있음
읽기 전용 모드로 동작하는 복제본 노드
- replica-read-only
- 복제본에 직접 데이터를 쓸 수 있다하더라도 복제본에 쓰는 내용은 로컬에만 유지되며 다른 복제본으로 전파되지 않음
- 서브 복제보는 항상 최상위 마스터가 중간 복제본으로 보낸 것과 동일한 복제 프로토콜을 전달 받음
유효하지 않은 복제본 데이터
- 유효하지 않은 데이터: 복제본의 데이터와 마스터의 데이터가 정확하게 일치하지 않는 경우의 데이터
- 복제본이 마스터와 연결이 끊어진 상태
- 복제 연결이 시작된 뒤 아직 완료되지 않았을 경우
- replica-serve-stale-data: 복제본의 데이터가 유효하지 않다고 판단될 때 복제본의 동작 방식 제어
- yes: 유효하지 않다고 판단될 때에도 클라이언트로부터 들어오는 모든 읽기 요청에 데이터 반환
- no: INFO, CONFIG, PING 등의 일부 기본 커맨드를 제외한 모든 커맨드에 대해 SYNC with master in progress 오류 반환
백업을 사용하지 않는 경우에서의 데이터 복제
- 레디스에서 복제를 사용하는 경우 마스터와 복제본에서 백업 기능을 사용하는 것이 좋음
- 백업 기능을 사용하지 않으려면 재부팅 후 레디스가 자동으로 재시작되지 않도록 설정하는 것 권장

- 백업 기능 사용하지 않는 마스터와 복제본 노드
- 마스터가 장애로 인해 종료되었지만 레디스 프로세스를 자동 재시작하는 시스템에 의해 노드 재부팅. 메모리 노드 초기화
- 복제본 노드에는 데이터가 존재하지만, 마스터 노드로의 복제 연결 시도
- 마스터에서 복제본으로 빈 데이터셋 전달