Redis
Redis는 기본적으로 인메모리 키-값 저장소야. 데이터가 메모리에 있어서 정말 빠르고, 보통은 캐시로 많이 사용.
그리고 pub/sub 구조를 지원해서 메시지 전달에도 사용.
또한 Redis Streams 같은 기능을 통해 간단한 메시지 큐 시스템으로도 사용.
특징 요약하자면:
- 빠르다 (메모리 기반이라서)
- 구조가 단순하고 사용하기 쉽다
- 캐시, 세션 저장, 일시적인 메시지 처리에 적합
- 메시지 보관 기간이 짧고, 디스크 내구성이 약해 (기본은 휘발성)
언제?
- 서버 간 간단한 pub/sub 통신이 필요할 때
- 로그인 세션 저장이나 캐시 용도로
- 요청을 큐에 잠깐 쌓았다가 백그라운드 처리할 때 (예: 이메일 발송 대기열)
Kafka
Kafka는 일종의 분산 메시징 시스템 또는 이벤트 스트리밍 플랫폼으로 보면 된다.
기본적으로 모든 메시지를 디스크에 로그처럼 저장하면서 여러 컨슈머가 읽을 수 있게 해준다.
한 번 들어온 메시지를 수많은 시스템이 동시에 처리할 수 있게 도와주는 게 강점.
특징을 정리하자면:
- 내구성이 높다 (디스크에 저장됨)
- 대규모 트래픽을 견딜 수 있음
- 메시지를 오래 저장하면서 순서를 보장함
- 컨슈머가 늦게 들어와도 이전 메시지를 다시 읽을 수 있음
언제 쓰냐면?
- 로그 수집, 분석 시스템 만들 때 (ELK, 데이터 파이프라인)
- 대용량 실시간 이벤트 처리가 필요할 때 (예: 실시간 주문 처리, 실시간 추천 시스템)
- 마이크로서비스 간 이벤트 전달할 때
Redis와 Kafka비교
- Redis는 "간단하고 빠른 캐시 또는 짧은 메시지 전달용"
- Redis는 빠르고 가벼운 큐 (간단하고 휘발성)
- Kafka는 "대규모 데이터를 안정적으로 저장하고 전달하는 로그 기반 시스템"
- Kafka는 무겁지만 안정적이고 유연한 스트리밍 시스템
실제 상황에서 선택 기준
- 회원가입 요청 후 인증 메일 보내기: Redis로 큐에 쌓고 비동기 처리하면 충분해
- 주문 처리 이벤트를 여러 서비스가 처리해야 함: Kafka가 정답. 주문 이벤트를 저장하면서 여러 서비스가 동시에 메시지를 읽게 할 수 있다
- API 응답을 빠르게 하면서 자주 조회되는 데이터 캐시: Redis가 제격
- 모든 유저 행동 로그를 저장하고 분석해야 함: Kafka가 강력
Redis 사용법
Redis의 주요 용도
- 캐시 (가장 많이 쓰임)
- 세션 저장소
- 간단한 큐 (비동기 처리용)
- pub/sub (간단한 메시지 브로커 역할)
- JWT 토큰 캐싱 (리프레시 토큰 관리 등)
- 로그인 세션 저장
- 자주 조회되는 데이터 캐싱 (예: 인기 검색어)
- 비동기 작업 큐 (이메일 전송 대기열 등)
- API rate limiting (요청 횟수 제한)
1. Redis 설치/접속
설치 방법
로컬에 설치 (Mac 기준):
brew install redis
brew services start redis
Docker로 실행:
docker run -d -p 6379:6379 redis
접속 방법
Redis CLI로 접속:
redis-cli
기본 포트는 6379야. 접속 후 이렇게 쳐보면 돼:
SET user:1 "heesung"
GET user:1
2. 기본 사용법 (명령어 중심)
Redis는 key-value 저장소야.
기본적인 데이터 타입은 아래와 같아:
- String
- List
- Set
- Hash
- Sorted Set
String
SET name "mars"
GET name
DEL name
EXPIRE name 60 # 60초 뒤에 자동 삭제
Hash (자바스크립트 객체처럼)
HSET user:1 name "mars" age 29
HGET user:1 name
HGETALL user:1
List (Queue처럼 활용 가능)
LPUSH jobs "email"
RPUSH jobs "sms"
LPOP jobs # email
RPOP jobs # sms
참고: LPUSH + RPOP 조합이면 Queue, LPUSH + LPOP이면 Stack 처럼 사용
pub/sub 구조
- 터미널 1에서 구독:
SUBSCRIBE news
- 터미널 2에서 발행:
PUBLISH news "New blog posted!"
Redis의 pub/sub은 메시지를 저장하지 않아서 구독 중일 때만 받을 수 있다 (Kafka와 가장 큰 차이점 중 하나)
3. Node.js / Java에서 어떻게 쓰냐?
Node.js 예시 (ioredis)
import Redis from 'ioredis';
const redis = new Redis();
await redis.set('user:1', 'heesung');
const value = await redis.get('user:1');
console.log(value); // 'heesung'
Spring Boot 예시
- build.gradle에 추가:
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
- application.yml 설정:
spring:
redis:
host: localhost
port: 6379
- 사용 예시:
@Service
@RequiredArgsConstructor
public class RedisService {
private final StringRedisTemplate redisTemplate;
public void setValue(String key, String value) {
redisTemplate.opsForValue().set(key, value);
}
public String getValue(String key) {
return redisTemplate.opsForValue().get(key);
}
}
Redis를 쓸 때 주의할 점
- 기본은 휘발성이기 때문에, 데이터 영속성이 필요한 경우 RDB / AOF 설정을 해야 함
- 만료시간(Expiration) 설정은 꼭 하는 습관을 들이자 (캐시 서버는 오래 남기면 오히려 병목돼)
- 너무 많은 키를 한 번에 조회하는 건 위험함 (KEYS *는 피해야 함)
Redis 확인하기
Redis Insight
DO MORE WITH YOUR DATA Visualize, optimize, and troubleshoot with Redis Insight Redis Insight is our free graphical interface for analyzing Redis data across all operating systems and Redis deployments with the help of our AI assistant, Redis Copilot. L
redis.io
Redis Insight를 다운받고 6378 (기본 Redis 포트)에서 저장한 key-value를 확인 할 수 있다.
Kafka
- Kafka는 “내구성 있는 대용량 메시지 전달 시스템”
- 하나의 이벤트를 여러 시스템이 동시에 소비해야 할 때 진가 발휘
- 처음엔 복잡하지만, 구조를 한 번 익히면 확장성이 훌륭하다.
- Kafka는 데이터나 이벤트를 토픽(topic)이라는 단위로 쌓아두고, 필요한 시스템이 그걸 꺼내가는 발행/구독 기반의 로그 시스템
- 이벤트 스트리밍 플랫폼
쉽게 말하면: 벤트를 일단 다 적어두고, 누가 언제 오든 꺼내서 보여준다
핵심 개념
1. Producer
- Kafka에 메시지를 보냄
- 예: 주문 생성 API, 로그 수집기
2. Topic
- 메시지를 모아놓는 공간 (일종의 폴더 느낌)
- 예: orders, user-signups, chat-messages
3. Partition
- 하나의 topic이 쪼개진 실제 저장 단위 (scale-out을 위함)
- 병렬 처리할 수 있게 만들어줌
4. Consumer
- 메시지를 읽음
- 예: 알림 서비스, 결제 처리기 등
5. Consumer Group
- 소비자들을 묶은 그룹. 서로 다른 컨슈머끼리는 같은 메시지를 공유, 같은 그룹 안에서는 메시지를 분담 처리
Kafka의 가장 큰 특징
- 메시지를 디스크에 저장해서 영속성 보장
- Redis는 메시지가 사라질 수 있지만 Kafka는 디스크에 쌓고 오래 보관할 수 있다
- 메시지를 한 번에 여러 컨슈머가 읽을 수 있음
- Redis pub/sub은 실시간 구독자만 메시지를 받음. Kafka는 나중에 들어와도 과거 메시지를 볼 수 있다
- 엄청난 양의 데이터를 견딤
- 페이스북, 넷플릭스, 우버 같은 데서 실시간 이벤트 전송에 사용 중
사용법
Kafka는 설치부터 사용까지 조금 복잡하다
보통은 Docker-compose나 클라우드 서비스(AWS MSK 등)를 통해 사용함.
- 실시간 로그 수집 (ELK 스택처럼)
- 여러 서비스가 같은 이벤트를 처리해야 할 때 (ex. 주문 생성 → 알림, 재고 감소, 포인트 적립)
- 순서 보장 / 메시지 유실 방지가 중요한 경우
- 빅데이터 분석을 위한 이벤트 스트리밍 처리
- Kafka + Flink, Kafka + Spark 구조도 많이 씀
설치 (간단히)
# Docker-compose 예시
zookeeper:
image: confluentinc/cp-zookeeper
ports: [2181:2181]
environment:
ZOOKEEPER_CLIENT_PORT: 2181
kafka:
image: confluentinc/cp-kafka
ports: [9092:9092]
environment:
KAFKA_ZOOKEEPER_CONNECT: zookeeper:2181
KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://localhost:9092
Kafka 사용
CLI로 토픽 만들기
# 토픽 생성
kafka-topics.sh --create --topic test-topic --bootstrap-server localhost:9092 --partitions 3 --replication-factor 1
메시지 보내기 (Producer)
kafka-console-producer.sh --topic test-topic --bootstrap-server localhost:9092
# 입력창 뜨면 메시지 입력
메시지 받기 (Consumer)
kafka-console-consumer.sh --topic test-topic --bootstrap-server localhost:9092 --from-beginning
Java (Spring Kafka) 사용법 예시
1. Gradle 설정
implementation 'org.springframework.kafka:spring-kafka'
2. 설정
spring:
kafka:
bootstrap-servers: localhost:9092
consumer:
group-id: test-group
auto-offset-reset: earliest
key-deserializer: org.apache.kafka.common.serialization.StringDeserializer
value-deserializer: org.apache.kafka.common.serialization.StringDeserializer
3. Producer
@Service
@RequiredArgsConstructor
public class KafkaProducer {
private final KafkaTemplate<String, String> kafkaTemplate;
public void sendMessage(String topic, String message) {
kafkaTemplate.send(topic, message);
}
}
4. Consumer
@KafkaListener(topics = "test-topic", groupId = "test-group")
public void consume(String message) {
System.out.println("받은 메시지: " + message);
}
'Java > Spring Boot' 카테고리의 다른 글
| JPA (3) | 2025.03.31 |
|---|---|
| OAuth 구현 (0) | 2025.03.28 |
| HTTP 상태 코드 종류 (0) | 2025.03.27 |
| JWT & CRSF (0) | 2025.03.25 |
| [restartedMain] i.n.r.d.DnsServerAddressStreamProviders : Unable to load io.netty.resolver.dns.macos.MacOSDnsServerAddressStreamProvider, fallback to system defaults. This may result in incorrect DNS resolutions on MacOS. (3) | 2025.01.30 |