토스증권 Apache Kafka 데이터센터 이중화 구성 #1

1 day ago 2

안녕하세요. 토스증권 실시간 데이터팀 강병수 입니다. 토스증권은 데이터센터 장애 상황에도 유저에게 정상적으로 서비스를 제공하기 위해 대부분의 시스템을 이중화했습니다.

Kafka 이중화에 대해서는 2023년 6월 토스 개발자 컨퍼런스 SLASH23에서 한 차례 발표한 바 있는데요. 이번 아티클에서는 3부작으로 구성해 보다 상세하게 설명드리려고 합니다.

본 글인 1부에서는 Kafka 이중화 구성에 대한 개요를 담았습니다. 2부에서는 토스증권에서 채택한 Active-Active 구성에서 중요한 부분인 양방향 데이터 미러링에 대해 소개하고, 3부에서는 Active-Active 구성을 채택 했을 때 운영적으로 높은 난이도를 요구하는 양방향 Consumer Group Offset Sync에 대해 설명하는 순서로 이어집니다.

Kafka 이중화의 필요성

Kafka 이중화에 대한 고민과 설계는 데이터센터 장애 상황에도 정상적으로 서비스를 동작시키기 위해 시작됐습니다. 한쪽 데이터센터에 장애가 발생하여 동작하지 않는 상황에도 서비스를 제공할 수 있으려면 어떻게 해야 할까요?

답은 간단합니다. 다른 지역의 데이터센터에 서비스 서버를 소산해놓고 정상 동작하는 데이터센터로 유저 트래픽을 모두 몰아주면 됩니다.

토스증권의 서비스 서버 구성은 아래와 같은 특성을 갖고 있습니다.

  1. 서버를 운영하는 Kubernetes는 두 곳의 데이터센터에 비슷한 스팩으로 구성돼있습니다.
  2. 두 데이터센터 모두 평시에 유저 트래픽을 처리하는 Active-Active 구성입니다.
  3. 서버는 MSA 구조로 설계되어 Kafka를 메시지 브로커로 활용합니다.

서비스 서버는 Active-Active로 구성돼 이중화 됐습니다. 하지만 MSA에서 메시지 브로커 역할을 하는 Kafka가 이중화 돼있지 않으면 실제 데이터센터 장애 상황 발생 시 서비스는 정상 동작하지 않을 것이 분명합니다. Kafka 역시 데이터센터 이중화를 해야 하는 상황이 됐습니다.

그림 1. 유저의 트래픽이 이중화된 클러스터로 분산돼서 들어오면 뒷단은 어떻게 구성해야 할까요?

서비스 서버가 stateless하게 구현됐다면 상대적으로 이중화 구성이 간단합니다. 하지만 stateless한 서비스 서버와 다르게 stateful한 Kafka는 이중화 구성에 더 많은 고민이 필요합니다. 어떻게 구성해야 좋은 아키텍처가 될까요?

Kafka 이중화 아키텍처

Kafka 이중화 구성은 크게 두 가지 아키텍처가 있습니다. Active-Active 구성Stretched Cluster 구성입니다. 이해를 돕기 위해 그림으로 먼저 볼게요.

두 구성 모두 데이터센터 장애 상황에 가용성을 확보할 수 있다는 이중화 본래 목적을 충족합니다. Active-Active 구성과 Stretched Cluster 구성에서 가장 결정적인 차이점은 Kafka 클러스터를 하나로 구성할 것인지 분리해서 두 개로 구성할지입니다.

Kafka 클러스터가 한 개냐 두 개냐 차이로 각각 아키텍처의 장단점이 생깁니다.

먼저, Active-Active 구성은 독립적으로 구성된 두 개의 클러스터를 하나로 묶어주는 과정에서 운영부담이 크다는 단점이 있습니다.

  • 장점
    1. Producer와 Consumer는 지역성이 보장된 Kafka에 접근하기 때문에 latency가 상대적으로 짧습니다.
    2. 양 클러스터가 독립적으로 구성됐으므로 한쪽 데이터센터 장애가 다른 쪽 클러스터에 영향을 주지 않습니다.
  • 단점
    1. 수백 개의 토픽을 양방향 데이터 미러링을 구성하고 운영해야 합니다.
    2. 수천 개의 Consumer Group Offset을 양쪽 클러스터에 동기화 시켜야 합니다.
    3. 토픽관리와 권한관리와 같은 모든 작업을 두 배로 해야 합니다.

Stretched Cluster는 물리적으로 분리된 장비에 하나의 Kafka 클러스터로 구성하기 때문에 추가적인 운영부담없이 이중화가 가능하지만, 평시 성능저하와 Split-brain이 발생할 여지가 있습니다.

  • 장점
    1. 이중화를 하지 않은 Kafka 운영과 크게 다르지 않아서 운영이 편리합니다.
    2. 데이터센터 장애 상황이 발생했을 때 클라이언트들이 안전한 데이터센터에 재연결 후 즉시 작업을 재개할 수 있습니다.
  • 단점
    1. Kafka의 전송 프로토콜 구조상 매 요청마다 데이터센터 간 네트워크를 경유해야 하므로 latency 저하가 심합니다.
    2. Kafka 클러스터의 상태를 관리하는 Zookeeper는 Stretched Cluster 구성 시 장애 상황에도 정족수를 충족시키기 위해 삼중화 구성이 필요한데, 데이터센터 간 네트워크가 단절되는 장애 상황에 Zookeeper에서 Split-brain이 발생해 Kafka 클러스터가 먹통이 될 가능성이 있습니다.

Active-Active 구성을 선택한 이유

아키텍처를 선택하기 위해 크게 세 가지를 고려해야 합니다.

  1. 다양한 장애 케이스에서 가용성을 확보할 수 있는가?
  2. 가용성 확보를 위한 이중화 구성이 성능 저하를 유발하지는 않는가?
  3. 클러스터 운영이 너무 어렵지는 않은가?

이중화 클러스터를 구성하는 일은 많은 공수와 돈이 들어가지만, 그럼에도 불구하고 이것을 하는 이유는 모든 장애 케이스에 대비할 수 있는 가용성을 확보하기 위함입니다. 이 조건을 필수로 충족시키는 구성이어야 하고, 동시에 성능 저하와 같은 페널티도 없는 것이 이상적입니다.

운영 편의성은 위 두 가지와 비교하면 상대적으로 중요도는 떨어집니다. 가용성이 확보되고 성능 저하도 없는 이중화 구성을 해낸다면 운영 부담은 어떻게든 풀어나가면 되기 때문입니다. 이 부분들을 모두 고려하여 토스증권에 적합한 아키텍처는 Active-Active 이중화 구성이라고 판단하고 적용했습니다.

Stretched Cluster의 경우 허용될 수 없는 큰 결함이 두 가지 있었습니다.

  1. 데이터센터 간 네트워크 단절 장애 케이스에서 Split-brain 발생으로 가용성 확보 불가
  2. 데이터센터 간 거리에 따라 통신 latency가 늘어나기 때문에 Kafka 성능 저하 발생

Stretched Cluster는 데이터센터 간 네트워크 단절 시 Split-brain이 발생해 클러스터가 먹통이 되는 문제를 갖고 있습니다. 따라서 어떠한 상황에도 가용성을 확보하는 것이 Kafka 이중화 구성의 목표라는 점에서 목적에 부합하지 않았습니다.

또한, Kafka 프로토콜 특성 상 leader가 요청을 받으면 replica 복제 완료 후 클라이언트로 응답을 전달하게 되는데, 매 요청마다 latency가 큰 DC간 네트워크를 경유해야 하는 Stretched Cluster 구성은 Kafka 성능을 크게 저하시키는 문제도 있었습니다. Stretched Cluster는 운영 편의성이 무척 높지만, 위와 같은 두 가지 허용할 수 없는 결함을 내재하고 있어서 포기하게 됐습니다.

Active-Active로 결정하고 구성을 하게 되면서 해당 구성의 단점들이 눈에 밟히기 시작했는데, 독립된 두 클러스터를 하나로 만들어 주기 위해 수백 개의 토픽에 한 ‘데이터 미러링’과 ‘Consumer Group Offset Sync’를 구성하고 유지해야 하는 운영 부담이 가장 크게 다가왔습니다.

이 3부작의 Kafka 이중화 글은 결국 대규모로 구성된 Active-Active Kafka 클러스터에서 운영 부담을 어떻게 극복해 나가는지에 대한 이야기가 담겨 있습니다.

이중화 구성 후 달성해야 할 목표

토스증권에서 이중화 구성된 Kafka를 서비스에 제공하기 위해서는 두 가지가 필요했습니다.

  1. Kafka 이중화 구성에 대한 이해가 깊지 않은 서비스 서버 개발자들도 쉽게 활용할 수 있어야 합니다.
  2. 데이터센터 장애 발생 시 메인 센터 전환이 빠르고 편해야 합니다.

1번 목표를 달성하기 위해서 양쪽 Kafka 클러스터에 토픽명을 동일하게 가져갔습니다. Uber와 같은 외국 기업 사례를 참조했을 때, 데이터센터 별 prefix를 토픽명에 붙여서 다른 토픽으로 가져가는 경우가 있었는데, 토스증권에서는 서비스 개발자가 이중화된 클러스터 어디에 배포가 되든 신경 쓰지 않아도 잘 동작하는 환경을 만들기 위해 토픽명을 동일하게 가져가도록 정책을 세웠습니다.

이 결과 이중화 Kafka 활용에 대한 추가적인 러닝커브가 없어졌고, 회사의 성장에 발맞춰 서비스 서버 개발자들이 계속해서 늘어나는 상황임에도 부담이 없었습니다.

2번 목표인 장애 발생 시 메인 센터 전환을 달성하기 위해서는 DNS 정책을 적극적으로 활용했습니다. 메인 센터 전환은 Producer와 Consumer를 분리해서 정책을 설계했습니다.

  • 이중화 구성 후 트래픽의 흐름
    그림 4. Active-Active로 Kafka 이중화 구성을 하면 실시간으로 양방향 데이터 미러링으로 각각 100%를 맞춰줘야 하고, Consumer가 데이터센터를 옮겨갈 경우를 대비해서 Consumer Group Offset Sync를 맞춰야 합니다.

Producer 정책

Producer를 먼저 살펴보면 Kafka에 접근할 때 Split DNS를 활용해서 배포된 zone과 동일한 Kafka로 메시지를 전송하도록 구성해 지역성을 확보했습니다. 각 zone으로 전송된 메시지는 실시간 양방향 데이터 미러링 도구가 상대 zone으로 메시지를 전달함으로써 양쪽 모두 100%의 메시지를 갖게 됩니다.

이렇게 구성하니 서비스 개발자는 어느 데이터센터에 서비스가 배포되는지 관심 가질 필요가 없고, 또 데이터센터 장애 상황 시 안전한 데이터센터로 최상단 트래픽만 모두 옮겨주면 정상적인 Kafka가 모든 메시지를 받게 됩니다.

Producer의 메인 센터 전환은 이와 같이 Split DNS를 활용해서 간단하게 해결했습니다.

Consumer 정책

Consumer는 조금 더 복잡한데요. 양방향 데이터 미러링으로 인해 양쪽 Kafka 클러스터에 데이터가 100%가 존재합니다. 따라서 Consumer는 2배로 소비하는 것을 피하기 위해 한쪽 Kafka 클러스터에서 소비를 하는 Active-Standby 구조입니다. 언제나 한쪽 Kafka만 바라보도록 통제하기 위해 GSLB(Global Server Load Balancing)라는 DNS를 활용하도록 구성했고, GSLB 제어를 통해 전체적으로 Active 데이터센터를 전환하고 있습니다. Active-Active인 Producer 와 다르게 Active-Standby인 Consumer도 DNS를 활용해서 서비스 개발자가 신경 쓰지 않아도 이중화 및 메인 센터 전환이 가능하도록 구성했습니다.

Consumer는 Consumer Group Offset이라는 것으로 상태 저장을 하고 재시작 시 저장된 Offset을 활용해서 종료 전 마지막으로 읽은 다음 메시지부터 소비합니다.

서로 독립된 Kafka 클러스터는 Offset 정보가 서로 다릅니다. 예시를 통해 설명하면 같은 토픽이름 ‘toss’에 메시지 ‘증권 최고’가 데이터센터 1 Kafka에는 10번 Offset에 들어있고, 데이터센터 2에는 9,959,273번 Offset에 들어있다고 가정해볼 수 있습니다. 두 숫자 사이에 연관성이 있는 건 아니고 시작점이 달라서 생기는 차이입니다.

이 차이 때문에 Standby로 컨슈머가 넘어갈 때는 Standby 클러스터 Offset 순서에 맞게 보정된 값이 저장돼있어야 합니다. 그래야 새로운 클러스터에서 소비를 시작하면서 유려하게 이어질 수 있기 때문입니다.

데이터센터 1의 Consumer Group Offset을 데이터센터 2에 맞는 Offset으로 변환해서 저장해주는 도구가 Offset Sync입니다. 어떤 식으로 동작하는지 상세한 설명은 3부에서 이어집니다.

Consumer 역시 GSLB DNS를 이용해서 메인 센터를 전환함으로써 데이터센터 장애 상황시 가용성을 확보하도록 구성했습니다.

마무리

이번 글 에서는 Kafka 데이터센터 이중화에 대한 개요를 다뤄보았습니다. 데이터센터 이중화 작업을 설계함에 있어 토스증권의 니즈와 환경에 맞춘 적절한 오픈소스가 전무해 실시간 데이터팀에서 직접 개발하게 되었는데요. 현재 본래의 기능 구현과 더불어 Active-Active 구성의 단점이었던 운영상 어려움을 많이 해결했습니다. 나아가서 너무나도 중요한 모니터링 환경도 고도화해서 현재 토스증권 시스템에서 중요한 천 개가 넘는 토픽과 Consumer Group을 안정적으로 운영 중입니다.

토스증권 Apache Kafka 데이터센터 이중화 구성의 실제 구현 내용은 2부 ‘데이터 미러링’와 3부 ‘Offset Sync’에서 이어집니다. 많은 기대 부탁드립니다. 감사합니다.

Read Entire Article