Redis
Redis 는 데이터를 메모리에 두고 쓰는 저장소입니다. 키 하나에 값 하나를 넣고 꺼냅니다. 값은 문자열만이 아니라 리스트나 집합 같은 자료구조일 수 있습니다. 디스크에 쓰는 일은 선택 사항이라서, 켜고 끄고 세기를 고를 수 있습니다.
쉽고 빠른 이해
자주 꺼내 쓰는 데이터를 메모리에 얹어 두고 키로 넣고 꺼내는 저장소입니다. 로그인한 사용자의 장바구니를 키 하나에 담아 두고 요청마다 그 키만 읽는 식입니다.
왜 이렇게 하나. 같은 것을 관계형 데이터베이스에서 읽으면 요청마다 5~20밀리초가 붙고, 점수 순으로 줄 세우는 일에는 테이블 전체를 정렬해야 합니다. 동시 사용자가 수천이면 그 왕복이 병목이 됩니다.
어떻게 도나.
- 값의 모양을 고릅니다. 문자열·리스트·해시·집합·정렬집합 중 무엇으로 두느냐가 붙는 명령을 정합니다.
- 요청을 한 줄로 세워 하나씩 처리합니다. 앞 요청이 끝나야 뒤 요청이 시작됩니다.
- 디스크에 남길지 말지를 고릅니다. 아예 끄고 메모리만 쓸 수도 있습니다.
대가. 죽으면 마지막으로 디스크에 맞춘 시점 이후가 사라집니다. 설정에 따라 1초치이기도 하고 몇 분치이기도 합니다. 트랜잭션을 되돌리는 기능이 없고, 오래 걸리는 명령 하나가 뒤의 모든 요청을 세웁니다. 메모리 한도에 닿으면 새 데이터를 쓰는 명령이 오류로 떨어집니다.
상세
Redis 는 자료구조를 메모리 안에 들고 있다가 내줍니다. maxmemory 문서는 그 자리를 캐시 데이터에 쓸 메모리의 최댓값이라고 적습니다. 반대편에 지속성이 있습니다. Redis 지속성 문서는 지속성을 SSD(Solid State Drive, 고체 상태 드라이브) 같은 내구성 있는 저장 장치에 데이터를 쓰는 일이라고 정의합니다. 같은 문서가 드는 방식은 둘입니다. 정해진 간격마다 데이터셋의 특정 시점 스냅샷을 뜨거나, 서버가 받은 쓰기 연산을 파일에 계속 덧붙이는 것입니다. 그리고 그 지속성을 아예 끄는 선택지를 나란히 둡니다. 캐싱으로 쓸 때 가끔 그렇게 한다고 적습니다. 메모리가 본체이고 디스크는 옵션이라는 뜻입니다.
flowchart TD
C["클라이언트"]
subgraph MEM["메모리 · 본체"]
K["키 하나에 값 하나"]
end
subgraph DSK["디스크 · 옵션"]
SNAP["특정 시점 스냅샷"]
LOG["쓰기 연산을 덧붙인 파일"]
end
C --> K
K -. "켜고 끌 수 있다" .-> SNAP
K -. "켜고 끌 수 있다" .-> LOG
클라이언트가 닿는 자리는 메모리입니다. 디스크로 내려가는 두 갈래는 그 아래에 선택으로 붙습니다. 둘 다 끄면 데이터가 사는 자리는 메모리뿐입니다.
공식 레포 README 는 Redis 를 캐시이자 자료구조 서버이자 문서·벡터 질의 엔진이라고 소개합니다. 그 아래로 캐시, 분산 세션 저장소, 자료구조 서버, NoSQL 데이터 저장소, 보조 인덱스 및 검색·질의 엔진, 분산 이벤트 저장소이자 스트림 처리 플랫폼이자 메시지 브로커를 늘어놓습니다. 하나의 물건이 여러 자리를 겸합니다.
값의 모양
데이터 타입 문서의 첫 문장은 "Redis is a data structure server" 입니다. 문자열 하나만 담는 키-값 저장소가 아닙니다. 캐싱부터 큐잉, 이벤트 처리까지 다양한 문제를 풀도록 네이티브 자료구조 모음을 제공한다고 적습니다.
| 타입 | 문서가 적는 모양 |
|---|---|
| 해시 | 필드-값 쌍의 모음으로 모델링된 레코드 타입. 파이썬 딕셔너리, 자바 HashMap, 루비 해시를 닮았습니다 |
| 리스트 | 삽입 순서로 정렬된 문자열들의 리스트 |
| 집합 | 유일한 문자열들의 순서 없는 모음. 추가·제거·존재 확인이 원소 수와 무관하게 O(1) 입니다 |
| 정렬집합 | 각 문자열에 딸린 점수로 순서를 유지하는, 유일한 문자열들의 모음 |
| 스트림 | 추가 전용 로그처럼 동작하는 자료구조. 이벤트를 일어난 순서로 기록해 두었다가 처리 쪽으로 배분합니다 |
값의 모양이 곧 명령의 모양입니다. 리스트에는 LPUSH 가 붙고 정렬집합에는 ZADD 가 붙습니다.
어떤 자료구조를 고르느냐가 애플리케이션 쪽에서 무엇을 직접 구현하지 않아도 되느냐를 정합니다.
한 번에 한 요청
지연 문제 해결 문서는 Redis 가 대체로 단일 스레드 설계를 쓴다고 적습니다. 프로세스 하나가 멀티플렉싱 기법으로 모든 클라이언트 요청을 처리합니다. 주어진 순간에 요청 하나만 처리할 수 있으므로 모든 요청이 순차적으로 처리됩니다. 문서는 이것이 Node.js 의 동작 방식과 매우 비슷하다고 적습니다.
"대체로" 라고 적은 이유도 같은 문서에 있습니다. Redis 2.4 부터 일부 오래 걸리는 I/O(Input/Output, 입출력) 작업을 백그라운드에서 처리하려고 스레드를 씁니다. 주로 디스크 I/O 입니다. 그래도 Redis 가 모든 요청을 단일 스레드로 처리한다는 사실은 바뀌지 않는다고 못 박습니다.
이 설계는 트랜잭션의 성질로도 드러납니다. 트랜잭션 문서는 트랜잭션 안의 모든 명령이 직렬화되어 순차적으로 실행된다고 적습니다. 다른 클라이언트가 보낸 요청은 트랜잭션 실행 중간에 처리되는 일이 결코 없습니다.
포기한 것
매 쓰기의 내구성
RDB(Redis Database)는 지정한 간격으로 데이터셋의 특정 시점 스냅샷을 뜹니다. 지속성 문서는 RDB 의 단점을 스스로 적습니다. Redis 가 멈췄을 때 데이터 손실 가능성을 최소화해야 한다면 RDB 는 맞지 않습니다. 세이브 포인트를 여러 개 설정할 수는 있지만 보통 5분 이상 간격으로 스냅샷을 만들게 됩니다. 정상 종료 없이 어떤 이유로든 멈추면 마지막 몇 분치 데이터를 잃을 각오를 해야 한다고 적습니다.
AOF(Append Only File)는 서버가 받은 모든 쓰기 연산을 로그로 남깁니다. 그 대신 디스크에 몇 번 맞출지를 고르게 합니다.
appendfsync |
문서가 적는 값 |
|---|---|
always |
새 명령이 AOF 에 덧붙을 때마다 fsync. 매우 느립니다. 매우 안전합니다 |
everysec |
1초에 한 번 fsync. 재해가 나면 1초치 데이터를 잃을 수 있습니다 |
no |
fsync 하지 않고 운영체제 손에 맡깁니다. 리눅스는 보통 30초마다 flush 하지만 커널 튜닝에 달렸습니다 |
everysec 가 팔아치운 것은 1초입니다. 매 쓰기마다 디스크에 맞추는 비용을 안 치르기로 한 것입니다.
RDB 에는 다른 값도 붙습니다. 자식 프로세스로 디스크에 쓰려고 자주 fork() 해야 합니다. 데이터셋이
크면 fork() 에 시간이 걸릴 수 있고, 데이터셋이 아주 크고 CPU(Central Processing Unit, 중앙처리장치)
성능이 좋지 않으면 Redis 가 몇
밀리초에서 심지어 1초까지 클라이언트에게 서비스를 멈출 수도 있습니다.
동기 복제
복제 문서는 Redis 가 기본으로 비동기 복제를 쓴다고 적습니다. 마스터는 명령이 복제본에서 처리되기를 매번 기다리지 않습니다. 복제본이 받은 데이터 양을 주기적으로 비동기 확인해 줄 뿐입니다.
sequenceDiagram
participant 클라이언트
participant 마스터
participant 복제본
클라이언트->>마스터: 쓰기
마스터-->>클라이언트: 완료
마스터->>복제본: 뒤이어 전달
복제본-->>마스터: 받은 양을 주기적으로 확인
완료 응답이 복제본 도착보다 앞에 옵니다. 그 사이에 페일오버가 나면 클라이언트가 완료로 받은 쓰기가 남지 않을 수 있습니다.
WAIT 명령으로 특정 데이터의 동기 복제를 요청할 수는 있습니다. 다만 WAIT 는 지정한 수만큼 확인된
복사본이 다른 인스턴스에 있다는 것만 보장하고, Redis 인스턴스 집합을 강한 일관성을 가진 CP(Consistency and Partition tolerance, 일관성과 분할 내성) 시스템으로
바꾸지는 않습니다. 확인된 쓰기도 페일오버 중에 사라질 수 있습니다. Redis 지속성의 정확한 설정에
달렸습니다. 문서는 그래도 WAIT 가 장애 후 쓰기를 잃을 확률을 특정한 유발하기 어려운 실패 양상까지
크게 줄여준다고 적습니다.
트랜잭션 롤백
트랜잭션 문서는 한 줄로 못 박습니다. Redis 는 트랜잭션 롤백을 지원하지 않습니다. 롤백을 지원하면 Redis 의 단순성과 성능에 큰 영향을 주기 때문이라고 적습니다.
얻은 것은 앞에서 본 격리입니다. 트랜잭션 안의 모든 명령이 직렬화되어 순차 실행되고, 다른 클라이언트의 요청이 실행 중간에 끼어들지 않습니다. 되돌리기를 버리고 끼어들지 않음을 가져간 것입니다.
클러스터에서의 자유로운 다중 키 연산
클러스터 명세는 구현한 부분집합을 밝힙니다. Redis Cluster 는 비분산 판에 있는 단일 키 명령을 전부 구현합니다. 집합 합집합·교집합 같은 복잡한 다중 키 연산은 연산에 관련된 키가 전부 같은 슬롯으로 해시되는 경우에 한해 구현됩니다.
해시 태그가 그 제약을 다루는 손잡이입니다. 특정 키들을 같은 해시 슬롯에 저장되도록 강제하는
개념입니다. MSET {user:1000}.name Angela {user:1000}.surname White 가 명세에 실린 유효한 예입니다.
다만 수동 리샤딩 중에는 다중 키 연산이 한동안 사용 불가능해질 수 있습니다. 단일 키 연산은 항상
사용 가능합니다.
발행구독의 재전송
발행구독 문서는 Redis 의 Pub/Sub 이 at-most-once 전달 의미를 갖는다고 적습니다. 이름 그대로 메시지는 전달된다면 한 번 전달됩니다. Redis 서버가 메시지를 보낸 뒤에는 다시 보낼 가능성이 없습니다. 구독자가 오류나 네트워크 끊김 때문에 메시지를 처리하지 못하면 그 메시지는 영영 사라집니다.
문서는 더 강한 전달 보장이 필요하면 Redis 스트림을 알아보라고 안내합니다. 스트림의 메시지는 저장되며 at-most-once 와 at-least-once 전달 의미를 모두 지원합니다.
예시
Django 의 캐시 백엔드
CACHES = {
"default": {
"BACKEND": "django.core.cache.backends.redis.RedisCache",
"LOCATION": "redis://127.0.0.1:6379",
}
}
BACKEND 를 django.core.cache.backends.redis.RedisCache 로, LOCATION 을 Redis 인스턴스를
가리키는 URL(Uniform Resource Locator, 통합 자원 위치 지정자)로 두면 됩니다. Django 문서는 Redis
파이썬 바인딩이 따로 필요하다고 적습니다. Django 가
네이티브로 지원하는 바인딩은 redis-py 입니다. hiredis-py 패키지 설치도 권장합니다.
Celery 의 브로커와 결과 백엔드
app.conf.broker_url = 'redis://localhost:6379/0'
app.conf.result_backend = 'redis://localhost:6379/0'
Celery 문서는 pip install -U "celery[redis]" 로 Celery 와 의존성을 한 번에 설치한다고 적습니다.
설정은 Redis 데이터베이스 위치를 적는 것으로 끝납니다. 태스크의 상태와 반환값까지 Redis 에 저장하려면
result_backend 를 함께 적습니다. Redis 의 기본 visibility timeout 은 1시간입니다.
Sidekiq 이 Redis 를 고른 이유
Sidekiq 은 모든 작업 데이터와 운영 데이터를 Redis 에 저장합니다. FAQ(Frequently Asked Questions, 자주 묻는 질문)는 다른 저장소를 지원하지 않는 이유를 직접 적습니다. Redis 가 그 위에 기능을 쌓아 올릴 자료구조 한 벌을 준다는 것입니다. 저장소를 추상화하려면 그 구조들을 API(Application Programming Interface, 응용 프로그램 인터페이스)로 추상화하고, 시스템마다 어댑터를 쓰고, 여러 판에서 테스트하고, 각 시스템의 기능·성능 한계를 문서로 남겨야 한다고 적습니다. Sidekiq 은 Redis 가 제공하는 자료구조를 전부 씁니다. 리스트, 정렬집합, 해시입니다.
메모리 상한과 축출 정책 한 벌
maxmemory 100mb
maxmemory-policy allkeys-lru
maxmemory 는 캐시 데이터에 쓸 메모리 최대량을 정합니다. 시작할 때 redis.conf 에 적거나, 런타임에
redis-cli 로 CONFIG SET maxmemory 100mb 를 씁니다. maxmemory-policy 는 그 한도에 닿았을 때 쓸
축출 정책을 고릅니다. allkeys-lru 는 가장 오래 안 쓰인 키를 버립니다. volatile-ttl 은 만료가 붙은
키 중 남은 TTL(Time To Live, 생존 시간)이 가장 짧은 것을 버립니다.
명령 한 줄
SET key value [NX | XX | IFEQ ifeq-value | IFNE ifne-value |
IFDEQ ifdeq-digest | IFDNE ifdne-digest] [GET] [EX seconds |
PX milliseconds | EXAT unix-time-seconds |
PXAT unix-time-milliseconds | KEEPTTL]
GET key
EXPIRE key seconds [NX | XX | GT | LT]
SET 은 키가 문자열 값을 갖게 합니다. 복잡도 O(1) 이고 1.0.0 부터 있습니다. 키가 이미 값을 갖고
있으면 타입과 무관하게 덮어씁니다. 성공한 SET 에서는 그 키에 붙어 있던 TTL 이 버려집니다.
GET 은 키의 값을 돌려줍니다. 키가 없으면 nil 을 돌려줍니다. 키에 저장된 값이 문자열이 아니면
오류를 돌려줍니다. GET 은 문자열 값만 다루기 때문입니다. EXPIRE 는 키에 타임아웃을 겁니다.
타임아웃이 지나면 키가 자동으로 삭제됩니다. 타임아웃이 붙은 키를 Redis 용어로 흔히 volatile 이라고
부릅니다.
사용처
세션 저장. 상태 없는 애플리케이션 서버들 사이에서 사용자별 세션 상태를 공유해야 할 때 씁니다. 로그인 컨텍스트, 장바구니, 선호 같은 것들입니다. sticky session 이나 데이터베이스 왕복 없이 공유하는 것이 목적입니다. 세션을 앱 서버마다 두면 sticky routing 이 필요해지고 그것이 핫스팟을 만들며 페일오버를 불가능하게 만듭니다. 세션 읽기를 관계형 데이터베이스로 옮기면 요청마다 5~20ms 가 붙습니다. 동시 사용자가 수천이면 세션 읽기가 커넥션 풀을 지배합니다. 실제로는 세션 하나를 Redis 해시 하나로 저장하고 세션 ID 마다 키에 만료를 걸어 둡니다. 외부 정리 작업 없이 비활성 세션이 치워집니다.
속도 제한. 분산된 서비스 인스턴스들에 걸쳐 사용자별·API별·테넌트별 요청 할당량을 일관되게 강제해야 할
때 씁니다. 프로세스 로컬 카운터는 로드 밸런서 뒤에서 깨집니다. 같은 클라이언트가 다른 인스턴스를 때려
제한을 우회합니다. 요청 경로 위에 앉아도 의미 있는 지연을 더하지 않을 만큼의 중앙 저장소가 필요합니다.
INCR 과 EXPIRE 가 원자적 고정 윈도 카운터와 시간 윈도 자동 정리를 줍니다.
작업 큐. 이메일 발송, 결제 처리, 이미지 처리, ML(Machine Learning, 기계 학습) 추론, 웹훅 같은 배경 작업을 사용자 요청 경로에서
떼어내 워커 풀에 분배할 때 씁니다. 인프로세스 큐는 크래시에 작업을 잃고 여러 워커나 서비스에 일을
분배하지 못합니다. 데이터베이스의 대기 행을 폴링하면 주 데이터베이스에 상시 부하가 생기고 같은 행을
두고 다투는 워커들 사이에 핸드오프 경쟁이 생깁니다. RabbitMQ·Kafka·SQS 같은 전용 메시지 브로커를
더하는 것은 배포하고 감시하고 비용을 치를 인프라를 하나 더 두는 일입니다. LPUSH 와
BRPOPLPUSH(또는 BLMOVE)가 원자적 적재와 블로킹 획득을 줍니다. 워커가 한 번의 왕복으로 작업을
꺼내면서 처리 중 리스트에 등록합니다. Sidekiq 과 Celery 가 이 자리에 Redis 를 씁니다.
순위표. 점수가 계속 바뀌는 개체를 실시간으로 순위 매겨 사용자에게 보여줘야 할 때 씁니다. 플레이어,
상품, 판매자, 종목 같은 것들입니다. 관계형 데이터베이스에서 한 개체의 순위를 계산하려면 전체 테이블에
ORDER BY 가 필요합니다. 잘해야 O(N) 이고 수백만 행이면 질의 시간이 초 단위로 갑니다. 결과를 캐시해도
소용이 없습니다. 점수가 사용자 행동마다 바뀌므로 TTL 기반 캐시는 즉시 낡거나 만료 때 썬더링 허드 성
갱신을 부릅니다. 정렬집합이 순위 순서를 자동으로 유지합니다. ZADD·ZRANGE·ZREVRANK 가 집합
크기와 무관하게 O(log N) 으로 돕니다.
발행구독. 알림, 채팅 메시지, 캐시 무효화 신호, UI(User Interface, 사용자 인터페이스) 갱신 같은 실시간 이벤트를 하나 이상의 생산자에서
다수 소비자로 느슨하게 뿌려야 할 때 씁니다. Kafka·RabbitMQ 같은 완전한 메시지 브로커는 메시지 지속성,
재생, 전달 보장이 필요 없을 때는 운영 부담과 지연이 과합니다. 발행자가 PUBLISH channel payload 를
부르면 Redis 가 그 채널을 구독 중인 모든 클라이언트에게 발행된 순서대로 뿌립니다. 구독자는
SUBSCRIBE channel 이나 PSUBSCRIBE pattern 으로 관심을 등록하고, 그 연결은 같은 소켓으로 메시지를
밀어주는 구독 전용 모드로 바뀝니다. Socket.IO 의 Redis 어댑터가 이 자리에 앉습니다. 여러 클라이언트로
나가는 패킷을 Redis 채널에 발행해 클러스터의 다른 Socket.IO 서버들이 받게 합니다. Socket.IO 문서는
새로 만드는 것이라면 Redis 7.0 의 sharded Pub/Sub 을 활용하는 sharded 어댑터를 권장합니다.
운영
maxmemory 와 noeviction
메모리가 본체인 물건이라 상한을 어디에 두었느냐가 제일 먼저 아픕니다. maxmemory 를 0 으로 두면
데이터셋의 메모리를 제한하지 않겠다는 뜻입니다. 64비트 시스템에서는 이것이 기본 동작입니다. 32비트
시스템은 암묵적으로 3GB 제한을 씁니다. maxmemory-policy 의 기본값은 noeviction 입니다.
flowchart TD
A["데이터를 더하는 명령이 들어온다"] --> B{"사용 메모리가 maxmemory 를 넘나"}
B -- 아니오 --> C["그대로 처리한다"]
B -- 예 --> D{"정책이 noeviction 인가"}
D -- 예 --> E["쓰기 명령에 오류로 응답한다"]
D -- 아니오 --> F{"축출할 만한 키가 있나"}
F -- 예 --> G["한도 아래로 내려갈 때까지 키를 버린다"]
F -- 아니오 --> E
클라이언트가 캐시에 데이터를 더하는 새 명령을 실행할 때마다 Redis 가 메모리 사용량을 확인합니다.
한도보다 크면 고른 축출 정책에 따라 총 사용량이 한도 아래로 내려갈 때까지 키를 버립니다.
noeviction 이면 키를 버리지 않습니다. 대신 새 데이터를 캐시하는 명령을 실행하려 할 때 서버가 오류를
돌려줍니다. 데이터베이스가 복제를 쓴다면 이 조건은 primary 에만 적용됩니다. 기존 데이터를 읽기만 하는
명령은 정상적으로 동작합니다.
redis.conf 는 같은 것을 명령 이름으로 적습니다. 정책에 따라 키를 제거하지 못하거나 정책이
noeviction 이면 Redis 는 SET·LPUSH 처럼 메모리를 더 쓰는 명령에 오류로 응답하기 시작하고,
GET 같은 읽기 전용 명령에는 계속 응답합니다. 어떤 정책이든 축출하기에 적합한 키가 없을 때도 같은
일이 벌어집니다. 새 키를 만들거나 데이터를 더하거나 기존 키를 고치는 연산들입니다. redis.conf 가
드는 예는 SET·INCR·HSET·LPUSH·SUNIONSTORE·SORT(STORE 인자 때문)·EXEC(메모리를
요구하는 명령이 트랜잭션에 들어 있으면)입니다. volatile- 로 시작하는 정책들은 만료가 붙은 키가
하나도 없으면 noeviction 처럼 동작합니다.
오래 걸리는 명령 하나
sequenceDiagram
participant 클라이언트A
participant 클라이언트B
participant Redis
클라이언트A->>Redis: 큰 집합 두 개의 SUNION
클라이언트B->>Redis: GET
Note over Redis: 단일 스레드라 순차 처리
Redis-->>클라이언트A: 결과
Redis-->>클라이언트B: 결과
단일 스레드의 결과입니다. 한 요청이 처리에 오래 걸리면 다른 모든 클라이언트가 그 요청이 끝나기를
기다립니다. GET·SET·LPUSH 같은 일반 명령을 실행할 때는 전혀 문제가 되지 않습니다. 상수 시간에,
그것도 아주 짧은 시간에 실행되기 때문입니다. 문제는 많은 원소를 다루는 명령입니다. 문서는
SORT·LREM·SUNION 등을 듭니다. 예를 들어 큰 집합 두 개의 교집합을 구하는 것은 상당한 시간이 걸릴
수 있습니다. 볼 자리는 명령의 복잡도 표기입니다. 상수 시간이 아닌 명령이 요청 경로에 있는지를 봅니다.
KEYS
지연 문제 해결 문서는 오래 걸리는 명령이 만드는 지연의 아주 흔한 원인 하나를 이름으로 못 박습니다.
프로덕션 환경에서 KEYS 명령을 쓰는 것입니다. KEYS 는 문서에 적힌 대로 디버깅 목적으로만 써야
합니다.
KEYS 명령 문서도 같은 말을 합니다. 시간 복잡도는 O(N) 이지만 상수는 꽤 작습니다. 예를 들어 보급형
노트북에서 도는 Redis 는 100만 키 데이터베이스를 40밀리초에 훑을 수 있습니다. 그래도 프로덕션
환경에서는 극도로 주의해서 쓰라고 적습니다. 큰 데이터베이스에 실행하면 성능을 망칠 수 있습니다.
디버깅과 키스페이스 레이아웃 변경 같은 특수 작업용 명령입니다. 일반 애플리케이션 코드에서는 쓰지
말라고 적습니다. 키스페이스의 일부에서 키를 찾는 방법이 필요하면 SCAN 이나 집합을 쓰는 것을
고려하라고 안내합니다. Redis 2.8 부터 키스페이스와 큰 컬렉션을 점진적으로 순회하는
SCAN·SSCAN·HSCAN·ZSCAN 이 있습니다.
토폴로지 고르기
Redis 는 여러 토폴로지를 제공합니다. Sidekiq 위키가 그중 둘을 이렇게 갈라 적습니다. Redis Sentinel 은 장애 내성을 주고 primary 장애 시 복제본으로 페일오버합니다. Redis Cluster 는 여러 인스턴스에 걸친 멀티마스터 키스페이스입니다.
flowchart TD
subgraph SEN["Redis Sentinel"]
P["primary"]
R1["복제본"]
R2["복제본"]
P --> R1
P --> R2
end
subgraph CLU["Redis Cluster"]
M1["인스턴스 · 키스페이스의 일부"]
M2["인스턴스 · 키스페이스의 일부"]
M3["인스턴스 · 키스페이스의 일부"]
end
키스페이스가 놓이는 자리가 다릅니다. Sentinel 에서는 같은 키스페이스 한 벌이 복제본마다 통째로 있습니다. Cluster 에서는 키스페이스가 인스턴스들에 나뉘어 있습니다.
같은 위키가 Cluster 를 안 고른 이유를 적습니다. Cluster 는 캐시처럼 여러 머신에 고르게 흩어질 수 있는 대규모 데이터셋을 위해 설계되었습니다. Sidekiq 에는 적절하지 않다고 적습니다. Sidekiq 에는 끊임없이 바뀌는 아주 뜨거운 키가 몇 개 있고 그것이 큐이기 때문입니다. Cluster 는 작업 시스템을 빠르고 일관되게 유지하는 데 필요한 고성능 트랜잭션을 보장할 수 없습니다. 위키는 Sentinel 을 쓰거나 페일오버가 내장된 Redis SaaS(Software as a Service, 서비스형 소프트웨어)를 쓰라고 권합니다. 워크로드의 키 분포가 고른지 뜨거운 키 몇 개에 몰리는지가 이 선택의 기준입니다.
관련 항목
Redis 를 가리키는 다른 이름
캐싱 · NoSQL · 세션 · 인덱스 · 검색 · 메시지
지속성을 이루는 구성 요소
장애·복제를 다루는 배포 형태
Redis Sentinel · Redis Cluster · 복제 · 페일오버
트랜잭션이 지키거나 포기하는 성질
클러스터 다중 키 연산에 적용되는 규칙
태그 · 해시 슬롯 · 리샤딩
발행구독이 다루는 전달과 신호
캐시가 낡아 비워지는 규칙
값을 표현하는 자료 개념
Redis 가 처리하는 워크로드 종류
세션·순위표가 우회하는 병목
관계형 데이터베이스 · 커넥션 풀 · 로드 밸런서
fork 비용이 걸리는 하부 자원
메시지 브로커 대안
얹는 제품
Sidekiq · Django · Celery · Socket.IO
다른 이름: redis · 레디스