본문 바로가기
빅테크 글 읽기

[Toss Tech] 토스 서비스를 구성하는 서버 기술 소개

by sangyunpark99 2025. 3. 27.

이번 글은 Toss Tech에서 발표한 "토스 서비스를 구성하는 서버 기술 소개"을 정리했습니다.

 

출처 : https://toss.im/slash-21/sessions/1-3

 

토스 서비스를 구성하는 서버 기술

Active-Active 데이터센터 운영, Kubernetes와 Istio Service Mesh 운영, API-Gateway, Kafka, Redis, Monitoring Stack 등 토스에서 사용하는 전반적인 기술과 시스템 구성을 공유합니다.

toss.im

 

 

토스에서 서비스를 구성하는 서버 기술

 

이미지 출처 : toss tech

 

토스는 데이터센터 이중화로 2개의 데이터 센터에서 Active-Active로 서비스를 운영중이고, AWS 일부를 사용합니다.

 

토스는 두 개의 물리적인 데이터 센터를 동시에 운영하면서 서비스를 제공하고 있습니다.
이러한 구조를 Active-Active 구조라 하고, 이는 두 데이터 센터 모두 동시에 요청하는 것을 의미합니다.
즉, 하나의 데이터 센터가 죽어도 다른 하나가 계속 서비스할 수 있어서 장애 대응이 가능합니다.

 

이미지 출처 : toss tech

 

토스는 MSA로 구성이 되어 있어 많은 서버가 뜨게 됩니다.

많은 서버를 잘 관리하고 효율적인 인프라 활용을 위해 Kubernates를 Container orchestration으로 사용합니다.

caliico cni와 service mesh로 istio를 사용합니다. 또한 민감자료 저장 용도로 Ceph를 사용해서 내부 스토리지 서비스를 제공해줍니다.

 

컨테이너 오케스트라는 MSA 환경으로 인해 수십-수백 개가 떠있는 컨테이너들을 자동으로 배치하고, 상태를 체크하고, 죽으면 다시 살리고, 로드밸런싱까지 해주는 도구입니다. 대표적인 도구로는 쿠버네티스가 있습니다.

컨테이너는 네트워크 연결도 필요한데, 쿠버네티스에는 기본적으로 네트워크를 연결하는 기능이 없습니다. 따라서 네트워크를 붙여주는 플러그인이 필요한데, 이를 CNI라고 합니다. 즉,Callico는 컨테이너들 사이의 네트워크 연결을 안전하고 빠르게 해주는 도구입니다.

MSA 환경에서 서비스 간 통신이 엄청 많기 때문에, 이를 일일히 개발자가 관리하기 힘듭니다.
그래서 서비스들 간의 통신, 보안, 로깅, 트래픽 제어 등을 도와주는 미들웨어가 Service Mesh 입니다.
즉, Istio는 대표적인 Service Mesh 도구 입니다.

 

이미지 출처 : toss tech

 

이전엔 Memcached를 캐시로 많이 사용했었는데, 데이터 보존 문제와 Optimistic Lock 구현 편의성 때문에 Redis cluster를 캐시로 이용합니다.

Kafka는 로그 데이터 파이프라인으로 사용하는 로그용 클러스터 하나, 서비스에서 메시지 큐를 사용하는 클러스터 하나로 사용합니다.

모니터링은 ELK + filebeat, thanos, grafana를 사용하고 있습니다.

ELK는 로그 모니터링에 사용됩니다.
Elasticsearch는 로그를 저장하고 검색하는 DB이고, Logstash는 로그를 수집하고 가공합니다. 요즘엔 Filebeat으로 대체되었습니다. Kibana는 로그를 시각화해서 보여주는 웹 화면입니다.
Filebeat은 서버에 설치되어 로그 파일을 읽어서 ELK로 전송해주는 역할을 합니다.

Thanos + Grafana는 매트릭 기반 모니터링, 즉 수치 기반 모니터링을 위한 도구 입니다.
Thanos는 Prometheus 데이터를 장기 저장하거나 여러 Prometheus 서버를 하나처럼 합쳐줍니다.
Grafana는 Prometheus/Thanos 데이터를 시각화해서 보여주는 대시보드입니다.

 

 

이미지 출처 : toss tech

 

서버는 Spring을 사용합니다.

이전엔 Java를 많이 사용했지만, 최근 개발되는 언어는 Kotlin을 사용합니다.

 

이미지 출처 : toss tech

 

AWS는 DNS 설정을 하거나 이미지 검수와 static file을 서빙하는 기능으로 사용합니다.

Route 53 같은 서비스를 사용해서, 도메인 이름을 실제 서버 IP 주소와 연결해주는 작업을 AWS에서 합니다.
사용자 업로드 이미지에 대해 필터링, 포맷 변경, 리사이징, 검열 등을 Lambda, Rekognition을 통해 처리합니다.
정적인 파일(이미지, JS, CSS, PDF 등)을 S3 + CloudFront 같은 AWS 서비스로 빠르게 제공합니다.

Lambda는 코드를 서버 없이 실행해주는 서비스 입니다. 일종의 서버리스 컴퓨팅 입니다.
서버를 만들지 않아도 특정 동작이 있을 때 자동으로 코드를 실행해줍니다.

Rekognition은 이미지나 영상에서 얼굴, 객체, 부적절한 콘텐츠 등을 자동으로 분석해주는 서비스입니다.

 

 

데이터 센터 트래픽 조절

이미지 출처 : toss tech

 

평상시에 2개의 데이터 센터에 각각 트래픽이 50:50으로 들어가지만, 한쪽이 100%가 되는 트래픽을 옮기는 작업을 자주 진행합니다.

트래픽을 한쪽으로 옮기는 이유는 2가지가 존재합니다.

첫번째 이유는 장애가 나는 경우 이 문제를 해결해야지 복구가 되는 경우엔 장애시간이 오래 걸릴 수 밖에 없습니다. 따라서, 문제를 해결하는 것보다는 복구를 중심으로 대응해 장애가 나지 않는 반대편 데이터 센터로 트래픽을 옮기게 된다면, 장애 시간을 줄일 수 있다는 큰 장점이 있습니다.

두번째 이유는 새로운 시스템 도입이나 쿠버네티스 설정을 변경하는 경우, 테스트를 많이하고 예상되는 문제 부분을 확인하지만, 문제가 발생할 가능성이 0%로는 아니므로, 최대한 장애 여파를 줄이기 위해 트래픽을 한쪽으로 옮기고 나서 설정을 하고 다시 트래픽의 1% 정도 원상 복구를 합니다.

이렇게 적은 트래픽으로 문제가 없는 경우, 점진적으로 늘려가고 문제가 발생하면 바로 트래픽을 제거해서 장애를 겪는 고객 수를 최소화 합니다. 이는 서비스 카나리 배포를 데이터 센터에 적용한 것입니다.

 

그림에서 트래픽을 틀 수 있는 구간은 L7과 Route53 2군데가 존재합니다.

L7에서 트래픽을 트는 경우엔 모든 트래픽이 곧바로 옮겨지는 장점이 있어서, 대부분의 경우에는 L7에서 트래픽을 이동시킵니다.

쿠버네티스의 작업이 있는 경우엔 중간에 있는 L7에서 트래픽을 틀어주고, 중간 L7 경우엔 위쪽에 있는 L7에서 틀어줍니다.

위쪽 L7에서는 Route53으로 트래픽을 옮겨줍니다.

 

하지만, Route53은 변경 사항이 다른 라우터에 전파가 된 후에 반영되다 보니, 시간이 오래 걸리는 단점이 있습니다.

 

L7(Layer 7 Load Balancer) : 애플리케이션 계층에서 요청을 분산 처리하는 로드밸런서
Route53은 전 세계 DNS 캐시가 존재해서 즉시 반영이 되지 않습니다.

Route53은 AWS에서 제공하는 DNS 서비스이며, 도메인 이름을 IP 주소로 변환해주는 역할을 합니다. DNS는 전 세계적으로 여러 계층에 캐시되는데, 사용자 컴퓨터, 브라우저, 네트워크, 통신사 DNS 서버 등 다양한 위치에 저장됩니다. 이 때문에 Route53에서 도메인의 IP를 바꾸더라도 변경 사항이 즉시 반영되지 않고, 일정 시간이 지나야 새 IP가 적용됩니다.

이 시간은 TTL이라는 설정값에 따라 달라지며, 그동안은 이전에 캐시된 IP 주소를 계속 사용하게 됩니다. 그래서 빠르게 트래픽을 옮겨야 하는 경우에는 DNS보다 L7 로드밸런서에서 트래픽을 조정하는 것이 더 효과적입니다.

L7에서는 DNS 캐시 영향을 받지 않기 때문에 실시간으로 트래픽 전환이 가능합니다. 따라서 대부분의 트래픽 전환은 Route53이 아닌 L7 레벨에서 수행됩니다.

L7 로드 밸런서는 애플리케이션 계층에서 동작하는 로드 밸런서로, HTTP/HTTPS 요청의 URI, 헤더, 쿠키, 파라미터 등을 기반으로 트래픽을 분기합니다.

코드로 직접 구현하기보다는 Nginx, Envoy, Istio, 또는 Spring Cloud Gateway, Netflix Zuul 같은 프레임워크나 프록시 서버를 사용해 구성합니다.

 

이미지 출처 : Toss Tech

 

dc/os에서 쿠버네티스로 이동합니다.

container orchestration에서 가장 중요한 것이 service discovery와 container lifecycle management인데, dc/os에서 canary 배포로 사용하던 vamp는 service discovery 기능의 비효율과 한계가 있게 됩니다. 따라서, DC2에서 쿠버네티스를 도입하고 DC1에서는 dc/os를 동시에 운영하게 됩니다.

 

그 다음에 DC1 dc/os 일부 노드를 제거하고, 쿠버네티스를 설치하게 됩니다.

이 이유는 한번에 DC1을 쿠버네티스로 변경 했다가 문제가 발생하면, 롤백이 불가능해 조금씩 작업을 진행합니다.

DC1, DC2 두 군데에서 쿠버네티스를 사용하는데 검증을 하게 됩니다.

 

이미지 출처 : Toss Tech

 

쿠버네티스를 도입 할 때, Istio도 같이 도입하게 됩니다. 그 이유는 service mesh의 장점이 크다고 판단했기 때문입니다.

모놀로틱 구조에서 msa로 넘어가면서 여러 서버들의 호출로 하나의 서비스가 구성됩니다. 따라서, 서버들 간의 network 처리가 필요하게 되었고, circuit breaker, retry, fallback 등을 애플리케이션에서 처리하게 됩니다.

 

Istio를 도입하는 경우 Istio-proxy가 sidecar 형태로 붙어서 모든 네트워크를 proxy하게 됩니다.

proxy 하면서 애플리케이션에서 하는 일을 대신할 수 있으니, 어플리케이션의 언어와 상관 없이 개별 어플리케이션에서 처리하는 것이 아니라 infra 차원에서 한 번에 해결해 줄 수 있다는 장점이 있습니다.

msa는 외부에서 내부로 들어오는 요청보다 내부 서비스 간의 요청이 많은 특징이 있습니다.

내부 요청을 중앙 집중형태로 처리하다 보면 장애에 취약한 부분이 생기고 부하도 많이 받게 됩니다.

Istio는 내부 요청처리를 중앙집중이 아닌, client side에서 처리할 수 있게 됩니다. 즉, dc/os 보다는 쿠버네티스가 더 넓은 생태계를 갖고 있고, 더 큰 규모의 서비스에서 검증되었다는 점도 하나의 장점으로 판단하게 됩니다.

 

이미지 출처 : Toss Tech

Istio는 service에 sidecar로 붙어서 실행되고, iptable을 통해 모든 트래픽을 제어하게 됩니다.

제어된 모든 트래픽은 istio-proxy를 통해 나가게 되고, istio-proxy를 통해 받게 됩니다.

istio-proxy는 envoy proxy를 Istio에서 wrapping 한 것인데, envoy는 proxy가 어떻게 동작하는지 명확히 보여주자 이기 때문에, 많은 통계를 갖고 있게 됩니다. 예시로, connection pool 동작 방식이나 어디에서 connection pool을 끊겼는지도 통계로 확인할 수 있습니다.

 

이러한 통계를 보내는 쪽과 받는 쪽을 합쳐서 보내면, 어디에 문제가 있었는지 파악하기 쉽습니다.

기존 tcpdump로 네트워크 문제를 해결할 때, 보내는 쪽과 받는 쪽 모두 dump를 떠서 확인했던 것을 envoy가 대신해주는 것으로 생각하면 됩니다. 이러한 통계를 통해서 토스 서비스의 전체적인 observability가 높아지게 됩니다.

 

이미지 출처 : Toss Tech


Istio를 사용하면서 infra 쪽으로 네트워크 처리를 넘겨보려 했으나 circuit breaker는 host 별 설정이라 세부 설정이 힘들었고,

retry도 api의 트랜잭션 처리가 어떻게 되어있는지와 응답값에 따라 retry 해야 할 때와 안 해야 할 때가 있습니다.

그런 세부 설정이 부족하고, 된다 하더라도 설정이 많이 들어가야 해서 여전히 어플리케이션에서 처리하고 있습니다.

 

대신, mTls 설정을 통해 A 서비스는 B를 호출하고, C는 B 호출이 안되는 서비스별 권한을 적용하거나 envoy filter를 작성해 애플리케이션 변경없이 dynamic하게 네트워크 기능을 추가할 수 있는 장점이 있습니다. envoy filter로 헤더 처리, 접근 제어 등을 하고 있습니다.

 

 

이미지 출처 : Toss Tech

 

Istio route weight로 1% canary 배포를 진행하고 있습니다.

인스턴스 단위로 canary를 하게 되면 세밀한 트래픽 조절이 힘들어집니다. 10개의 인스턴스에서 1개만 카나리를 나가면 10% 카나리가 되기 때문에, 1% 카나리 배포를 하려면 100개의 인스턴스가 필요하게 됩니다.

 

Istio는 router의 weight로 canary를 할 수 있어서, 인스턴스 개수와 상관없이 1% canary 배포를 할 수 있습니다.

Istio로 할 수 있는 기능 중 또다른 하나는 failure injection test와 squeeze test 입니다.

 

failure injection test는 특정 조건에 맞는 요청의 경우, 실패 또는 응답을 늦게 하도록 만들어 서비스에서 실패에 대한 처리가 제대로 되어있는지 확인할 수 있는 test 입니다.

 

squeeze test는 하나의 인스턴스에 요청의 비율을 높여, 부하를 약간 주는 테스트입니다.

어느 정도 요청부터 서비스가 부하를 느끼는지 알아보고, 그 지표를 비교해보면서 이번 배포로인한 성능 하락이 있는지 확인이 가능합니다.

 

이미지 출처 : Toss Tech

 

클라이언트 인증과 암복호화를 담당하는 서비스가 있었지만, 점점 트래픽이 많아지면서 고성능 요구가 커지게 됩니다.

따라서, 신규 gateway 도입을 검토했고, zuul이나 kong, spring cloud gateway 후보 중 spring cloud gateway를 선택하게 됩니다.

그 이유는 WebFlux 도입을 하면서 reactor에 대한 운영 자신감이 생기고, 성능이 검증되면서 선택하게 됩니다.

 

api-gateway는 트래픽을 여러 필터를 통해 처리하게 되는데, custom filter를 만들어서 기존 인증/oauth2/암복호화를 구현합니다.

gateway의 라우팅은 static이나 dynamic으로 추가할 수 있게 되어있습니다. dynamic의 경우에는 routing 검증프로세스가 아직 확립되지 않아 대부분 static으로 추가하고 있습니다.

Istio는 MSA 구조에서 서비스 간 네트워크 처리를 애플리케이션이 아닌 인프라에서 공통으로 처리하기 위해 Kubernetes와 함께 도입되었습니다.
sidecar 형태의 istio-proxy가 네트워크를 대신 처리하면서 언어와 무관하게 공통 기능(circuit breaker, retry 등)을 적용할 수 있는 장점이 있습니다.
또한 envoy 기반의 proxy를 통해 통계 수집과 로그 분석이 가능해져 observability가 향상되고, mTLS와 envoy filter를 이용해 서비스 간 접근 제어도 가능합니다.
Istio는 router weight 설정으로 인스턴스 수에 상관없이 1% 단위의 canary 배포가 가능하며, failure injection test와 squeeze test를 통해 장애 대응 및 성능 테스트도 가능합니다.
다만, circuit breaker나 retry는 세부 설정이 어려워 여전히 애플리케이션 내에서 처리하는 부분이 있습니다.
기존의 인증 및 암복호화 서버가 트래픽 증가로 성능 한계에 도달하자, WebFlux 기반의 Spring Cloud Gateway를 도입하여 custom filter로 인증, OAuth2, 암복호화를 구현하고 있습니다.

 

spring 내부 코드가 reactor이지만, 유지보수의 편리성을 위해 corutine을 사용중입니다.

 

이미지 출처 : Toss Tech

 

처음엔 하나의 gateway로 서비스를 진행했지만, 점점 gateway에 요청을 보내느 서비스들이 다양해지면서, gateway가 무거워지기 시작합니다. 따라서 각 클라이언트에 대응하고, gateway 로직을 분리하기 위해 새로운 gateway를 추가합니다.

 

이미지 출처 : Toss Tech

 

토스의 많은 서비스들은 Spring MVC로 되어 있지만, 홈탭이나 내 소비와 같이 여러 데이터를 모아 보여주는 I/O가 많은 프로젝트에는 WebFlux를 이용 중에 있습니다. 최근엔 Spring에서 Kotlin dsl을 잘 지원하고 R2DBC를 사용하면서 많은 프로젝트가 webflux로 시작하고 있습니다.

R2DBC는 Reactive Relational Database Connectivity의 줄임말로 비동기 논블로킹 방식으로 관계형 DB에 접근할 수 있게 해주는 표준입니다.

 

Webflux를 초기엔 reactor로 개발을 했지만, 조직 이동이나 신규 입사시 러닝커브가 크다는 점이 있어서 coroutine을 도입하게 됩니다.

operator는 control flow를 짜는 것이 아닌, reactor가 제공하는 operator를 사용해야 합니다. 어떤 경우에 operator를 사용해야 하는지 살펴보고, 또 테스트를 통해서 의도대로 동작하는지 확인하고, 비즈니스 로직을 추가하다 보니 초기 러닝커브가 높습니다.

 

 

이미지 출처 : Toss Tech

 

모니터링은 오픈소스를 많이 활용합니다.

msa 구조에서 서버들이 여러 군데에서 뜨다 보니 logback과 filebeat을 통해 kibana에서 검색해 볼 수 있습니다.

로그에는 메시지를 포함한 다양한 데이터가 들어가 있습니다.

 

어느 데이터센터에서 어떤 컨테이너가 로그를 남겼는지를 보통 이 데이터로 특정 장비의 문제인지, 배포 ID는 어는 배포 버전에서 발생하는 로그인지 알려줘서, 신규 배포에 발생하는지 이전 배포에 발생하는지 확인할 수 있습니다. 에러 로그가 신규 배포에만 발생하면 바로 롤백합니다. MSA 구조에서는 문제가 발생했을 때, 원인이 요청을 받는 서비스의 문제일 수도 있고, 요청을 주는 서비스에서 잘못 요청을 줄 수도 있습니다.  전체적으로 여러 서비스 중 어느 곳에 문제가 있는지 확인하기 위해 apm으로 pinpoint를 사용 중인데, 해당 요청이 pinpoint의 어떤 요청과 매칭되는지 그리고 금융 회사로 5년 동안 장기 보관해야 하는 데이터들은 Kafka에서 hadoop로 데이터를 쌓아서 장기 보관하고 있습니다. 로그는 데이터 센터급 장애가 발생하는 상황에서도 서비스 개발자들이 확인할 수 있어야 해서 이중화가 되어 있습니다.

 

ES의 경우엔 각 데이터센터별 50대씩 100대 정도 운영 중이고, 하루에 15TB정도의 로그가 쌓이고 있습니다.

Pinpoint는 분산 시스템에서 요청 흐름을 추적하고, 성능을 분석하는 오픈 소스 APM 도구 입니다.

 

 

이미지 출처 : Toss Tech

 

metric은 쿠버네티스와 잘 맞는 prometheus를 사용중이고, HA와 데이터 장기 보관을 위해 thanos를 사용합니다.

global thanos가 따로 존재합니다. ceph를 내부 저장소로 사용하고 grafana로 데이터를 확인합니다.

grafana에 있는 대시보드와 알림 데이터들도 중요하기 때문에, 저장소로 사용하는 mysql은 서비스 DB와 마찬가지로 이중화가 되어 있습니다.

 

이미지 출처: Toss Tech

 

setry + Toss ES Alert + grafana

알림은 개별서비스에서는 sentry로 알림을 설정하고, 전체적인 관리는 에러나 워닝 로그 발생이 많아지거나 특정 로그가 많아지면 Slack으로 알림을 주고 있습니다. 그리고 grafana에도 알림을 걸어놔서 Istio error flag가 발생하면 Slack으로 알림을 주고 있습니다.

 

이미지 출처 : Toss Tech

 

flink를 통해서 서비스들의 응답을 파싱해서 응답시간이 튀거나, 응답 실패율이 높아졌을 때도 알림을 보냅니다.

 

이미지 출처 : Toss Tech

 

토스에 데이터센터가 2개일 때, 어떻게 카프카를 안정적으로 운영할 것인가에 대한 고민이 있었습니다.

하나의 클러스터로 두 개 데이터센터를 묶을 것인가, 아니면 다른 클러스터로 구성해 replication을 걸지 고민했었습니다.

그때 우버에서 사용하고 있는 방식을 보고 두 개의 클러스터로 운영하는 것이 좀 더 좋겠다고 판단하게 됩니다.

 

하나의 클러스터로 운영 시 데이터 센터급 장애가 발생하면, 다른 센터에 있는 서비스에서 일부 장애가 발생할 수 있는 반면, 두 개의 클러스터로 운영하면 다른 데이터 센터에서는 장애가 발생하지 않아 트래픽을 옮기면 빠르게 복구되기 때문입니다.

 

다만 두 개의 클러스터를 운영하면 추가 기능이 필요한데, active/standby인 consumer가 다른 데이터 센터로 active하게 넘어갈 때,

두 개의 Kafka는 consumer offset이 다르기 때문에, 어느 지점부터 consume을 할지 모르게 됩니다. sync 해주는 애플리케이션이 필요하게 되고, 토스에서는 데이터 플랫폼 팀에서 wakuwaku라는 이름으로 개발해서 사용중 입니다. 

 

producer는 active/active라 장애시 추가 대응은 필요 없고, consumer는 active/standby로 장애시 반대편 데이터센터의 Kafka를 바라보도록 변경하여 장애에 대응합니다.

 

이미지 출처 : Toss Tech

 

consumer에서 메시지 처리를 실패하는 부분을 고민한 결과 uber에서 사용하는 topic별 retry와 dead letter를 본떠 

toss에서도 Spring Kafka를 wrapping해 구현했습니다.

 

같은 topic에서 retry로 처리시간이 오래 걸리면, 뒤에 있는 메시지 처리가 밀리기 때문에, 다른 topic에서 retry를 하는것이 성능정 이점이 있습니다.  그리고 requeue를 할때 필연적으로 따라 오는 것이 delay입니다.

 

consume 하는 서비스가 정상화가 안 되었는데 requeue를 하면 다시 에러가 발생하게 됩니다.

topic이 나누어야 retry시 delay를 주는 것도 자유롭게 됩니다. 

 

topic별로 자동 delay requeue를 설정할 수 있고, dead letter topic에서는 수동배치로 requeue하고 있습니다.

 

이미지 출처 : Toss Tech

 

producer 쪽에는 Kafka A에서 실패할 경우 Kafka B로 보내서 retry를 하도록 처리했습니다.

여러 종류의 Kafka를 운영 중이라 서로 백업으로 사용할 수 있습니다. producer는 대부분이 재발행을 바로 하길 원해서 

약간의 delay후 자동으로 requeue를 시도합니다. 자동 requeue도 실패할 경우 dead letter topic으로 이동해 수동배치로 requeue를 하고 있습니다.

 

메시지 발행은 DB  처리 후 이벤트 발행용으로 많이 사용 중인데, DB와 Kafka 이기종 트랜잭션에 대한 고민을 해결하기 위해 kafka cluster 이중화로 대응했습니다. 하지만 여전히 하나의 트랜잭션이 아니라서 완벽한 transaction 처리가 필요한 서비스의 경우, outbox 패턴을 활용해 동일 transaction 처리 후, retry를 통해 전송하는 방법을 사용하고 있습니다.

 

이미지 출처 : Toss Tech

 

이전엔 memcahced를 사용했지만, 현재는 Redis Cluster를 사용중이고, cluster라서 데이터 보존이 조금 더 용이해 장기보관이 필요 없는 단발성 데이터 저장과 캐시로 사용 중에 있습니다.

 

현재 데이터 센터가 2개 밖에 없어서 한쪽에 master가 많은 상황이고, 데이터 센터 간 네트워크가 끊겼을때, split brain이 발생해 양쪽 다 master가 되는 상황이 발생할 수 는 있습니다. 이러한 부분은 인프라 이중화로 대응하고 있고, 3번째 데이터 센터도 준비중입니다.

데이터 센터가 2개라 한쪽이 장애시, 반대편에서도 master 3대, slave 3대를 구성하기 위해 각각 6대로 총 12대로 하나의 클러스터를 구성했습니다. 3번째 데이터 센터가 생긴다면 master 1대 slave 2대를 각 데이터 센터별로 구성해 9대로 클러스터를 구성할 계획입니다.

운영하다 보면 메모리 확장이 필요한데, 그때마다 slot rebalance로 대응 중이고, aws에서는 분산락으로 redlock을 구현해 이용하고 있습니다. 3번째 데이터 센터 완성시 redlock을 적용할 예정입니다.

 

Redis client로는 redisson, jedis, lettuce를 두고 고민을 했었는데 WebFlux와 mvc에서 공통으로 사용할 수 있고 spring에서 잘 지원해주는 lettuce를 선택하였습니다.