Redis가 7.4부터 RSALv2 와 SSPL 이중 라이선스로 바뀐 뒤로, 캐시 서버 하나 올릴 때마다 라이선스 조항을 들여다보게 됐다. 그 틈에 Linux Foundation 산하로 포크된 Valkey가 BSD로 나왔고, 현장에서도 교체 문의가 다시 늘었다. 마침 운영 중인 Redis 몇 대를 손볼 일이 생겨서, 서비스를 세우지 않고 옮기는 방법을 정리해 둔다.
결론부터 말하자면, Valkey를 기존 Redis의 복제본으로 붙여(replicaof) 데이터를 실시간으로 받아 온 뒤, 애플리케이션 접속을 Valkey로 돌리고 REPLICAOF NO ONE으로 승격하면 된다. 다만 이 방법은 소스 Redis가 OSS 2.x~7.2.x일 때만 안전하다. Redis CE 7.4 이상이 만든 RDB 파일은 Valkey가 읽지 못하기 때문이다. 그래서 작업 전 버전 확인이 전부라고 해도 과언이 아니다.
Valkey와 replicaof가 무엇인가
Valkey는 Redis 7.2.4 시점을 기준으로 갈라져 나온 오픈소스 키-값 저장소다. RESP 프로토콜, 명령어 집합, 설정 지시자, RDB와 AOF 파일 형식까지 Redis OSS 7.2와 호환되도록 유지한다. 즉 Redis 7.2를 쓰던 클라이언트와 설정을 거의 그대로 가져갈 수 있다.
replicaof(옛 이름 slaveof)는 한 서버를 다른 서버의 복제본으로 만드는 명령이다. 복제본은 프라이머리에 붙는 순간 전체 데이터셋을 한 번 받아 온 뒤(풀 동기화), 이후 프라이머리가 받는 쓰기 명령을 스트림으로 계속 넘겨받는다. Redis와 Valkey가 같은 복제 프로토콜을 쓰기 때문에, Valkey를 Redis의 복제본으로 붙이는 교차 복제가 성립한다. 이 성질이 무중단 마이그레이션의 핵심이다.
먼저 Redis 버전을 확인한다
작업을 시작하기 전에 소스 Redis 버전부터 본다. 여기서 갈린다.
$ redis-cli INFO server | grep redis_version redis_version:7.2.5
Valkey 공식 문서는 복제 호환 범위를 Redis OSS 2.x ~ 7.2.x로 못 박는다. 그리고 Redis CE 7.4 이상이 만든 데이터 파일은 Valkey가 적재하지 못한다고 명시한다. 풀 동기화는 프라이머리가 스냅샷(RDB)을 만들어 복제본에 넘기는 방식이라, 소스가 7.4 이상이면 Valkey 쪽에서 RDB 적재가 실패하고 복제가 붙지 않는다.
다행히 라이선스 변경을 이유로 떠나려는 쪽은 BSD 라이선스였던 마지막 버전인 7.2.x에 머물러 있는 경우가 많다. 그렇다면 replicaof 방식이 그대로 통한다. 이미 7.4 이상으로 올라가 버렸다면 이 방법은 쓸 수 없고, DUMP/RESTORE 기반의 키 단위 복사나 valkey-cli --cluster 계열 도구 같은 다른 경로를 검토해야 한다.
Valkey 8 설치와 설정 호환성 점검
Valkey 8 계열(이 글 기준 8.1.x) 패키지를 설치한다. 데비안, 우분투라면 공식 저장소나 배포판 패키지로 올린다.
$ valkey-server --version Valkey server v=8.1.10 sha=00000000:0 malloc=jemalloc bits=64 build=...
설정 파일은 기존 redis.conf를 그대로 복사해 valkey.conf로 써도 대부분 동작한다. 지시자 이름이 같기 때문이다. 다만 몇 가지는 눈으로 확인해야 한다.
bind와protected-mode: 복제본이 프라이머리에 접속해야 하므로, 프라이머리 쪽이 복제본 IP의 접속을 허용하는지 확인한다.requirepass: 소스 Redis에 비밀번호가 걸려 있으면, 복제본 쪽에masterauth(Valkey는primaryauth로도 받는다)로 같은 값을 넣어야 풀 동기화가 인증을 통과한다.appendonly,save: 영속성 정책은 승격 이후 Valkey가 프라이머리로서 지킬 값이므로, 운영 기준에 맞춰 둔다.replica-read-only: 기본값이 활성이다. 복제본으로 붙어 있는 동안 Valkey는 읽기 전용이 된다. 이 상태에서 애플리케이션 쓰기를 Valkey로 보내면 거부되니, 전환 순서를 지켜야 한다.
참고로 소스 Redis가 쓰던 모듈이나 Redis CE 전용 명령(일부 신규 자료구조 등)을 썼다면, 그 부분은 Valkey에서 지원 여부를 따로 확인해야 한다. 순수 캐시, 세션, 간단한 자료구조 용도라면 걸릴 일이 거의 없다.
replicaof로 동기화 시작
Valkey를 띄운 뒤, Valkey의 valkey-cli에서 소스 Redis를 가리켜 복제를 건다. 프라이머리 주소와 포트를 넣는다.
$ valkey-cli -p 6380 127.0.0.1:6380> REPLICAOF 10.0.1.10 6379 OK
비밀번호가 걸린 프라이머리라면 복제를 걸기 전에 인증 값을 먼저 설정하거나 valkey.conf에 masterauth를 넣어 둔다.
127.0.0.1:6380> CONFIG SET masterauth "소스Redis비밀번호" OK 127.0.0.1:6380> REPLICAOF 10.0.1.10 6379 OK
설정 파일에 미리 넣어 두고 싶으면 valkey.conf에 다음 한 줄을 적고 Valkey를 시작해도 된다. 런타임 명령과 효과는 같다.
replicaof 10.0.1.10 6379
동기화 상태 확인
복제가 붙었는지는 INFO REPLICATION으로 본다. 처음엔 master_sync_in_progress:1로 풀 동기화가 돌고, 데이터 크기에 따라 수 초에서 수십 초 뒤 master_link_status:up으로 바뀐다.
127.0.0.1:6380> INFO REPLICATION # Replication role:slave master_host:10.0.1.10 master_port:6379 master_link_status:up master_last_io_seconds_ago:0 master_sync_in_progress:0 slave_read_repl_offset:1899240 slave_repl_offset:1899240
master_link_status:up이 뜨고 master_sync_in_progress:0이면 초기 적재가 끝나 스트림만 따라가는 상태다. 프라이머리 쪽에서 INFO REPLICATION을 보면 connected_slaves:1과 복제본의 오프셋이 보인다. 양쪽 slave_repl_offset 값이 붙어 따라가면 지연이 거의 없다는 뜻이다.
간단한 검증으로, 소스 Redis에 키 하나를 넣고 Valkey에서 바로 읽히는지 확인한다.
$ redis-cli -h 10.0.1.10 SET canary:1 ok OK $ valkey-cli -p 6380 GET canary:1 "ok"
클라이언트 전환과 승격
여기서 순서가 중요하다. 복제본은 읽기 전용이므로, 동기화가 붙어 있는 동안 애플리케이션 쓰기를 Valkey로 보내면 안 된다. 전환은 다음 순서로 한다.
- Valkey가
master_link_status:up으로 안정화됐는지 확인한다. - 소스 Redis로 가는 쓰기를 잠시 멈추거나, 애플리케이션 접속 대상을 Valkey로 바꾸기 직전에 소스 Redis를 읽기 전용으로 두는 식으로 쓰기 창을 줄인다.
- 애플리케이션 접속 문자열(호스트, 포트)을 Valkey로 바꾼다. RESP 프로토콜이 같아서 Jedis, Lettuce, redis-py 같은 기존 클라이언트는 코드 변경 없이 접속된다.
- Valkey에서
REPLICAOF NO ONE을 실행해 복제를 끊고 프라이머리로 승격한다. 이 순간부터 Valkey가 쓰기를 받는다.
127.0.0.1:6380> REPLICAOF NO ONE OK 127.0.0.1:6380> INFO REPLICATION # Replication role:master connected_slaves:0 master_replid:8f3a... master_repl_offset:1899240
role:master와 connected_slaves:0이 보이면 승격이 끝났다. 쓰기 창을 더 줄이고 싶으면, 접속 전환과 REPLICAOF NO ONE 사이 간격을 최소화하거나, 프라이머리를 바라보는 접속 설정을 로드밸런서나 DNS로 돌려 한 번에 끊는 방법을 쓴다. 마지막으로 소스 Redis를 SHUTDOWN으로 내린다. 이 작업은 되돌릴 수 있도록, Redis를 바로 지우지 말고 며칠 두고 Valkey가 안정적으로 쓰기를 받는지 지켜본 뒤 폐기하는 편을 권한다.
흔히 걸리는 함정
RDB 적재 실패. 소스가 Redis 7.4 이상이면 풀 동기화 중 Valkey 로그에 RDB 형식 비호환으로 적재가 실패한다. 복제가 master_link_status:down에서 넘어가지 못한다. 이 경우 replicaof 경로를 포기하고 키 단위 복사로 바꿔야 한다.
인증 누락. 프라이머리에 requirepass가 걸렸는데 masterauth를 안 넣으면 풀 동기화가 인증 단계에서 끊긴다. Valkey 로그에 MASTER aborted replication 또는 인증 거부 메시지가 남는다.
쓰기를 복제본에 보냄. 전환 중 애플리케이션 쓰기가 아직 복제 상태인 Valkey로 가면 READONLY You can't write against a read only replica. 오류가 난다. 접속 전환과 승격 순서를 지키면 피할 수 있다.
방화벽. 복제본에서 프라이머리의 6379 포트로 아웃바운드가 막혀 있으면 복제가 붙지 않는다. 보안그룹, iptables, protected-mode를 함께 확인한다.
마무리
Redis 7.2 이하라면 Valkey 8로의 이전은 특별한 도구 없이 replicaof, INFO REPLICATION, REPLICAOF NO ONE 세 가지로 끝난다. 프로토콜과 파일 형식이 7.2 호환이라 클라이언트도 손대지 않는다. 작업의 성패는 사실상 소스 버전 확인 하나에 달려 있다. 7.4 이상으로 이미 올라간 환경이라면 복제 경로를 쓸 수 없다는 점만 기억하면 된다.