Notice
Recent Posts
Recent Comments
Link
«   2026/03   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31
Archives
Today
Total
관리 메뉴

채움의 길

Redis 알아보기 본문

지식 채우기/개인 공부

Redis 알아보기

chae-um 2026. 1. 23. 00:06

 

 

https://redis.io/

1. Redis 캐시로 사용하기

캐시의 정의 및 유용성

캐시(Cache)란 사용자의 입장에서 데이터의 원본 소스보다 더 빠르고 효율적으로 액세스할 수 있는 임시 데이터 저장소를 의미합니다.

캐시가 유용하려면 다음 조건이 충족되어야 합니다.

  • 캐시에 접근하는 것이 원본에 접근하는 것보다 쉽고 빨라야 합니다.
  • 동일한 데이터에 대해 반복적으로 액세스하는 상황이 많을 때 유용하며, 데이터의 재사용 횟수가 한 번 이상이어야 의미가 있습니다.
  • 잘 변하지 않는 데이터일수록 캐시 사용이 효율적입니다.

Redis는 사용이 간편하고(Key-Value 형태), 모든 데이터를 메모리에 올리는 인메모리 데이터 스토어이므로 매우 빠릅니다.

평균 읽기 및 쓰기 속도가 1ms 미만이며, 초당 수백만 건의 작업이 가능합니다. 빠른 처리 속도는 지연시간 감소와 처리량 증가로 이어집니다.

캐싱 전략

캐싱 전략은 데이터 유형과 액세스 패턴을 고려하여 선택해야 합니다.

Look-Aside 전략 (읽기 작업이 많을 때) 

  1. 애플리케이션이 데이터를 찾을 때 캐시에 먼저 확인합니다.
  2. 캐시에 데이터가 있으면 캐시에서 데이터를 가져오는 작업을 반복합니다.
  3. 캐시에 키가 없으면(Cache Miss) DB에 접근하여 데이터를 가져온 뒤 다시 Redis에 저장합니다.
  4. 캐시에 찾는 데이터가 없을 때만 입력되므로 Lazy Loading이라고도 불립니다.
  5. 캐시 미스 발생 시 성능 저하를 막기 위해 미리 DB에서 캐시로 데이터를 밀어 넣는 Cache Warming 작업을 할 수 있습니다. (예: 티켓링크에서 상품 오픈 전 정보 사전 적재)

Look-Aside 전략의 장단점

  • 장점 : Redis가 다운되어도 DB에서 데이터를 가져올 수 있어 즉각적인 장애로 이어지지 않습니다.
  • 단점 : 캐시 미스 발생 시 모든 커넥션이 DB로 몰려 DB에 갑자기 많은 부하가 발생할 수 있습니다.

데이터 쓰기 전략

Write Around 방식

  • 모든 데이터는 DB에만 저장됩니다.
  • 캐시 미스가 발생한 경우에만 캐시로 데이터를 끌어옵니다.
  • 단점: 캐시 내 데이터와 DB 내 데이터가 다를 수 있습니다.

Write-Through 전략

  • DB에 데이터를 저장할 때 캐시에도 함께 저장합니다.
  • 장점: 캐시는 항상 최신 정보를 가집니다.
  • 단점: 저장 시 두 단계 스텝을 거쳐 상대적으로 느리며, 재사용되지 않을 데이터도 캐시에 저장되어 리소스 낭비가 될 수 있습니다.

Expire Time 설정: 저장하는 데이터가 재사용되지 않을 수 있으므로, 보관 기간을 의미하는 Expire Time을 설정하는 것이 좋습니다.


2. Redis 데이터 타입 야무지게 활용하기

제공되는 주요 데이터 타입 개요

  • String : 가장 기본적인 타입이며, SET 커맨드로 저장되는 모든 데이터는 String 형태입니다.
  • Bitmap : String의 변형으로, Bit 단위 연산이 가능합니다.
  • List : 데이터를 순서대로 저장하며, 큐(Queue)로 사용하기 적절합니다.
  • Hash : 하나의 키 안에 여러 개의 필드와 밸류 쌍으로 데이터를 저장합니다.
  • Set : 중복되지 않은 문자열의 집합입니다.
  • Sorted Set : Set처럼 중복되지 않은 값을 저장하지만, 모든 값은 Score라는 숫자 값으로 정렬됩니다. Score가 같으면 사전 순으로 정렬됩니다.
  • HyperLogLogs : 굉장히 많은 데이터를 다룰 때 주로 사용되며, 중복되지 않는 값의 개수를 카운트할 때 사용됩니다.
  • Stream: 로그를 저장하기 가장 좋은 자료구조입니다.

카운팅 상황별 활용 비교

String의 Increment 함수 사용

  • 키 하나를 만들어 카운팅할 때마다 1씩 증가시키는 가장 쉬운 방법입니다.
  • INCR 함수로 1 증가, INCREMENT BY 함수로 지정된 값만큼 증가시킬 수 있습니다.

Bit 연산 사용 (Bitmap)

저장 공간을 많이 절약할 수 있습니다.

  • SETBIT으로 Bit를 설정하고 BITCOUNT로 1로 설정된 값을 카운팅합니다.
  • 제약: 모든 데이터를 정수로 표현할 수 있어야 하며, User ID 같은 0 이상의 정수값일 때만 사용 가능합니다.
  • 예시: 오늘 접속한 유저 수를 셀 때, 날짜 키를 만들고 유저 ID에 해당하는 Bit를 1로 올립니다. (천만 명 유저가 1.2MB 차지)

HyperLogLogs 사용

  • 모든 String 데이터 값을 유니크하게 구분할 수 있으며, 대량의 데이터를 카운팅할 때 Set보다 적절합니다.
  • 저장되는 데이터 개수에 상관없이 모든 값이 12KB로 고정되어 저장됩니다.
  • PFADD 커맨드로 데이터를 저장하고, PFCOUNT 커맨드로 유니크 개수를 조회합니다.
  • PFMERGE 커맨드를 사용하여 일별로 저장된 데이터를 취합할 수 있습니다.
  • 제약: 한번 저장된 값은 다시 불러올 수 없어 데이터 보호 목적으로도 적절합니다.
  • ex. 웹사이트 방문 IP 개수, 크롤링한 URL 개수, 검색 엔진의 유니크 단어 개수 등 크고 Unique한 값 계산에 적합합니다.

메시징 방법 활용

List를 메시지 큐로 사용

  • List는 메시지 큐로 사용하기 적절하며, 자체적으로 Blocking 기능을 제공하여 불필요한 Polling을 막을 수 있습니다.
    • Blocking 예시: Client A가 BRPOP으로 데이터를 꺼내려 대기 중일 때, Client B가 값을 넣어주면 Client A가 즉시 값을 확인할 수 있습니다.
  • LPUSHX나 RPUSHX 커맨드는 키가 있을 때에만 리스트에 데이터를 추가하여 비효율적인 데이터 이동을 막을 수 있습니다.
  • SNS 타임라인 캐싱: 트위터에서 유저 타임라인에 보일 트윗 캐싱 시 RPUSHX를 사용합니다. 자주 이용하는 유저 타임라인에만 데이터를 미리 캐시하고, 자주 사용하지 않는 유저를 위한 비효율적인 데이터 적재를 방지합니다.

Streams 활용 (로그 저장)

  • Streams는 로그를 저장하기 가장 적절한 자료구조입니다.
  • 모든 데이터는 Append-Only 방식으로 저장되며 중간에 데이터가 바뀌지 않습니다.
  • XADD 커맨드로 데이터를 저장하며, ID 값(*로 입력 시 Redis가 자동 할당)은 데이터 저장 시간을 의미합니다.
  • 데이터는 ID 뒤에 Key-Value 쌍으로 저장됩니다 (예: sensor id, 온도).
  • 데이터 읽기 방법: ID 값을 이용한 시간 대역 검색, 새로 들어오는 데이터만 리스닝(tail -f와 유사), 소비자 그룹 개념을 통한 특정 데이터 읽기 등이 가능합니다.
  • Streams는 카프카의 개념을 차용했으며, Redis 공식 문서는 Streams를 카프카를 대체하여 간단하게 사용할 수 있는 자료구조로 소개합니다.

3. Redis에서 데이터를 영구 저장하려면? (RDB vs AOF)

Redis는 인메모리 데이터 스토어이므로 서버 재시작 시 모든 데이터가 유실됩니다.

복제 구조를 사용하더라도 코드 버그나 실수로 인한 데이터 유실 시에는 복원이 불가능하므로, 캐시 이외 용도로 사용 시에는 적절한 데이터 백업이 필요합니다.

영구 저장 방식 두 가지

AOF (Append Only File)

  • 데이터를 변경하는 커맨드가 들어오면 커맨드를 그대로 모두 저장합니다.
  • 데이터가 추가되기만 하므로 대부분 RDB 파일보다 커지며, 주기적으로 압축하여 재작성하는 과정이 필요합니다.
  • 실제 AOF 파일은 Redis 프로토콜 형태로 저장되어 사람이 읽을 수 없습니다.

RDB (Snapshot)

  1. 스냅샷 방식으로 동작하며, 저장 당시의 메모리 데이터를 사진 찍듯 파일로 저장합니다.
  2. RDB는 바이너리 파일 형태로 저장되어 사람이 읽을 수 없습니다.
  3. ex. key1이 a에서 apple로 변경되고 key2가 삭제되어도, RDB에는 key1이 apple인 값만 남습니다.

파일 생성 및 백업 선택 기준

파일 생성

커맨드를 이용해 직접 생성하거나, 원하는 시점에 자동 생성되도록 설정 가능합니다.

  • RDB는 시간 단위로 파일 저장을 설정할 수 있습니다.
  • AOF는 파일의 크기를 기준으로 압축 시점을 지정할 수 있습니다.

선택 기준

  • 캐시로만 사용한다면 이 기능을 사용할 필요가 없습니다.
  • 어느 정도 데이터 손실을 감수할 수 있다면 RDB만 사용해도 되며, redis.conf의 SAVE 옵션(예: SAVE 900 1 - 900초 동안 1개 이상 키 변경 시 재작성)을 적절히 사용해야 합니다.
  • 장애 상황 직전까지 모든 데이터가 보장되어야 한다면 AOF를 사용해야 합니다.
  • AOF의 APPENDFSYNC 옵션이 기본값인 everysecond인 경우, 최대 1초 사이의 데이터는 유실될 가능성이 있습니다.
  • 가장 강력한 내구성이 필요할 경우, RDB와 AOF를 동시에 사용하라고 Redis 공식 문서에서 가이드합니다.

4. Redis 아키텍처 선택 노하우 (Replication vs Sentinel vs Cluster)

Redis 아키텍처는 크게 세 가지로 나눌 수 있으며, 고가용성 기능과 샤딩 필요 여부에 따라 선택 기준이 달라집니다.

 

세 가지 아키텍처 구성

  • Replication 구성 (복제 구성): 마스터와 Replica 노드만 존재하는 간단한 구조입니다.
  • Sentinel 구성: 마스터/ Replica 노드 외에 Sentinel 노드가 추가되어 일반 노드들을 모니터링합니다.
  • Cluster 구성: 최소 세 대의 마스터가 필요하며 샤딩 기능을 제공합니다.

각 구성의 특징 및 HA 기능

Replication  구성

  • 모든 Redis 구조에서 복제는 비동기식으로 동작하며, 마스터는 복제본 전달 여부를 확인하지 않습니다.
  • HA 기능 없음: 마스터 장애 발생 시 수동으로 Replica 노드 접속 끊기, 애플리케이션 연결 설정 변경 및 배포 작업이 필요합니다.

Sentinel 구성

  • Sentinel 이 마스터를 모니터링하다가 마스터가 다운되면 자동으로 페일오버를 발생시켜 기존 Replica 노드가 마스터가 됩니다.
  • 애플리케이션은 Sentinel 노드만 알면 되며, Sentinel 이 변경된 마스터 정보로 연결을 시켜주므로 연결 정보 변경이 필요 없습니다.
  • 구성 조건: Sentinel 프로세스를 추가로 띄워야 하며, Sentinel 은 항상 세 대 이상의 홀수로 존재해야 합니다.
    (예시: 두 대의 서버에 일반 Redis + Sentinel , 최저 사양 서버에 Sentinel 만 구성)

Cluster 구성

  • 데이터가 여러 마스터 노드에 자동 분할 저장되는 샤딩 기능을 제공합니다.
  • 모든 노드가 서로 감시하며 마스터 비정상 시 자동 페일오버를 진행합니다.
  • 최소 세 대 이상의 마스터 노드가 필요하며, Replica 노드를 하나씩 추가하는 것이 일반적입니다.

아키텍처 선택 기준 정리

  1. HA 기능(자동 페일오버) 필요 여부가 첫 번째 질문입니다.
  2. HA가 YES인 경우:
    1. 서비스 확장을 위한 샤딩이 필요하다면 Cluster 구조를 사용합니다.
    2. 샤딩이 필요 없고 HA만 필요하다면 Sentinel 만 사용해도 충분합니다.
  3. HA가 NO인 경우:
    1. 복제 기능이 필요하다면 Replication 구조를 사용합니다.
    2. 복제 기능도 필요 없다면 마스터 하나를 띄운 Stand-Alone 구조를 사용합니다.

5. Redis 운영 꿀팁 + 장애 포인트

싱글 스레드 동작으로 인한 장애 포인트

  • Redis는 싱글 스레드로 동작하므로, 한 사용자가 오래 걸리는 커맨드를 실행하면 나머지 모든 요청이 대기하게 되어 장애가 빈번하게 발생합니다.
  • KEYS 커맨드 사용 금지: 운영 환경에서 실수로 실행될 수 있으므로 사용하지 않는 것을 권장합니다.
    • KEYS는 SCAN으로 대체 가능하며, SCAN은 재귀적으로 키들을 호출할 수 있습니다.
  • Hash나 Sorted Set의 아이템 개수: 키 내부에 아이템이 많아질수록 성능이 저하됩니다. 하나의 키에 최대 100만 개 이상은 저장하지 않도록 키를 적절히 나누는 것이 좋습니다.
  • 데이터 삭제 시 주의: 데이터가 많을 때 DEL로 지우면 키를 지우는 동안 아무 동작도 할 수 없습니다. UNLINK 커맨드를 사용하면 키를 백그라운드로 지워주므로 이를 권장합니다.

장애를 막기 위한 기본 설정값 변경

STOP-WRITES-ON-BGSAVE-ERROR 옵션

  • 기본값은 YES이며, RDB 파일이 정상 저장되지 않았을 때 Redis 로 들어오는 모든 쓰기(write)를 차단하는 기능입니다.
  • 서버 모니터링을 적절히 하고 있다면, 이 기능을 꺼두는 것이 불필요한 장애를 막는 방법입니다.

MAXMEMORY-POLICY 값

  • 메모리가 한정되어 있으므로, 캐시 사용 시 Expire Time을 설정하지 않으면 메모리가 금세 가득 차 장애가 발생할 수 있습니다.
  • 메모리가 가득 찼을 때 데이터 삭제 정책(MAXMEMORY-POLICY)에 의해 데이터가 삭제됩니다.
  • 옵션값 종류
    • noeviction : 기본값, 메모리가 가득 차면 더 이상 새로운 키 저장이 불가능하여 장애가 발생합니다.
    • volatile-lru: Expire 설정이 있는 키 중 가장 최근에 사용하지 않은 키부터 삭제합니다. Expire 설정값이 없는 키만 남아있으면 장애가 발생할 수 있습니다.
    • allkeys-lru: 추천 설정, 모든 키에 대해 LRU 방식으로 키를 삭제합니다. 이 설정에서는 데이터가 가득 참으로 인해 장애가 발생할 가능성이 없습니다.

Cache Stampede 현상 및 TTL 관리

Cache Stampede 현상: 대규모 트래픽 환경에서 TTL 값을 너무 작게 설정했을 때 발생 가능성이 있습니다.

  • 발생 과정: Look-Aside 패턴에서 키가 만료되는 순간, 많은 서버가 이 키를 보고 있다면 모든 애플리케이션 서버들이 DB로 가서 같은 데이터를 찾게 되는 Duplicate Read가 발생합니다.
  • 이로 인해 불필요한 작업이 늘어나 장애로 이어질 수 있습니다.
  • 실제 사례: 발표자티켓링크에서 인기 공연 오픈 시, 하나의 공연 데이터를 읽기 위해 수십 개의 서버에서 커넥션이 연결되었고, TTL 시간을 넉넉하게 늘리는 것으로 이슈를 해결했습니다.

메모리 사용량 및 Fragmentation 관리

Copy On Write로 인한 메모리 2배 증가 가능성

  • Redis 가 파일을 저장할 때 포크(Fork)를 통해 자식 프로세스를 생성합니다. 자식 프로세스는 백그라운드에서 파일 저장을 수행하고, 원래 프로세스는 요청 처리를 계속합니다.
  • 이는 Copy On Write 기능으로 메모리를 복사하여 사용하기 때문에 가능합니다.
  • 이로 인해 서버의 메모리 사용률이 2배로 증가하는 상황이 발생할 수 있습니다.
  • 데이터를 영구 저장하지 않더라도 복제 기능을 사용할 경우, 연결 시도나 재시도 시 RDB 파일을 저장하는 과정을 거치므로 주의해야 합니다.
  • 권장 설정: 이 경우 maxmemory 값을 실제 메모리의 절반 정도로 설정해야 예상치 못한 메모리 부족 장애를 막을 수 있습니다.

메모리 모니터링 중요성

  • Redis 는 메모리 사용 저장소이므로 운영 환경에서는 메모리 관리가 가장 중요합니다.
  • 모니터링 시 used_memory 값이 아닌 used_memory_rss 값을 보는 것이 더 중요합니다.
    • used_memory: 논리적으로 저장된 데이터 크기
    • used_memory _rss: OS가 실제로 할당한 메모리 크기
  • Fragmentation: 실제 저장된 데이터는 적은데 rss 값이 큰 상황을 의미하며, 이 둘의 차이가 클 때 Fragmentation이 발생했다고 합니다. 이는 로 삭제되는 키가 많을 때 증가합니다.
    (예: 특정 시점에 피크를 찍고 다시 삭제되는 경우, TTL로 인해 삭제가 과도하게 발생하는 경우)

Fragmentation 해결

  • 피크를 친 후 초록색 used 그래프는 내려가지만 노란색 rss 그래프는 많이 남아있는 현상이 발생합니다.
  • 이때 activefrag 기능을 잠시 켜두면 도움이 됩니다.
  • 공식 문서에서는 이 값을 항상 켜두는 것보다 단편화가 많이 발생했을 때 켜두는 것을 권장합니다.

 


사실 Redis는 회사 재직하면서도 썼었고, 부트캠프에서도 다뤄봤던 건데 개념을 좀 더 잡고가면 좋을 것 같아서 Redis에 대해 공부한 내용을 정리해보았습니다.

위에 정리된 내용은 NHN Cloud의 [NHN FORWARD 2021] Redis 야무지게 사용하기 영상을 참고하였습니다.

참고 블로그
레디스를 학습하며 도움 받았던 레퍼런스 링크 모음

참고 영상
[NHN FORWARD 2021] Redis 야무지게 사용하기