Redis vs Memcached vs Valkey — 인메모리 DB 선택 가이드
인메모리 데이터 저장소를 도입하려는데, Redis, Memcached, Valkey 중 어떤 것을 선택해야 할까요?
인메모리 DB 선택의 중요성
인메모리 데이터베이스는 캐시, 세션 저장, 실시간 처리 등 다양한 용도로 사용됩니다. 한번 선택하면 나중에 바꾸기 어렵기 때문에, 프로젝트의 요구사항에 맞는 도구를 처음부터 잘 선택하는 것이 중요합니다.
Redis
특징
Redis는 "데이터 구조 서버(Data Structure Server)"를 표방합니다. 단순 key-value를 넘어서 다양한 자료구조를 제공합니다.
지원 자료구조: String, Hash, List, Set, Sorted Set,
Stream, Bitmap, HyperLogLog, Geospatial
영속성: RDB (스냅샷), AOF (명령 로그)
복제: Master-Replica 비동기 복제
고가용성: Sentinel (자동 페일오버)
수평 확장: Redis Cluster (해시 슬롯 기반 샤딩)
스크립팅: Lua, Redis Function (7.0+)
메시징: Pub/Sub, Stream
라이선스: SSPL + RSALv2 (7.4부터)
강점
- 풍부한 자료구조로 복잡한 로직을 서버사이드에서 처리
- 영속성으로 캐시 이상의 데이터 저장소 역할 가능
- Pub/Sub, Stream으로 메시징 기능 제공
- 거대한 생태계와 풍부한 클라이언트 라이브러리
약점
- 싱글 스레드 명령 실행 (6.0+ I/O 멀티스레딩으로 일부 완화)
- 라이선스 변경으로 클라우드 서비스 제약
- 메모리 오버헤드가 Memcached보다 큼
Memcached
특징
Memcached는 2003년에 만들어진 인메모리 캐시 시스템의 원조입니다. 단순함이 최대 장점입니다.
지원 자료구조: String (key-value)만
영속성: 없음 (순수 캐시)
복제: 없음
고가용성: 없음 (클라이언트 측 일관성 해싱으로 분산)
수평 확장: 클라이언트 측 샤딩
스크립팅: 없음
메시징: 없음
라이선스: BSD
강점
- 처음부터 멀티스레드 설계 → 멀티코어 CPU를 효율적으로 활용
- Slab Allocator로 메모리 단편화가 적음
- 구조가 단순하여 예측 가능한 성능
- 메모리 효율이 좋음 (같은 데이터에 대해 Redis보다 적은 메모리)
- BSD 라이선스
약점
- String만 지원 — 구조화된 데이터는 직렬화/역직렬화 필요
- 영속성 없음 — 재시작하면 데이터 소실
- 서버 측 복제/고가용성 없음
- 1MB 값 크기 제한 (기본)
Memcached 사용 예시
// Memcached 클라이언트 (Java - spymemcached)
MemcachedClient client = new MemcachedClient(
new InetSocketAddress("localhost", 11211));
// 저장 (TTL 3600초)
client.set("user:1001", 3600, serializedUser);
// 조회
Object result = client.get("user:1001");
// CAS (Compare And Swap)
CASValue<Object> casValue = client.gets("counter");
client.cas("counter", casValue.getCas(), newValue);
Valkey
탄생 배경
2024년 3월, Redis Labs가 Redis의 라이선스를 BSD에서 SSPL(Server Side Public License) + RSALv2(Redis Source Available License)로 변경했습니다. 이는 AWS, Google Cloud 등 클라우드 벤더가 Redis를 "매니지드 서비스"로 제공하는 것을 제한하는 것이 주 목적이었습니다.
이에 대응하여 Linux Foundation 주도로 Redis 7.2.4를 기반으로 Valkey가 포크되었습니다. AWS, Google, Oracle, Ericsson 등이 참여하고 있습니다.
특징
기반: Redis 7.2.4 포크
호환성: Redis API와 거의 100% 호환
기존 Redis 클라이언트 그대로 사용 가능
라이선스: BSD 3-Clause (자유로운 사용)
개발: Linux Foundation 후원, 커뮤니티 주도
독자 기능 (8.0+):
- 듀얼 채널 복제 (복제 성능 개선)
- RDMA 지원
- 비동기 I/O 개선
Redis와의 차이
# Valkey 설치
# Docker
docker run -p 6379:6379 valkey/valkey:latest
# 사용법 — Redis와 동일
valkey-cli
127.0.0.1:6379> SET hello "world"
OK
127.0.0.1:6379> GET hello
"world"
# 기존 Redis 클라이언트도 그대로 사용 가능
# Lettuce, Jedis, Redisson 등
Valkey를 선택해야 하는 경우
- 클라우드에서 인메모리 DB를 서비스로 제공하는 경우
- 라이선스 제약을 피하고 싶은 경우
- 오픈소스 커뮤니티 주도 개발을 선호하는 경우
- Redis와 동일한 기능이 필요하지만 BSD 라이선스가 중요한 경우
세 가지 비교
기능 비교
| 특성 | Redis | Memcached | Valkey |
|---|---|---|---|
| 자료구조 | String, Hash, List, Set, ZSet, Stream 등 | String만 | Redis와 동일 |
| 영속성 | RDB, AOF | 없음 | Redis와 동일 |
| 복제 | Master-Replica | 없음 | Redis와 동일 |
| 클러스터링 | Redis Cluster | 클라이언트 측 샤딩 | Redis와 동일 |
| 스크립팅 | Lua, Function | 없음 | Redis와 동일 |
| Pub/Sub | 지원 | 없음 | 지원 |
| 스레드 모델 | 싱글 (I/O 멀티스레딩) | 완전 멀티스레드 | 싱글 (I/O 개선) |
성능 비교
| 워크로드 | Redis | Memcached | Valkey |
|---|---|---|---|
| 단순 GET/SET | 빠름 | 비슷하거나 약간 빠름 | Redis와 동일 |
| 멀티코어 활용 | 제한적 | 우수 | 개선 중 |
| 큰 값 처리 | 좋음 | 1MB 제한 | 좋음 |
| 복잡한 연산 | 우수 (자료구조 활용) | 불가 | 우수 |
| 메모리 효율 | 보통 | 우수 | 보통 |
라이선스 비교
| Redis | Memcached | Valkey | |
|---|---|---|---|
| 라이선스 | SSPL + RSALv2 | BSD | BSD 3-Clause |
| 클라우드 서비스 | 제약 있음 | 자유 | 자유 |
| 상용 사용 | 제약 확인 필요 | 자유 | 자유 |
| 수정 배포 | 조건부 | 자유 | 자유 |
선택 기준
Memcached를 선택해야 할 때
✅ 단순 key-value 캐시만 필요
✅ 영속성이 필요 없음
✅ 멀티코어 CPU 활용이 중요
✅ 메모리 효율이 최우선
✅ 이미 Memcached 인프라가 구축되어 있음
Redis를 선택해야 할 때
✅ 다양한 자료구조 필요 (Sorted Set, Hash 등)
✅ 영속성이 필요 (캐시 이상의 데이터 저장)
✅ Pub/Sub, Stream 등 메시징 기능 필요
✅ 분산 락, Rate Limiting 등 고급 기능 필요
✅ 라이선스 제약이 문제되지 않는 환경
Valkey를 선택해야 할 때
✅ Redis의 모든 기능이 필요하지만 BSD 라이선스가 중요
✅ 클라우드에서 매니지드 서비스로 제공해야 함
✅ 오픈소스 커뮤니티 거버넌스를 선호
✅ 새 프로젝트에서 라이선스 리스크를 피하고 싶음
마이그레이션 가이드
Memcached → Redis/Valkey
// Memcached
client.set("user:1001", 3600, serializedUser);
Object user = client.get("user:1001");
// Redis — 동일한 패턴
redisTemplate.opsForValue().set("user:1001", user, Duration.ofSeconds(3600));
User user = redisTemplate.opsForValue().get("user:1001");
// Redis — 자료구조 활용으로 개선
redisTemplate.opsForHash().putAll("user:1001", userMap);
// 필요한 필드만 조회 가능
String name = redisTemplate.opsForHash().get("user:1001", "name");
Redis → Valkey
# 1. Valkey 설치 (동일한 포트도 가능)
# 2. RDB 파일 복사 → Valkey에서 로드
# 3. 클라이언트 연결 대상 변경 (IP/포트만)
# 4. 코드 변경 불필요 — API 호환
Redis에서 Valkey로의 마이그레이션은 가장 간단합니다. 프로토콜과 명령이 호환되므로 연결 대상만 변경하면 됩니다.
실무에서의 조합 사용
하나만 선택할 필요는 없습니다. 용도에 따라 조합하는 것도 방법입니다.
L1 캐시: Caffeine (로컬)
L2 캐시: Memcached (단순 key-value, 대량 캐시)
세션/락: Redis 또는 Valkey (자료구조, 영속성)
메시징: Redis Stream 또는 Kafka
정리
- Memcached: 단순 캐시, 멀티스레드, 메모리 효율 → "간단한 캐시만 필요하다면"
- Redis: 풍부한 자료구조, 영속성, 메시징 → "캐시 이상의 기능이 필요하다면"
- Valkey: Redis 호환 + BSD 라이선스 → "Redis 기능 + 라이선스 자유가 필요하다면"
- 새 프로젝트에서는 라이선스 고려 시 Valkey를, 단순 캐시만 필요하면 Memcached를, 풍부한 기능이 필요하면 Redis 또는 Valkey를 선택하세요
댓글 로딩 중...