rdb를 이용한 마이그레이션, 클러스터간의 마이그레이션을 할 일이 있어서, 간단히 redis-trib을 이용해서 옮기려고 했다. 하지만 버전간의 차이, 인증, 소요 시간 등의 문제로 일이 간단하지 않아 다른 솔루션을 찾다가 RedisShake라는 것을 발견했다. 대충 살펴보니 rdb 포맷의 파일이나 스트림(sync/psync)을 읽어 다른 redis로 옮기는 것 같은데, 목적에 잘 부합하는 것 같아 테스트해보기로 했다. 구현 방식은 나중에 알아보기로 하고, 일단은 내가 필요한 요구 조건을 맞춰줄 수 있는지 테스트/검증을 해보기로 한다.
설치는 간단하다. 아래 경로에서 패키지를 다운받아 압축을 풀고 사용하면 된다. 현 시점에서 최신인 2.0.3 버전을 다운받아 사용했다.
https://github.com/alibaba/RedisShake/releases
https://github.com/alibaba/RedisShake/releases/download/release-v2.0.3-20200724/redis-shake-v2.0.3.tar.gz
주의
아직 이슈가 보고된 것 같지는 않은데, 2.0.3 패키지 내에는 hypervisor 바이너리 파일이 존재하지 않아, start.sh
실행시에 이러한 에러가 발생한다.
./start.sh: line 20: ./hypervisor: No such file or directory
이 경우, github에서 scripts/hypervisor.c
파일의 내용을 복사해 redis-shake 디렉터리에 만들고, 소소 코드 내에서 안내된 주석처럼 컴파일해서 사용하면 된다. 커밋 히스토리를 살펴보면, hypervisor.c의 수정은 최초 파일이 작성/추가되었을 때 이외에는 없는 것으로 보이기 때문에, 직접 컴파일해서 사용해도 호환성등의 문제가 없을 것 같다.
gcc -Wall -O3 hypervisor.c -o hypervisor
관련 이슈
클러스터간의 데이터를 동기화 시켜본다. redis-shake를 사용할 때에는inline으로 필요한 옵션을 전달하는 것이 아닌, config 필요한 옵션을 모두 기입해서 사용하는 형태다. 클러스터 간의 데이터 동기화에서 요구되는 옵션은 wiki의 튜토리얼을 참고하여 작성한다.
# current configuration version, do not modify.
conf.version = 1
# id
id = redis-shake
log.file = /var/log/redis-shake.log
log.level = info
pid_path = /var/run/
system_profile = 9310
http_profile = 9320
parallel = 32
source.type = cluster
source.address = master@__source_ip__:__source_port__
source.password_raw = 123456
source.auth_type = auth
target.type = cluster
target.address = master@__target_ip__:__target_port__
target.password_raw = 123456
target.auth_type = auth
key_exists = rewrite
standalone
, sentinel
, proxy
등이 지정 가능하다.@
를 함께 지정하면, 자동으로 클러스터 구성 노드 전체를 식별해서 주소를 찾아준다.none
으로 동일 키가 존재시 동기화가 중단되고 에러가 발생. rewrite
는 말그대로 덮어쓰는 것. 이외에도 ignore
를 지정하여 에러를 무시하는 것도 가능.start
./start.sh redis-shake.conf sync
stop
./stop.sh /var/run/redis-shake.pid
redis-shake가 시작되면, 원본 redis 노드에 접근하여 replica 행세?를 한다. 즉, replica로서 원본 redis에 접근하여 일반적인 리플리케이션과 동일한 흐름으로 psync를 통하여 스냅샷을 전달받아 파싱하고, 이를 대상 redis로 전달(full synchronization)하고, 그 이후 발생하는 변경 사항에 리플리케이션 스트림으로 지속적으로 동기화(incremental synchronization)를 시킨다.
# CLIENT LIST의 출력 결과
id=503 addr=127.0.0.1:48706 fd=15 name= age=0 idle=0 flags=S db=0 sub=0 psub=0 multi=-1 qbuf=0 qbuf-free=0 obl=0 oll=0 omem=0 events=r cmd=psync
# INFO REPLICATION
slave0:ip=127.0.0.1,port=9320,state=online,offset=398242826,lag=0
redis-shake에는 sync
이외에도 rdb파일을 읽어 대상 redis에 복원시키는 restore
기능도 존재하는데, 결국 이는 sync
커맨드의 full synchronization 부분만을 이용하여 복원시키는 형태가 되는 것 같다.
alicloud에서 내/외부 redis간의 데이터 동기화 등을 위해서 만든 툴인 것 같은데, 아주 효용이 높은 것 같다. 원본과 대상의 데이터를 realtime으로 맞춰준다!는 점은 정말 매력적이다. redis 운영시 필요하지 않을까 했었던 기능들인데 이미 잘 구현이 되어 있는듯 하여, 잘 활용하면 실무에 많은 도움이 될 것 같다.
특히, redis 클러스터를 사용할 때, rdb 스냅샷 파일들을 백업 용도로 보존해두다가 복원할 필요가 있을 때, 슬롯 구성이 다른 상황에서 클러스터에 복원하려고 하면 여간 귀찮은 일이 아닌데, redis-shake를 이용하면 정말 쉽게 해결될 수 있을 것 같다.