Post

Redis

Redis

Redis 정리 문서


회사에서 야구장 프로젝트를 하면서 실시간으로 cctv 프레임 데이터들을 처리하기 위해 Redis를 사용했다.
큐로 사용할 때는 간단하게 Redis List로 했는데, 더 나은 방법이 있었을까 찾아보다가 작성하게 되었다.
대표적인 NoSQL인 Redis에 대해 알아보자!


Redis 기본 개념

  • Redis는 인메모리 기반의 Key-Value 저장소
  • 다양한 자료구조를 지원: String, List, Set, Hash, Sorted Set, Streams, Bitmap 등
  • Key를 넣는 순간 Redis가 자동으로 해당 자료구조를 생성해준다.

인메모리

  • 데이터를 디스크가 아닌 RAM(메인 메모리) 에 저장하여 읽기/쓰기 속도가 매우 빠르다는 것을 의미한다.
  • 이로 인해 마이크로초 단위 응답이 가능하고, 실시간성이 중요한 시스템에 적합하다!
  • 그런데 RAM이 휘발성이기 때문에 서버가 종료되거나 장애가 발생해서 중단되면 데이터가 유실될 수 있다.
    • 이를 방지하기 위해 RDB(스냅샷 저장), AOF(명령어 로그 저장) 방식으로 디스크에 백업할 수 있다.
    • 이러한 특성때문에 장시간 저장되어야하는 데이터보다는 실시간 처리, 캐시, 세션, 로그성 데이터 저장에 주로 활용된다.

메시지 큐로서의 Redis

  • Redis는 단순히 값을 저장하고 조회하는 용도 외에도, 메시지 큐 시스템으로도 매우 널리 활용된다.
  • 대표적인 메시지 큐 시스템인 Kafka나 RabbitMQ처럼 복잡한 설치나 설정 없이도, Redis가 기본으로 제공하는 자료구조(List, Streams)를 활용하면 빠르고 간단한 큐 시스템을 구축할 수 있다.
    • List는 가장 간단한 형태의 큐를 만들 수 있는 구조로, LPUSH와 RPOP을 조합하면 FIFO 큐처럼 사용할 수 있다.
    • Streams는 XADD, XREADGROUP 등의 명령어를 통해 Kafka처럼 스트리밍 메시지 처리를 구현할 수 있다.
      • 메시지를 여러 소비자가 나눠서 처리할 수도 있고, 메시지가 처리되지 않으면 다시 읽도록 구성할 수도 있다.
  • 이러한 큐 기능 덕분에 Redis는 실제 서비스에서 실시간 메세지 처리, 비동기 작업 큐, 데이터 수집 등 다양한 상황에서 활용되고 있다.


Redis List vs Redis Streams

Redis에는 왜 List와 Streams가 둘 다 있는가?

Redis는 초기에 List라는 자료구조를 통해 간단한 큐 기능을 제공해왔다.
원래는 큐 용도로 설계된 건 아니었지만, 자연스럽게 LPUSHLPOP/RPOP 같은 명령어가 제공되면서
큐처럼 사용할 수 있는 구조로 자리잡게 되었다.

  • LPUSH + RPOP → FIFO (선입선출)
  • LPUSH + LPOP → LIFO (후입선출)

이 덕분에 Redis List는 간단한 작업 큐, 비동기 처리용 큐 등에서 널리 활용됐지만,
사실 메시지 큐로서 쓰기엔 구조적으로 한계가 명확하다.

  • 데이터를 꺼내는 순간 바로 삭제되기 때문에 메시지 재처리가 불가능하고
  • 여러 소비자가 동시에 큐를 읽으면 충돌이나 중복 처리가 발생할 수 있다
  • 메시지 상태 추적(누가 처리했는지, 처리 중인지) 기능이 없다

이러한 단점을 해결하고, 보다 신뢰성 있는 메시지 스트리밍을 지원하기 위해
Redis 5.0 (2018년 10월 출시)부터 Streams 자료구조가 도입되었다.

Streams는 Kafka와 비슷한 구조를 갖고 있다.
메시지가 순차적으로 쌓이고, 각 항목에는 고유 ID가 부여된다.
데이터를 읽어도 자동으로 삭제되지 않으며, 소비자가 명시적으로 ACK를 호출해야 처리 완료로 간주된다.

  • 메시지는 XADD로 추가되고, XREADXREADGROUP으로 읽을 수 있다
  • XGROUP CREATE를 통해 컨슈머 그룹을 만들고, 여러 작업자가 하나의 스트림을 병렬로 처리할 수 있다
  • 메시지가 처리되지 않으면 다시 조회해서 재처리할 수 있다

정리

  • Redis List는 원래 큐를 위한 구조는 아니었지만, 큐처럼 사용 가능한 단순한 자료구조이다.
  • Redis Streams는 본격적인 메시지 큐 시스템을 구현하기 위한 구조로, Redis 5.0부터 추가되었다.
  • 상황에 따라, 단순한 작업에는 List, 신뢰성과 확장성이 필요한 시스템에는 Streams를 선택하면 된다.
항목Redis ListRedis Streams
목적단순한 큐로그 기반 고급 큐
생성 방법LPUSH, RPUSH 시 자동 생성XADD 시 자동 생성
소비자 그룹없음XGROUP CREATE 로 생성
메시지 추적불가PEL(Pending Entry List), ACK 필요
메시지 보존꺼내면 바로 삭제됨ACK 또는 수동 삭제 전까지 유지
사용성매우 간단약간 복잡하지만 유연함
재시도직접 구현 필요ACK 안 하면 재전송 가능
여러 소비자 처리어려움컨슈머 그룹 기반 분산 처리


List 명령어 조합에 따른 동작

조합동작설명
LPUSH + LPOP스택 (LIFO)최근 데이터 먼저 처리
LPUSH + RPOP큐 (FIFO)순서대로 처리, 일반적인 큐 구조
RPUSH + LPOP큐 (FIFO)반대 방향으로 넣고 앞에서 꺼냄


Redis Stream 구성

1
2
3
4
5
6
7
8
9
10
11
# Stream에 메시지 추가
r.xadd("camera_stream", {"image": image_b64, "timestamp": ts}, maxlen=1000)

# 소비자 그룹 생성 (최초 1회)
r.xgroup_create("camera_stream", "camera_group", id="0", mkstream=True)

# 메시지 읽기
r.xreadgroup("camera_group", "consumer_1", {"camera_stream": ">"}, count=1)

# 메시지 처리 후 ACK
r.xack("camera_stream", "camera_group", message_id)


Redis 설정

설정 파일 (redis.conf)

  • Redis는 설정 파일을 통해 포트 번호, 인증 비밀번호, 데이터 저장 경로, 로그 경로 등 다양한 동작 방식을 제어할 수 있다.
  • 보통 Redis를 설치하면 기본 설정 파일인 /etc/redis/redis.conf가 함께 제공된다.
  • 단, 이 파일은 자동으로 불리는 게 아니며, 서버 실행 시 명시적으로 경로를 지정해줘야 적용된다.
1
redis-server /etc/redis/redis.conf
  • 설정 파일을 지정하지 않고 redis-server만 실행하면, Redis는 내장된 기본 설정값으로 실행된다.
    • 포트: 6379
    • 저장 위치: 현재 디렉토리의 dump.rdb
    • 인증 없음, 로그 콘솔 출력 등

사용자 별 설정 분리

같은 머신에서 여러 Redis 인스턴스를 운영하고 싶다면, 설정 파일을 복사해서 인스턴스별로 분리하면 된다.

1
redis-server ~/myredis/redis_6380.conf

예시 conf 내용 (일부)

1
2
3
4
port 6380
dir /home/user/redis_data/6380
logfile "/var/log/redis_6380.log"
requirepass mypassword
  • 당연한 부분이지만 포트, 데이터 디렉토리, 로그 파일 등은 인스턴스마다 다르게 설정해야 충돌을 방지할 수 있다.


결론

  • Redis는 설정 없이 바로 쓰기 좋지만, Streams와 소비자 그룹을 쓸 땐 명시적인 명령어가 필요하다.
  • Redis List는 간단하지만 기능이 제한적이고, Redis Streams는 Kafka-lite로 사용 가능한 신뢰성 있는 큐 시스템
  • 설정 파일은 인스턴스 단위로 분리해 사용할 수 있다.
This post is licensed under CC BY 4.0 by the author.