Redis cluster 튜토리얼

TL;DR

코드는 여기1

시작하며

기존엔 redis 를 대규모로 쓰려면 sentinel 로 master-slave 를 구성하고 각 마스터들을 twemproxy 로 묶어서 샤딩할 수 밖에 없었다.

그러나 twemproxy 의 구조상 redis-cli 를 이용하여 콘솔에서 특정한 작업을 처리하는 것은 굉장히 귀찮은 작업이고, 무엇보다 twemproxy 는 유지보수를 안한지 오래되어 더 이상 쓰기가 좀 꺼려진다.

redis 3.0 부터 도입된 redis-cluster 를 쓰면 샤딩없이 redis 를 HA 하게 만들 수 있다.

cluster 이므로 sentinel 을 쓰지 않아도 되어 아키텍처가 간단해 지는 것은 덤.

redis-cluster 를 이용하여 클러스터를 구축하고

redis-cluster 용 proxy 인 predixy 를 이용하여 redis-cli 에서 쉽게 작업할 수 있는 환경을 구축해보자.

redis-cluster 특징

요즘 나오는 일반적인 클러스터 서비스의 특징을 다 갖추고 있다. (docker 안되는거 빼고)

redis-cluster 구성

클러스터 구성방법은 여기2 에 잘 나와있으므로 생략한다.

proxy 설정

클러스터 구성 후 아무 노드나 redis-cli 로 들어가서 get/set 해보면 키가 샤딩된 노드에 맞춰 커넥션이 이리저리 redirection 된다.

클라이언트가 직접 사용한다면 얼핏봐도 엄청난 오버헤드가 있을 것 같은 일이므로 프록시를 앞에 두고 클라이언트는 프록시랑만 통신하도록 하자.

redis-cluster proxy 로 검색해서 이리저리 보다 보면 결국 codis, corvus, predixy 3개로 압축된다. (star 순서대로)

개인적으로는 Predixy3 라는 녀석을 쓰기로 했는데 codis 는 기능이 너무 많고, corvus 는 관리가 안되고 있는 느낌이 들기 때문이다.

설치는 엄청 쉽다. 그냥 받아서 g++ 로 make 해버리면 된다. 하지만 요즘 이런 툴들은 내 컴에 깔기보다 도커로 까는 것이 낫다. 그래서 docker4 로 구워놨다. (용량을 줄이기 위해 alpine 으로 구우려고 했으나 musl glibc 와 리눅스용 glibc 가 함수 시그너처가 다른게 많아서 안구워져서 그냥 ubuntu 로 구웠다.)

여튼 일단 프로젝트를 클로닝한다.

$ git clone https://github.com/haandol/predixy
$ cd predixy

자신의 redis-cluster 구성대로 conf 아래의 cluster.conf, predixy.conf 를 수정한다. servers 만 바꿔주면 된다. (앞의 + 는 오타가 아니며 꼭 붙여줘야함.)

# conf/cluster.conf
ClusterServerPool {
    MasterReadPriority 60
    StaticSlaveReadPriority 50
    DynamicSlaveReadPriority 50
    RefreshInterval 1
    ServerTimeout 1
    ServerFailureLimit 10
    ServerRetryTimeout 1
    KeepAlive 120
    Servers {
        + 127.0.0.1:7001
        + 127.0.0.1:7002
        + 127.0.0.1:7003
    }
}

# conf/predixy.conf
Name PredixyExample
Bind 0.0.0.0:7617
WorkerThreads 4
MaxMemory 0
ClientTimeout 300
BufSize 4096
Log ./predixy.log
LogRotate 1d
LogVerbSample 0
LogDebugSample 0
LogInfoSample 10000
LogNoticeSample 1
LogWarnSample 1
LogErrorSample 1

Include auth.conf
Include cluster.conf
Include latency.conf

수정후 아래의 명령으로 실행해본다.

$ docker-compose up -d

별 에러메시지가 없다면 실행된 상태임. 셸을 새로 띄워서 접속해보자.

$ redis-cli -p 7617 info
# Proxy
Version:1.0.5-pre
Name:PredixyExample
Bind:0.0.0.0:7617
...
 
# Servers
Server:127.0.0.1:7000
Role:master
Group:7921290b7deb00d57650357fe73c3fa03f54e209
DC:
CurrentIsFail:1
Connections:4
Connect:405
Requests:829
Responses:22
SendBytes:488
RecvBytes:9095
 
Server:127.0.0.1:7001
Role:master
Group:f2bf617ccf931843539083bdfa4ef54decd16188
DC:
CurrentIsFail:0
Connections:4
Connect:4
Requests:164
Responses:164
SendBytes:4496
RecvBytes:114951
...
 
LatencyMonitorName:blist

마치며

twemproxy 에 비해 안정적이고 설정도 간편하다. 이미 대규모 서비스 들에서 잘 쓰고 있다고 하고, redis 를 쓸거면 대안이 없기도 하다. (dynomite 같은 걸로 옮겨가면 몰라도)

단점은 redis 들을 host=net 으로 띄워야 한다는 것인데, 포트를 적절히 열어주는 것이 sentinel 설정하고 관리하는 거보다는 쉽기 때문에 극복할 수 있다.