Redis 운영 관리
Redis 주요 특성
- Key-Value Store : 단순 스트링에 대한 key/Value 구조를 지원
- 컬렉션 지원 : List, Set, Sorted Set, Hash 등의 자료구조를 지원
- Pub/Sub 지원 : 서버간에 통지가 필요할 때 유용
- 디스크 저장 : 현재의 메모리 상태를 디스크에 저장 가능
- 복제 : 다른 노드에서 해당 내용을 복제할 수 있는 master/slave 구조 지원
- 빠른 속도 : 초당 50,000 ~ 60,000 QPS 이상의 처리 속도 지원
Single Thread
Redis 는 싱글 스레드이다. 그래서,시간이 오래 걸리는 Redis 명령을 호출하면, 명령을 처리하는 동안 다른 client 의 요청을 처리할 수 없다.
이런 특성 때문에 주의해야하는 경우가 몇 가지 있다.
서버에서 keys 명령을 사용하지 마라.
keys 명령은 서버에 저장된 key 목록을 볼 수 있는 명령이다.
모든 key 를 대상으로 검색한다. 작업하는 동안 다른 client 의 요청을 처리할 수 없다.flushall/flushdb 명령을 주의해라.
redis 는 db 라는 가상의 공간을 분리할 수 있는 개념이 있는데, select 명령으로 이동할 수 있다.
그래서, 같은 key 이름이라도 db 개수에 따라 여러 개 만들 수 있다. 예를 들면,1
2
3
4
5
6
7select 0
set jko "1234"
select 1
set jko "5678"
get jko --> 결과 : 5678
select 0
get jko --> 결과 : 1234flushdb 는 하나의 db 를 선택해서 지우고, flushall 은 데이터 전체 내용을 지운다.
flushall 의 경우 실제 존재하는 모든 데이터를 일일이 삭제하는데, 속도가 O(n) 이기때문에 데이터 양에 영향을 받는다.
작업하는 동안 다른 client 의 요청을 처리할 수 없다.
Persistent : RDB/AOF
Redis 는 데이터를 디스크로 저장할 수 있는 Persistent 기능을 제공한다.
Redis 에서 제공하는 RDB 와 AOF 기능을 정리해보자.
- RDB
'RDBMS' 가 아니라, 단순히 Redis 의 메모리 스냅샷을 파일로 저장한 파일 확장자
이다.
Redis 는 지속적인 서비스와 RDB 저장을 위해, fork 를 통해 자식 프로세스를 생성한다.
이 RDB 저장을 위한 명령으로 SAVE 와 BGSAVE 가 있다.
SAVE는, 모든 작업을 멈추고 현재 메모리 상태에 대한 RDB 파일을 생성한다.
BGSAVE는, 자식 프로세스에서 RDB 파일을 생성한다. - AOF (Append Only File)
클라이언트가 Redis 에 업데이트 관련 명령을 요청하면, Redis 는 해당 명령을 AOF 에 저장한다.
그리고, 실제로 해당 명령을 실행해서 메모리 내용을 변경한다.
RDB 를 저장할 때 fork 를 사용하여 문제가 되는 경우
이전에는 OS 가 자식 프로세스를 생성하면, 부모 프로세스의 메모리를 모두 자식 프로세스에 복사해야했다.
예를 들면, 부모 프로세스가 10 GB 메모리를 사용 중이라면, 자식 프로세스를 생성할 때 10 GB 메모리가 필요했다.
그런데 OS 가 발전하면서, COW (Copy On Write) 기술이 개발되었다. 그래서,
최초에 fork 로 자식 프로세스가 생성되면 부모 프로세스와 자식 프로세스는 같은 메모리를 공유한다.
그리고, 자식 프로세스에 write 가 발생할 때마다, 공유하는 해당 데이터는 자식 프로세스에 복사된다.write 작업이 많아지면
부모 페이지에 있는 모든 페이지가 자식 프로세스에 복사되어 사용 메모리 양이 결국 두 배가 된다.
Read 는 가능한데 Write 만 실패하는 경우
Redis 기본 설정상, RDB 저장이 실패하면 해당 장비에 이상이 있다고 판단하여 write 명령을 처리하지 않고, 데이터가 변경되지 않도록 관리한다.
즉, read 가능하지만 write 가 불가능한 경우이다.
그렇다면, RDB 생성이 실패하는 경우는 언제가 있을까 ?
- RDB 저장할 수 있는 정도의 디스크 여유가 없는 경우
- 실제 디스크 고장
- 메모리 부족으로 자식 프로세스를 생성하지 못한 경우
- 강제적으로 자식 프로세스를 종료시킨 경우
Redis 복제 : master/slave
redis 복제 모델은 master/slave 구조이다. 주의할점은, 하나의 slave 는 오직 하나의 master 만 가질 수 있다.
복제 과정은 다음과 같다.
- slave 에서 slaveof 명령을 통해, master 서버를 설정
- master 는 복제를 위해 RDB 생성 후에, 슬레이브에 전송
- 슬레이브는 RDB 를 로드하고 나머지 차이에 대한 명령을 마스터에서 전달받아 복제 완료
master 장애시, slave 모든 내용이 사라지는 경우
- slave 는 master 의 상태를 지속적으로 체크한다.
- master 와의 연결 상태 이상을 slave 가 감지한다.
- slave 에서 master 와의 연결 상태가 복원된 것을 확인한다.
- 이제, slave 는 master 의 모든 내용을 가져온다.
- 그런데,
마스터에 장애가 발생해서 master 에 데이터가 하나도 없으면 slave 의 모든 내용은 사라진다.
왜 모든 내용이 사라질까 ?
왜냐하면, 슬레이브는 마스터와 동일한 데이터를 유지하기 위해 RDB 를 읽어들이기 전에 현재 자신의 데이터를 모두 삭제하고 마스터와 싱크
를 맞추기 때문이다.
그래서, 마스터에 장애가 발생하면 슬레이브에 slaveof no one 명령을 줘서
더 이상 슬레이브로 동작하지 않도록 하여, 현재까지의 모든 데이터를 보존할 수 있다.
복제 시, RDB 는 무조건 백그라운드로 생성
복제를 하면, 사용자 설정과 무관하게 슬레이브에 전달할 RDB 를 만들기 위해 fork 를 해서 RDB 를 생성한다.
따라서, 하나의 프로세스가 너무 많은 메모리를 사용하지 않도록 나눌 필요가 있다.
Redis HA, Sentinel
master/slave 형태로 서비스 하기 위해서는, 다음과 같은 기능이 필요하다.
- 마스터 장애 판별
- 슬레이브를 마스터로 승격
- 해당 작업 내용을 클라이언트에게 통지
위와 같은 기능을 Sentinel 이라는 데몬을 이용해 처리할 수 있다.
다만, 3번 같은 경우 Sentinel 에서 이미 장애 발생한 마스터에 접속한 클라이언트를 알 수 없으므로, 해당 알림을 원하는 클라이언트는 Redis Pub/Sub 으로 Sentinel 에 등록해야한다.
즉, 마스터에 장애가 발생하면 처리 순서는 다음과 같다.
- Sentinel 은 슬레이브 중에 한대를 선택해서 마스터로 승격
- Sentinel 은 클라이언트에 Pub/Sub 으로 통지
- 클라이언트가 connection 을 승격된 마스터로 변경
Redis 운영 관리 <강대명>