Redis에서 Valkey로 무중단 마이그레이션 — 백엔드 서비스를 코드 변경 없이 전환하는 방법
2024년 3월, Redis Inc.가 BSD 라이선스를 SSPL/RSALv2로 전환한다는 발표를 봤을 때 솔직히 당황했습니다. "우리 서비스가 상업적 제약에 걸리는 건 아닌가?" 하고 법무팀에 문의를 돌렸을 거예요. 저도 그랬고요.
좋은 소식이 있습니다. Redis 7.2 이하를 쓰고 있다면, 지금 당장 코드 한 줄 바꾸지 않고 Valkey로 옮길 수 있습니다. Valkey는 Linux Foundation이 Redis 7.2.4를 포크해 BSD-3-Clause 라이선스로 영구 유지하는 프로젝트입니다. RESP 프로토콜과 RDB 파일 형식을 그대로 유지하기 때문에, 기존 클라이언트와 데이터를 새로 건드릴 필요가 없거든요. AWS, Google Cloud, Oracle, ByteDance 등 17개 벤더가 뒤를 받치고 있으니 거버넌스 측면에서도 든든합니다.
이 글에서는 어떤 Redis 버전에서 어떤 방법으로 Valkey로 넘어올 수 있는지, 그리고 운영 서비스를 다운타임 없이 전환하는 구체적인 절차를 코드와 함께 살펴봅니다. Node.js 예시를 중심으로 쓰지만, Python이나 Java를 쓰는 분께도 핵심 흐름은 동일하게 적용됩니다.
핵심 개념
Valkey가 Redis와 사실상 같은 이유
Valkey 마이그레이션이 생각보다 단순한 데는 이유가 있습니다. 포크 출발점이 Redis 7.2.4라서, 프로토콜부터 데이터 파일까지 하위 호환이 잘 유지되어 있거든요.
| 항목 | 내용 |
|---|---|
| 와이어 프로토콜 | RESP2 / RESP3 모두 지원 → 기존 Redis 클라이언트 연결 주소만 바꾸면 동작 |
| 데이터 파일 | Redis OSS 7.2 이하의 RDB/AOF 파일 형식과 완전 호환 |
| 주의 | Redis Community Edition 7.4 이상에서 생성된 데이터 파일은 직접 읽기 불가 |
RESP(REdis Serialization Protocol) — Redis와 클라이언트 사이의 통신 규약입니다. Valkey가 RESP2/RESP3를 동일하게 지원하기 때문에
ioredis,redis-py,Jedis,StackExchange.Redis같은 기존 클라이언트가 연결 주소만 바꿔도 정상 동작합니다.
현재 Redis 버전이 마이그레이션 난이도를 결정합니다
가장 먼저 확인해야 할 것은 현재 Redis 버전입니다.
redis-cli INFO server | grep redis_version- Redis OSS 7.2 이하 → 가장 쉬운 케이스. 데이터 파일을 그대로 가져올 수 있습니다.
- Redis CE 7.4 이상 → 데이터 파일 형식이 달라져 직접 복사가 안 됩니다. 레플리케이션 방식으로 라이브 동기화해야 합니다.
- Redis Stack / Enterprise → RedisJSON, RediSearch, 벡터 검색 같은 전용 모듈 의존성을 먼저 정리해야 합니다. 단순 전환보다 마이그레이션 설계가 필요한 케이스입니다.
Valkey에서 지원하지 않는 명령어도 미리 확인해두는 게 좋습니다. 핵심 캐싱이나 세션 용도라면 문제없겠지만, JSON.SET / FT.SEARCH / TS.ADD 같은 모듈 명령어를 쓰고 있다면 대안이 필요합니다. redis-cli COMMAND DOCS <명령어>로 현재 쓰는 명령어를 하나씩 확인해볼 수 있습니다.
성능은 오히려 올라갔습니다
저도 처음엔 "포크 프로젝트가 원본보다 나을 수 있나?" 반신반의했는데, 수치를 보니 납득이 됐습니다. Swiss Tables 기반으로 내부 해시 구조를 재구성한 것이 핵심인데, 기존 해시 테이블보다 캐시 적중률이 높아 메모리 접근 횟수가 줄어드는 효과가 있습니다. Valkey 8.1부터 차이가 눈에 띄게 벌어지기 시작합니다.
| 버전 | 주요 개선 |
|---|---|
| Valkey 8.1 (2025.03) | 처리량 +8%, P99 레이턴시 -22%, 메모리 -20% |
| Valkey 9.0 (2025.10) | 처리량 +40%, 해시 필드별 TTL 지원, 1억+ RPS 클러스터 |
| Valkey 9.1 (2026.05) | 약 210만 RPS, 메모리 추가 -10% |
위 수치는 Valkey 공식 블로그 및 Better Stack 벤치마크(2025~2026 기준)를 참고했습니다. 워크로드·인스턴스 사양에 따라 실측값은 달라질 수 있습니다.
실전 적용
예시 1: 스냅샷 방식 — 개발 환경 또는 짧은 점검 창이 허용되는 서비스
서비스 중단이 잠깐 허용되거나 데이터 양이 크지 않다면 RDB 파일을 그대로 옮기는 방법이 가장 단순합니다. 저는 개발 환경에서 이 방법으로 먼저 검증했습니다.
# 1. Redis에서 백그라운드 스냅샷 생성
redis-cli BGSAVE
# 저장 완료 여부 확인 — rdb_bgsave_in_progress가 0이면 완료
# (LASTSAVE는 타임스탬프를 반환할 뿐, 완료 여부 판단에 쓰면 안 됩니다)
redis-cli INFO persistence | grep rdb_bgsave_in_progress
# 2. RDB 파일을 Valkey 데이터 디렉터리로 복사
cp /var/lib/redis/dump.rdb /var/lib/valkey/dump.rdb
# 3. Valkey 서버 시작
valkey-server /etc/valkey/valkey.conf
# 4. 데이터 검증
# KEYS "*"는 단일 스레드를 블로킹하므로 운영 서버에서 절대 사용하면 안 됩니다
# 대신 SCAN으로 안전하게 샘플 키를 확인할 수 있습니다
valkey-cli DBSIZE
valkey-cli SCAN 0 COUNT 20| 단계 | 명령어 | 확인 포인트 |
|---|---|---|
| 스냅샷 생성 | BGSAVE |
INFO persistence의 rdb_bgsave_in_progress: 0 확인 |
| 파일 복사 | cp dump.rdb |
파일 크기·권한이 동일한지 확인 |
| 데이터 검증 | DBSIZE + SCAN |
이전 Redis의 DBSIZE와 키 수 비교 |
예시 2: 레플리케이션 방식 — 운영 서비스 무중단 전환
실무에서 가장 자주 맞닥뜨리는 상황입니다. 세션 캐시나 게임 랭킹처럼 짧은 다운타임도 허용하기 어려운 서비스라면 이 방법이 맞습니다. Valkey가 Redis의 replica처럼 동작하며 데이터를 라이브로 동기화한 뒤, 준비되면 primary로 승격하는 방식입니다.
# [Valkey 서버에서] Redis를 primary로 지정해 복제 시작
valkey-cli REPLICAOF <redis-host> 6379
# 복제 상태 실시간 모니터링
watch -n 2 "valkey-cli INFO replication | grep -E 'role|master_link_status|master_sync'"master_link_status: up이고 master_sync_in_progress: 0이 되면 실시간 동기화가 안정적으로 이루어지는 상태입니다.
# [동기화 완료 확인 후] Valkey를 독립 primary로 승격
valkey-cli REPLICAOF NO ONE승격 이후에는 애플리케이션 연결을 Valkey로 전환합니다. 환경변수나 DNS CNAME만 교체하면 되기 때문에, Redis 서버는 이 시점에 즉시 종료하지 않고 계속 실행 상태로 두는 것이 중요합니다. 전환 직후 이상이 생기면 환경변수를 원래 Redis 호스트로 되돌리기만 해도 롤백이 됩니다. 코드 재배포 없이 복구 가능합니다.
# 트래픽 전환 전 체크리스트
# 1. master_sync_in_progress: 0 (동기화 완료)
# 2. master_link_status: up (연결 유지)
# 3. Redis 서버 계속 실행 중 (롤백 대기용)Sentinel / Cluster 구성이라면? Sentinel을 쓰는 팀은 Valkey replica를 붙인 뒤 Sentinel이 Valkey primary를 바라보도록 설정을 변경하는 절차가 추가됩니다. Cluster 모드는 노드 단위로 교체하는 rolling 방식이 일반적입니다. 각 구성별 상세 절차는 Valkey 공식 마이그레이션 문서에서 확인할 수 있습니다.
예시 3: Node.js 애플리케이션 — 클라이언트 코드는 그대로
기존 ioredis를 쓰고 있다면 사실 연결 주소만 바꾸면 됩니다. 이 부분이 Valkey의 가장 큰 장점 중 하나예요. 실무에서 Redis 호스트는 보통 환경변수로 관리하는 경우가 많으니, 변경 포인트가 딱 하나입니다.
import Redis from 'ioredis';
const client = new Redis({
host: process.env.REDIS_HOST ?? 'valkey.internal', // 환경변수만 바꾸면 됩니다
port: Number(process.env.REDIS_PORT ?? 6379),
});
// 아래 사용 코드는 전혀 건드릴 필요 없습니다
await client.set('session:abc', JSON.stringify(sessionData), 'EX', 3600);
const data = await client.get('session:abc');Valkey 공식 클라이언트인 Valkey GLIDE도 있습니다. Rust 기반으로 작성되어 연결 풀 관리와 자동 재연결이 ioredis보다 안정적이고, 클러스터 모드를 별도 설정 없이 지원합니다. 기존 ioredis에서 주기적으로 연결이 끊기는 이슈를 겪었다면 GLIDE로 전환을 검토해볼 만합니다.
import { GlideClient } from '@valkey/valkey-glide';
const client = await GlideClient.createClient({
addresses: [{ host: process.env.VALKEY_HOST ?? 'valkey.internal', port: 6379 }],
});
await client.set('key', 'value');
const val = await client.get('key');
await client.close();Python이나 Java를 주로 쓰신다면 redis-py, Jedis 모두 연결 주소만 교체해도 동작합니다. GLIDE의 Python/Java 바인딩은 valkey-glide GitHub에서 확인할 수 있습니다.
장단점 분석
저희 팀에서 가장 걱정했던 부분은 고급 모듈 의존성이었는데, 세션 캐싱 용도가 대부분이라 결국 별다른 마찰 없이 넘어왔습니다. 아래 표는 그 과정에서 실제로 따져본 항목들입니다.
장점
| 항목 | 내용 |
|---|---|
| 영구 오픈소스 | BSD-3-Clause, Linux Foundation 관리. 라이선스 변경 리스크 없음 |
| 성능 향상 | Redis OSS 대비 처리량 최대 40% 향상, 메모리 20~30% 절감 |
| 클라우드 요금 | AWS ElastiCache for Valkey 시간당 요금 20% 저렴, 신규 인스턴스 기본값 채택 |
| 클라이언트 호환 | ioredis, redis-py, Jedis 등 기존 라이브러리 코드 변경 없이 사용 |
| 생태계 | AWS, Google Cloud, Oracle, Alibaba Cloud 등 17개 벤더 지원 |
단점 및 주의사항
| 항목 | 내용 | 대응 방안 |
|---|---|---|
| 고급 모듈 부재 | RedisJSON, RediSearch, 벡터 검색, 시계열이 없음 | 대안 모듈 또는 Google Memorystore(벡터 검색 포함) 검토 |
| CE 7.4 이상 비호환 | 최신 Redis CE 데이터 파일 직접 이식 불가 | 레플리케이션 방식으로 라이브 마이그레이션 |
| 모듈 명령어 차이 | JSON.*, FT.*, TS.* 등 모듈 명령어 미지원 |
전환 전 COMMAND DOCS로 사용 명령어 목록 점검 |
SSPL(Server Side Public License) — MongoDB가 처음 도입한 라이선스로, 서비스로 제공할 때도 소스를 공개해야 합니다. SaaS 사업자에게는 사실상 상업적 제약으로 작용합니다. Valkey의 BSD-3-Clause는 이런 제약이 없습니다.
솔직히 말하면, Valkey가 모든 팀에 맞는 선택은 아닙니다. Redis Enterprise를 쓰는 팀이나 벡터 검색이 핵심 기능인 팀은 서비스 요구사항을 먼저 따져봐야 합니다. 라이선스 비용보다 마이그레이션 공수가 더 클 수 있거든요.
실무에서 가장 흔한 실수
- Redis 버전 확인 생략 — 저도 처음에 이 실수를 했습니다. "그냥 RDB 파일 복사하면 되겠지" 하고 Redis CE 7.4 데이터를 Valkey에 올려봤는데 파일을 아예 읽질 못했습니다.
redis-cli INFO server | grep redis_version한 줄이 나중에 몇 시간을 아껴줍니다. - 모듈 명령어 의존성 파악 미흡 —
RedisJSON,RediSearch같은 모듈을 쓰고 있다면 Valkey에는 해당 명령어가 없습니다. 팀 내에서 실제로 쓰는 명령어를 정리해봤더니, 예상보다 훨씬 많은 곳에서 모듈 명령어를 쓰고 있어서 깜짝 놀랐습니다. 전환 전에 사용 명령어 목록을 꼭 뽑아보는 것을 권장합니다. - 레플리케이션 동기화 완료 전 트래픽 전환 —
master_sync_in_progress: 1인 상태에서REPLICAOF NO ONE을 실행하면 데이터 일부가 누락될 수 있습니다. 팀에서 실제로 이 타이밍을 놓쳐 키가 일부 사라진 경험이 있어서, 반드시0이 된 것을 눈으로 확인한 뒤 진행하는 것을 권장합니다.
마치며
지금 바로 버전 확인 명령어 하나만 실행해봐도 충분합니다. Redis 7.2 이하라면 오늘 개발 환경에서 전환을 시도해볼 수 있고, 라이선스 안정성과 성능 향상을 동시에 얻을 수 있습니다.
지금 바로 시작할 수 있는 3단계:
- 버전과 모듈 의존성부터 확인해볼 수 있습니다.
redis-cli INFO server | grep redis_version으로 현재 버전을 파악하고,RedisJSON이나RediSearch같은 모듈을 쓰고 있는지 점검해볼 수 있습니다. - 개발 환경에서 스냅샷 방식으로 먼저 시도해볼 수 있습니다.
docker run valkey/valkey:latest로 Valkey를 띄운 뒤 RDB 파일을 복사해DBSIZE와 주요 키를 검증해보면 됩니다. - 운영 전환은 레플리케이션 방식으로 진행하는 것을 권장합니다.
REPLICAOF로 Valkey를 replica로 붙이고,INFO replication으로master_sync_in_progress: 0을 확인한 다음REPLICAOF NO ONE으로 승격하면 됩니다. Redis 서버는 롤백 대기 용도로 계속 실행 상태로 두는 것이 중요합니다.
참고 자료
- Valkey 공식 마이그레이션 문서 | valkey.io
- Valkey GLIDE 공식 클라이언트 | GitHub
- Percona: Redis to Valkey Migration Guide | Percona Docs
- Aiven: 1만 5천 Redis 서버 Valkey 마이그레이션 사례 | Aiven Blog
- AWS ElastiCache for Valkey 마이그레이션 모범 사례 | AWS Blog
- Redis vs Valkey 2026 심층 비교 | Better Stack
- Valkey 2025 연간 회고 | Valkey 공식 블로그
- Valkey GitHub 공식 저장소 | GitHub
- Google Cloud Memorystore for Valkey 공식 문서 | Google Cloud