date
slug
author
status
tags(최대 3개)
summary
type
thumbnail
category
updatedAt
TL;DR
- Redis OSS 기반 9개 캐시, 28개 노드를 Valkey 9.0으로 업그레이드를 진행했습니다.
- Valkey의 I/O, memory, pipeline, cluster 개선이 운영 캐시 워크로드에 주는 이점을 다룹니다.
- 업그레이드 중 endpoint는 유지되지만 짧은 연결 끊김은 발생할 수 있어 재연결 검증이 핵심입니다.
- 업그레이드 후 대표 캐시에서 Engine CPU, FreeableMemory, GET/SET latency 개선을 확인했습니다.
- Redis OSS 대비 더 낮은 ElastiCache 비용까지 함께 기대할 수 있습니다.
1. 핵심 메시지
이번 작업의 핵심은 단순한 엔진 버전 업그레이드가 아니라, 운영 캐시의 성능 여유와 비용 효율을 함께 개선하는 것이었습니다.
Redis OSS 캐시를 계속 유지할지, Valkey로 전환할지 판단할 때는 세 가지를 봤습니다.
- 현재 캐시 병목이 CPU, memory, latency 중 어디에 있는가?
- Valkey의 I/O, memory, pipeline, cluster 개선이 우리 워크로드에 실제 이점이 있는가?
- 업그레이드 중 발생하는 짧은 연결 끊김을 client가 흡수할 수 있는가?
이번 마이그레이션에서는 총 9개 Redis OSS 캐시, 28개 노드를 대상으로 Valkey 9.0 인플레이스 업그레이드를 순차적으로 진행했습니다. 엔진 전환과 노드 크기 조정은 분리했습니다. 두 작업을 동시에 진행하면 장애나 성능 변화가 발생했을 때 원인을 구분하기 어렵기 때문입니다.
Valkey 전환은 단순한 패치가 아니라 Redis OSS 호환성을 유지하면서 성능과 비용 효율을 함께 개선하는 엔진 마이그레이션입니다. 따라서 이 글도 업그레이드 절차와 Valkey의 이점을 나누지 않고, “왜 올렸는가 → 어떻게 올렸는가 → 무엇이 좋아졌는가”의 흐름으로 설명합니다.
2. 왜 Valkey 인가
Valkey는 Redis 7.2 계열에서 분기된 뒤 Linux Foundation 산하에서 개발되는 오픈소스 인메모리 데이터 저장소입니다. Redis OSS와의 호환성을 유지하면서도 성능, 메모리 효율, 관측성, 클러스터 안정성 측면의 개선이 빠르게 누적되고 있습니다.
Redis OSS 6.x에서 Valkey 9.0으로 올릴 때 기대할 수 있는 변화는 크게 네 가지입니다.
- I/O 개선
- 메모리 효율 개선
- 클러스터 안정성 개선
- 파이프라인 기능 개선
2-1. I/O 개선 (8.0 적용)
I/O 개선은 같은 노드로 더 많은 요청을 처리하거나, 피크 시간대 latency 상승을 줄일 수 있다는 의미입니다.

Redis 계열 서버는 오랫동안 단일 스레드 기반의 명령 실행 모델로 높은 성능을 내왔습니다. 이 구조는 단순하고 예측 가능하지만, 연결 수가 많고 네트워크 I/O가 많은 캐시 워크로드에서는 요청 읽기, 명령 파싱, 응답 쓰기, 이벤트 처리, 메모리 해제 같은 작업이 병목이 될 수 있습니다.
Valkey 8.0은 이 I/O 처리 구조를 크게 개선했습니다. I/O 스레드가 요청 읽기, 명령 파싱, 응답 쓰기, 이벤트 처리, 메모리 해제 작업을 더 적극적으로 담당하고, 메인 스레드는 실제 명령 실행에 더 집중할 수 있도록 바뀌었습니다. 또한 명령 묶음 처리와 메모리 미리 읽기를 통해 CPU 캐시 미스도 줄이는 방향으로 최적화되었습니다.
공식 벤치마크 기준으로 Valkey 8.0은 AWS r7g 플랫폼에서 최대 1.2M QPS 수준을 목표로 했고, 기존 한계였던 약 380K QPS 대비 큰 폭의 처리량 개선을 보였습니다. 별도 심층 분석 글에서도 Valkey 8이 1.19M RPS를 달성한 벤치마크 구성이 소개되었습니다.
2-2. Memory path 개선 (8.0, 8.1 적용)
메모리 효율 개선은 같은 key/value를 더 적은 메모리로 담거나, 더 큰 여유 메모리를 확보할 수 있다는 의미입니다.

캐시 비용에서 메모리 효율은 곧 비용과 연결됩니다. 같은 keyspace를 더 작은 노드에서 운영할 수 있거나, 같은 노드에서 더 큰 여유 메모리를 확보할 수 있기 때문입니다.
Valkey 8.0 key embedding과 slot별 dictionary 구조를 통해 key당 메타데이터 오버헤드를 줄였습니다. 기존 구조에서는 slot 이동을 위해 slot별 key 목록을 유지해야 했고, 이 과정에서 추가 포인터와 메타데이터 비용이 발생했습니다. Valkey 8.0은 클러스터 모드에서 main dictionary를 slot 단위로 나누는 구조를 도입해 slot-to-key 메타데이터 비용을 줄였습니다.
Valkey 8.1 key/value를 저장하는 핵심 자료구조인 해시테이블이 새롭게 설계되었습니다. 기존dict구조는 충돌 처리와 조회 과정에서 여러 포인터를 따라가며 추가적인 메모리 접근과 메모리 오버헤드가 발생했는데, 새 해시테이블은 64바이트 cache line 단위의 bucket에 여러 entry를 함께 배치하고dictEntry를 제거해 key/value 정보를serverObject에 통합했습니다.
이 변경만으로 일반적인 key/value 당 메모리 사용량이 약 20바이트 줄어들며, TTL이 있는 key의 경우 약 30바이트까지 절감됩니다. 애플리케이션 로직이나 캐시 적중률을 바꾸지 않고도 동일한 메모리에서 더 많은 데이터를 수용할 수 있다는 점에서, 대규모 캐시 워크로드에서는 클러스터 크기와 비용 여유를 함께 개선할 수 있는 의미 있는 변화입니다.
2-3. Cluster operation 개선 (9.0 적용)
클러스터 운영 개선은 평상시 성능보다 장애, failover, resharding 같은 변화 상황에서 더 안정적으로 버티는 데 의미가 있습니다.

Valkey의 중요한 변화 중 하나는 클러스터 운영 안정성입니다. 단일 노드 성능만 보면 개선 지점이 I/O와 메모리에 집중되어 보이지만, 실제 대규모 운영에서는 cluster bus, gossip, 장애 감지, failover, slot 이동, pub/sub 메시지 오버헤드가 전체 안정성에 큰 영향을 줍니다.
Valkey cluster mode는 16,384개 hash slot을 여러 primary에 나누고, replica를 통해 가용성을 확보합니다. Client는 key가 속한 slot의 owner로 직접 명령을 보내며, resharding이나 failover 중에는 MOVED/ASK redirect를 따라갑니다. 이 과정에서 cluster bus는 노드 상태, topology, 장애 감지, election, epoch 충돌 해결을 담당합니다.
대규모 클러스터에서는 이 cluster bus 비용을 무시하기 어렵습니다. 노드 수가 늘수록 heartbeat, gossip, reconnect, failure report, pub/sub 메시지가 증가하고, 장애 상황에서는 살아남은 노드들이 실패 노드에 대한 report를 계속 교환하면서 CPU를 많이 사용할 수 있습니다.
Valkey는 이 영역에서 다음 개선을 누적해왔습니다.
- Slot migration reliability
CLUSTER SETSLOT상태를 replica에 동기적으로 복제하고, failover 이후 slot 이동 상태를 복구해 resharding 중 primary failover가 발생해도 slot routing과 가용성을 더 안정적으로 유지합니다.
- Multiple primary failure recovery 여러 primary가 동시에 실패했을 때 replica election이 충돌하지 않도록 failover를 순차화해 복구를 더 안정적이게 만듭니다.
- Reconnect storm throttling 여러 노드가 동시에 unavailable 상태가 되었을 때 재연결 시도를 제한하여 cluster가 reconnect storm을 겪지 않도록 합니다.
- Failure report tracking optimization failure report 정보를 더 효율적으로 관리해 중복 처리와 만료된 report 정리 비용을 줄입니다.
- Lightweight cluster bus message pub/sub 경로에서 더 가벼운 message header를 사용해 large cluster의 pub/sub traffic overhead를 줄입니다.
Valkey 공식 대규모 벤치마크에서는 2,000-node cluster, 1 primary + 1 replica per shard 구성으로 10억 RPS scale test를 진행했습니다. 이 수치를 일반적인 웹 서비스 캐시 워크로드와 직접 비교할 수는 없지만, Valkey cluster가 대규모 shard 수와 장애 회복 시나리오를 염두에 두고 개선되고 있다는 점은 확인할 수 있습니다.
2-4. 그 밖에 Valkey 9.0의 기능 개선
Valkey 9.0은 I/O와 메모리 개선 위에 파이프라인 처리량, 데이터 만료 방식, 클러스터 모드 유연성을 더했습니다.
주목할 만한 항목은 다음과 같습니다.
- Pipelined workload throughput Command lookup, Memory prefetching, 요청 묶음 처리 개선으로 pipeline 처리에서 최대 40% 처리량 향상을 제공합니다.
- Hash field expiration hash 전체 key가 아니라 개별 field에 TTL을 줄 수 있습니다.
- Numbered databases in cluster mode
cluster mode에서도
SELECT 0–15numbered database를 사용할 수 있어, standalone 환경에서 multi DB를 사용하던 워크로드의 마이그레이션 부담을 줄입니다.
3. 성능 개선이 비용 절감으로 이어지는 지점
ElastiCache에서 Valkey는 Redis OSS 대비 가격 이점이 있습니다. AWS 요금 기준으로 ElastiCache for Valkey는 노드 기반 요금에서 Redis OSS 대비 20% 낮은 가격을 제공하고, 서버리스에서는 다른 지원 엔진 대비 33% 낮은 가격과 더 낮은 최소 데이터 저장 용량을 제공합니다.
이 가격 차이는 캐시 규모가 커질수록 월 비용 차이로 이어집니다. 여기에 Valkey 8/9의 메모리 효율 개선까지 더해지면 추가 최적화 여지도 생깁니다.
예를 들어 같은 keyspace를 더 적은 메모리로 담을 수 있다면 선택지는 두 가지입니다.
- 같은 노드 타입을 유지하고 메모리 여유를 늘린다.
- 안정화 이후 더 작은 노드 타입으로 조정한다.
이번 마이그레이션에서는 두 번째 작업을 바로 묶지 않았습니다. 먼저 엔진 업그레이드와 client 안정성을 검증하고, 이후 관찰된 메모리, CPU, 지연 시간 지표를 기반으로 노드 크기 조정을 별도 단계로 판단하는 전략을 택했습니다.
운영 관점에서 이 분리는 중요합니다. 엔진 업그레이드와 노드 축소를 동시에 진행하면 지연 시간 변화, CPU 변화, eviction 증가, client error spike가 발생했을 때 원인이 엔진인지 용량인지 구분하기 어렵습니다.
4. ElastiCache 인플레이스 업그레이드
ElastiCache에서는 replication group을 수정해 Redis OSS 또는 Valkey 엔진 버전을 업그레이드할 수 있습니다. Redis OSS에서 Valkey로 전환하는 업그레이드도 지원됩니다.

내부적으로는 기존 노드 위에서 바이너리를 교체하는 방식이 아닌, 대상 엔진 버전의 새 노드를 붙이고 기존 primary/replica의 데이터를 복제한 뒤, 새 노드가 기존 노드의 데이터를 따라잡아 replication lag가 0에 가까워지면, ElastiCache가 failover를 수행해 트래픽을 새 노드로 넘깁니다.
이 때문에 endpoint DNS는 유지되지만, 실제 뒤에 있는 노드 IP와 client 연결은 바뀔 수 있습니다. 애플리케이션 입장에서 “endpoint가 그대로다”는 “연결이 끊기지 않는다”를 의미하지 않습니다. 짧은 연결 끊김이 발생할 수 있으므로 client는 이를 재연결과 재시도로 흡수할 수 있어야 합니다.
5. Client에서 확인한 항목
Valkey 성능 이점을 안정적으로 얻으려면 단순히 서버만 올려서는 부족합니다. 실제 운영에서는 client가 업그레이드 안정성을 좌우하게 됩니다.
5-1. 공통 확인 항목
모든 cache client에서 먼저 확인해야 하는 항목은 다음과 같습니다.
- connect timeout과 read timeout이 너무 길거나 짧지 않은가?
- reconnect가 자동으로 수행되는가?
- transient error에 retry가 걸리는가?
- retry에 exponential backoff와 jitter가 있는가?
- persistent connection 또는 connection pool이 failover 이후 stale connection을 계속 재사용하지 않는가?
- upgrade 중 발생 가능한 짧은 error spike가 application error budget 안에 들어오는가?
5-2. Cluster mode 추가 확인 항목
Cluster mode에서는 다음 항목을 추가로 봐야 합니다.
- standalone client가 아니라 cluster client를 사용하는가?
- configuration endpoint를 사용하고 있는가?
- MOVED redirect를 받았을 때 slot map을 refresh하는가?
- ASK redirect를 받았을 때
ASKING후 retry를 수행하는가?
- 같은 slot에 묶어야 하는 key에
{hash-tag}가 설계되어 있는가?
- MGET, MSET, DEL key1 key2, MULTI/EXEC, Lua script 등 multi-key command가 same slot 제약을 만족하는가?
- replica read를 사용하는 경우 READONLY와 stale read 허용 범위가 명확한가?
- pipeline을 여러 node로 보내야 할 때 client가 node/slot별 grouping을 수행하는가?
이 부분은 업그레이드 자체보다 cluster mode migration에서 중요합니다. 하지만 동시에 cluster client 설정을 바꾸는 경우도 많기 때문에, 체크리스트에는 함께 포함하는 편이 좋습니다.
이번 작업에서 진행한 client 설정 예시는 다음과 같습니다.
- connect timeout: 1.5초
- command timeout: 1.5초
- BLPOP 사용시 command timeout 사용하면 위험성 있음
- cluster topology refresh: 15초
- adaptive refresh: 활성화
- reconnect delay: 1초에서 시작해 최대 5초로 제한 (exponential + jitter)
6. 업그레이드 종합 체크리스트
Valkey 업그레이드를 준비한다면 다음 순서로 확인하는 것을 권장합니다.
사전 조사
- 대상 cache의 engine version, node type, shard/replica 수 확인
- cluster mode enabled/disabled 여부 확인
- DB 번호 사용 여부 확인
- TLS 사용 여부 확인
- cache별 영향도 분류
- key command pattern 확인: GET/SET 중심인지, multi-key/Lua/transaction이 많은지
- client library와 version 확인
Client 준비
- reconnect/retry/backoff 동작 확인
- timeout 값 확인
- connection pool stale connection 처리 확인
- failover 중 발생 가능한 error handling 확인
- cluster mode 사용 시 MOVED/ASK, hash tag, same-slot 제약 확인
- replica read 사용 시 stale read 허용 범위 확인
운영 준비
- 트래픽이 낮은 시간대 선정
- upgrade 전 snapshot 확보
- baseline metric 기록: connection, CPU, memory, network, latency, error rate
- application log 준비
- 작업 시작/완료/문제 발생 시 communication path 준비
- rollback 기준과 절차 사전 합의
업그레이드 후 검증
- engine/version 확인
- connection 수 회복 확인
- CPU/memory/network가 baseline 범위로 돌아오는지 확인
- application error spike가 사라지는지 확인
- cache latency와 timeout 증가 여부 확인
- 최소 관찰 기간 후 다음 cache 진행 여부 결정
7. 업그레이드 후 실제 메트릭 변화
이번 업그레이드 대상 중 범용 캐시는 특정 기능 하나에만 묶인 캐시가 아니라, 여러 서비스와 요청 경로에서 사용되는 공용 캐시입니다.
TTL 기반 단기 캐싱, lock, 중복 요청 방지, 임시 저장 등 다양한 목적으로 사용되며, 평소에도 전체 캐시 fleet 중 높은 처리량을 꾸준히 유지하는 클러스터입니다. 따라서 이 캐시는 업그레이드 효과를 관찰하기에 적합한 대표 샘플로 선정했습니다.
7-1. CPU 사용률 변화

7-2. Memory 효율 변화


7-3. GET/SET type command latency 변화


7-4. Connection 회복

8. 결론
돌이켜보면 Redis OSS 6.x에서 Valkey 9.0으로 바로 가는 선택은 생각보다 무리한 도약이 아니었습니다. 겉으로는 버전 숫자가 크게 뛰는 퀀텀점프처럼 보이지만, 판단 근거는 꽤 명확했습니다.
첫째, AWS ElastiCache에서 근무한 경험으로 이 작업의 핵심 리스크는 엔진 자체보다 client와 운영 절차에 있다는 점을 명확히 알고 있었습니다.
둘째, Valkey는 Redis OSS 7.2 계열을 기준으로 갈라진 프로젝트라 기존 Redis 6.x 워크로드가 사용하는 명령과 프로토콜은 자연스럽게 이어받을 수 있습니다. 반대로 Redis 7.4/8.x 이후 Redis 쪽에서 추가된 기능이나 포맷까지 호환된다고 보면 안 됩니다. 이 경계가 오히려 판단을 쉽게 해줬습니다.
결국 이번 전환은 “Redis를 Valkey로 바꾼다”기보다, 이미 검증 가능한 호환성 범위 안에서 비용, 처리량, 메모리 효율, 운영 안정성을 한 번에 끌어올리는 작업에 가까웠습니다. 그래서 엔진 업그레이드와 노드 조정은 분리하고, 낮은 영향도의 캐시부터 검증해 나가면 Redis 6.x에서 Valkey 9.0으로의 점프도 충분히 현실적인 선택이 됩니다.
참고자료
이승민B SRE Engineer
서비스 성능 병목을 분석하고 안정적으로 개선하는 일을 즐깁니다.
