Redis Cluster 정리, Predixy 역할과 필요한 경우 이해하기 (4)

Predixy는 왜 쓰는 걸까?

앞선 글에서는 Redis Cluster의 기본 구조를 정리했다.

Redis Cluster는 key를 Hash Slot으로 나누고, 각 Master 노드가 slot을 나눠 가진다.
그리고 Master에 장애가 발생하면 Replica가 새로운 Master로 승격될 수 있다.

여기까지 보면 Redis Cluster만으로도 충분해 보인다.

그런데 실제로 Redis Cluster를 애플리케이션에 붙이려고 하면 또 다른 고민이 생긴다.

애플리케이션이 Redis Cluster 구조를 직접 알아야 할까?
모든 서비스가 Cluster Client를 써야 할까?
Redis 노드가 바뀌면 애플리케이션 설정도 바꿔야 할까?
Cluster를 지원하지 않는 라이브러리나 툴은 어떻게 연결할까?
 

이런 고민이 나올 때 Redis Cluster 앞단에 둘 수 있는 프록시가 있다.

그중 하나가 Predixy다.

Predixy란?

Predixy는 Redis 앞단에 두는 프록시 서버다.

공식 GitHub 설명에 따르면 Predixy는 Redis Sentinel과 Redis Cluster를 지원하는 고성능 Redis Proxy다. Redis Cluster뿐 아니라 Sentinel, 단일/다중 Redis 그룹, Pub/Sub, SCAN, 일부 multi-key 명령어, latency monitor 등도 지원한다고 소개되어 있다.

구조는 간단하게 보면 이렇다.

App Server
   |
Predixy
   |
Redis Cluster
 

애플리케이션은 Redis Cluster의 각 노드로 직접 붙는 대신 Predixy로 요청을 보낸다.

기존 Redis Cluster 직접 연결:
App -> Redis Node A
App -> Redis Node B
App -> Redis Node C

Predixy 사용:
App -> Predixy -> Redis Cluster
 

즉 Predixy는 애플리케이션과 Redis Cluster 사이에서 중간 다리 역할을 한다.

Predixy를 쓰면 뭐가 편할까?

Redis Cluster를 직접 사용하려면 애플리케이션의 Redis 클라이언트가 Cluster를 지원해야 한다.

예를 들어 Go에서는 go-redis의 NewClusterClient 같은 것을 사용할 수 있다.

rdb := redis.NewClusterClient(&redis.ClusterOptions{
    Addrs: []string{
        "redis-1:6379",
        "redis-2:6379",
        "redis-3:6379",
    },
})
 

이 방식은 Redis Cluster를 제대로 지원하는 클라이언트를 쓰는 경우에는 가장 일반적이고 깔끔하다.

그런데 모든 환경이 이렇게 편한 것은 아니다.

어떤 서비스는 오래된 Redis 클라이언트를 사용하고 있을 수 있다.
어떤 배치 프로그램이나 관리 도구는 Redis Cluster를 제대로 지원하지 않을 수도 있다.
또 여러 애플리케이션에서 Redis Cluster 노드 정보를 각각 관리하는 것이 부담스러울 수도 있다.

이럴 때 Predixy를 앞단에 두면 애플리케이션은 Redis Cluster 구조를 직접 몰라도 된다.

App은 Predixy 주소만 바라본다.
Predixy가 Redis Cluster 쪽으로 요청을 전달한다.
 

애플리케이션 입장에서는 단일 Redis에 붙는 것처럼 보일 수 있다.

App -> predixy:7617
 

Predixy가 내부적으로 Redis Cluster와 통신하면서 key에 맞는 노드로 요청을 보내는 방식이다.

Redis Cluster Client와 Predixy의 차이

Redis Cluster를 사용하는 방식은 크게 두 가지로 볼 수 있다.

1. 애플리케이션이 Redis Cluster Client를 직접 사용한다.
2. 애플리케이션은 Predixy에 붙고, Predixy가 Redis Cluster와 통신한다.
 

첫 번째 방식은 애플리케이션이 Redis Cluster 구조를 알고 있는 방식이다.

App
 |
Cluster Client
 |
Redis Cluster
 

두 번째 방식은 Predixy가 중간에서 Redis Cluster 구조를 감싸는 방식이다.

App
 |
Predixy
 |
Redis Cluster
 

차이를 정리하면 이렇다.

구분 Cluster Client Predixy
구조 App이 Cluster를 직접 인식 App은 Predixy만 인식
클라이언트 요구사항 Cluster 지원 필요 일반 Redis Client도 사용 가능
요청 경로 App -> Redis Cluster App -> Predixy -> Redis Cluster
설정 관리 각 App에서 노드 관리 Predixy 중심으로 관리
장애 지점 App과 Redis Predixy가 추가 장애 지점
성능 프록시 홉 없음 프록시 홉 추가

즉 Predixy를 쓰면 편해지는 부분이 있지만, 중간 프록시가 하나 더 생긴다는 점도 같이 봐야 한다.

Predixy가 필요한 경우

Predixy가 유용한 경우는 꽤 명확하다.

1. Redis Cluster를 지원하지 않는 클라이언트를 써야 할 때

가장 대표적인 경우다.

애플리케이션이나 도구가 Redis Cluster를 지원하지 않는다면 Redis Cluster에 직접 붙기 어렵다.

이때 Predixy를 앞단에 두면 애플리케이션은 Predixy에만 연결하면 된다.

Cluster 미지원 Client -> Predixy -> Redis Cluster
 

이렇게 하면 기존 Redis Client를 크게 바꾸지 않고 Redis Cluster 뒤에 붙일 수 있다.

2. 여러 서비스에서 Redis Cluster 설정을 관리하기 부담스러울 때

서비스가 여러 개라면 각 서비스마다 Redis Cluster 노드 목록을 관리해야 한다.

Service A -> redis-1, redis-2, redis-3
Service B -> redis-1, redis-2, redis-3
Service C -> redis-1, redis-2, redis-3
 

노드가 추가되거나 변경될 때 각 서비스 설정을 모두 신경 써야 할 수 있다.

Predixy를 사용하면 서비스들은 Predixy 주소만 바라보게 만들 수 있다.

Service A -> Predixy
Service B -> Predixy
Service C -> Predixy
 

Redis Cluster의 세부 구성은 Predixy 쪽에서 관리한다.

3. 운영상 Redis 접속 지점을 단순화하고 싶을 때

운영 환경에서는 접속 지점을 단순화하는 것이 도움이 될 때가 있다.

예를 들어 애플리케이션 입장에서는 Redis Cluster 노드 여러 개를 몰라도 되고, Predixy 주소만 알고 있으면 된다.

REDIS_ADDR=predixy.internal:7617
 

이렇게 되면 설정이 단순해진다.

4. Redis Cluster 앞단에서 권한, 통계, 로그 등을 보고 싶을 때

Predixy는 단순 전달만 하는 프록시가 아니라 권한 제어, keyspace 제한, 요청/응답 통계, latency monitor 같은 기능도 제공한다고 소개되어 있다.

물론 이 기능들을 실제 운영에서 얼마나 쓸지는 환경마다 다르다.

하지만 Redis 요청을 한 지점에서 관찰하거나 제어하고 싶다면 프록시 구조가 도움이 될 수 있다.

Predixy가 꼭 필요한가?

결론부터 말하면 꼭 필요한 것은 아니다.

특히 새로 만드는 서비스이고, 사용하는 Redis 클라이언트가 Redis Cluster를 제대로 지원한다면 Predixy 없이 직접 붙는 것이 더 단순할 수 있다.

예를 들어 Go에서 go-redis ClusterClient를 사용하고 있다면 굳이 Predixy를 추가하지 않아도 된다.

App -> Redis Cluster
 

이 구조가 더 단순하다.

프록시가 없으니 네트워크 홉도 하나 줄고, 장애 지점도 줄어든다.

Predixy를 넣으면 구조가 이렇게 된다.

App -> Predixy -> Redis Cluster
 

중간에 Predixy가 추가되기 때문에 Predixy 자체도 관리해야 한다.

- Predixy 장애 대응
- Predixy 이중화
- Predixy 설정 관리
- Predixy 모니터링
- Predixy 성능 확인
 

즉 Predixy는 Redis Cluster를 편하게 만들어주는 도구이지만, 운영 요소가 하나 더 생긴다는 점을 무시하면 안 된다.

Predixy를 쓰면 안 좋은 점도 있을까?

있다.

가장 먼저 생각할 점은 프록시가 추가된다는 것이다.

요청 경로가 하나 더 늘어난다.

직접 연결:
App -> Redis Cluster

Predixy 사용:
App -> Predixy -> Redis Cluster
 

요청이 Predixy를 한 번 거쳐야 하므로 지연 시간이 조금이라도 추가될 수 있다.

또 Predixy가 장애나 병목 지점이 될 수도 있다.

그래서 Predixy를 쓴다면 Predixy도 이중화해야 한다.

App
 |
Load Balancer
 |
Predixy 1, Predixy 2
 |
Redis Cluster
 

또 하나 봐야 할 점은 프로젝트 유지보수 상태다.

Predixy GitHub releases 페이지에는 1.0.1 릴리스가 deprecated로 표시되어 있고, 최근 활발한 릴리스가 많은 프로젝트처럼 보이지는 않는다.

그래서 운영 도입 전에는 반드시 현재 환경에서 충분히 테스트해야 한다.

- 사용하는 Redis 버전과 잘 맞는지
- 사용하는 명령어가 정상 동작하는지
- 장애 상황에서 어떻게 동작하는지
- 성능 병목이 생기지 않는지
- 모니터링과 로그를 어떻게 볼 것인지
 

특히 Redis Cluster의 모든 동작을 완벽하게 감싸주는 마법 같은 도구라고 생각하면 안 된다.

프록시는 프록시일 뿐이고, Redis Cluster의 특성과 제약은 여전히 이해하고 있어야 한다.

Predixy를 쓰는 게 좋은 경우와 아닌 경우

개인적으로는 이렇게 나눠서 생각하면 좋을 것 같다.

Predixy를 고려해볼 만한 경우

- 기존 코드가 Redis Cluster Client로 바꾸기 어려운 경우
- 여러 서비스가 Redis Cluster에 붙어 있고 설정을 단순화하고 싶은 경우
- Redis Cluster를 지원하지 않는 도구나 라이브러리를 써야 하는 경우
- Redis 접속 지점을 프록시로 통일하고 싶은 경우
- Redis 앞단에서 요청 통계나 권한 제어를 일부 활용하고 싶은 경우
 

Predixy 없이 직접 붙는 게 나을 수 있는 경우

- 새로 만드는 서비스라 Cluster Client를 바로 사용할 수 있는 경우
- Go, Java, Python 등에서 안정적인 Redis Cluster Client를 쓰는 경우
- 프록시 운영 부담을 늘리고 싶지 않은 경우
- 요청 지연을 최대한 줄이고 싶은 경우
- 장애 지점을 최소화하고 싶은 경우
 

즉 Predixy는 필수 구성 요소라기보다는, Redis Cluster를 더 쉽게 사용하기 위한 선택지에 가깝다.

서버 3대 Redis Cluster에 Predixy를 붙이면 구조는?

앞선 3편에서 서버 3대로 Redis Cluster를 구성하는 예시를 봤다.

Server 1: Master A + Replica C
Server 2: Master B + Replica A
Server 3: Master C + Replica B
 

여기에 Predixy를 붙이면 이런 구조가 된다.

App Server
   |
Predixy
   |
Redis Cluster
   |
Server 1: Master A + Replica C
Server 2: Master B + Replica A
Server 3: Master C + Replica B
 

운영에서는 Predixy도 한 대만 두기보다는 이중화하는 것이 좋다.

App Server
   |
Load Balancer
   |
+-----------+-----------+
| Predixy 1 | Predixy 2 |
+-----------+-----------+
   |
Redis Cluster
 

그래야 Predixy 한 대가 죽어도 Redis Cluster 접근이 완전히 막히지 않는다.

Redis Cluster를 고가용성으로 만들어놓고 Predixy를 한 대만 두면, 오히려 Predixy가 단일 장애 지점이 될 수 있다.

결론

Predixy는 Redis Cluster 앞단에 둘 수 있는 Redis Proxy다.

애플리케이션이 Redis Cluster 구조를 직접 알지 않아도 되게 해주고, Cluster를 지원하지 않는 클라이언트나 도구를 사용할 때 도움이 될 수 있다.

하지만 무조건 필요한 것은 아니다.

Redis Cluster를 제대로 지원하는 클라이언트를 사용할 수 있다면, 애플리케이션이 Redis Cluster에 직접 붙는 구조가 더 단순할 수 있다.

정리하면 이렇게 볼 수 있다.

Redis Cluster Client 사용 가능
-> 굳이 Predixy 없이 직접 연결해도 됨

Redis Cluster Client 사용이 어렵거나 접속 지점을 단순화하고 싶음
-> Predixy 고려 가능
 

Predixy를 도입한다면 Predixy 자체도 운영 대상이 된다.

그래서 단순히 “Redis Cluster 앞에 프록시 하나 두면 편하겠네” 정도로만 보면 안 된다.

Predixy 장애 대응, 이중화, 모니터링, 성능 테스트까지 같이 봐야 한다.

결국 Predixy는 Redis Cluster를 대체하는 기술이 아니라, Redis Cluster를 더 편하게 사용하기 위한 프록시 선택지다.

Redis Cluster의 원리를 이해한 뒤, 내 애플리케이션 구조에서 정말 필요한지 판단하는 것이 가장 중요하다.

작업 기록과 샘플 코드는 GitHub에도 정리해두고 있어요.

GitHub 팔로우

Continue Reading

이전 글 / 다음 글