본문 바로가기
Kafka

LINE 오픈챗 서버가 100배 급증하는 트래픽을 다루는 방법 feat.Kafka

by 준형코딩 2023. 9. 21.

 
 

 

 

최근 새롭게 Join한 백엔드 스터디에서 기존에 사용해보지 못했던 기술들을 활용하는 방법들을 공부하고 기록으로 남기기 위해서 Kafka에 대해서 공부를 했고 모두 어느 정도 알고 있는 원리를 정리하기보다는 실제 기업에서는 어떤 방식으로 Kafka가 운영되고 어떤 목적으로 사용되는지 정리를 하기 위해서 Line의 오픈챗 서버에서 Kafka가 어떻게 활용이 되었고 어떤 방식으로 100배 급증하는 트래픽을 해결하였는지 정리를 하기 위해서 글을 작성하게 되었습니다.


이번 글에서는 Line의 개발자분들이 오픈챗의 핫챗을 통해 100배 급증하는 트래픽을 어떻게 Kafka를 활용하여 해결하게 되었는지 설명하겠습니다.

 

핫챗이란?

 

 

만약 한 오픈챗에 참여한 5천 명의 사용자가 모두 동시에 활발하게 메시지를 주고받는다면 어떤 일이 발생할까요? 실제로 소셜미디어 팔로워가 수백만 명에 달하는 유명 가수의 콘서트를 팬들이 함께 보며 참여하는 오픈챗이 있었고, 배우나 모델, 인플루언서의 방송 출연을 함께 보는 오픈챗, 온라인 게임의 이벤트를 함께 즐기는 오픈챗 등이 있었습니다.

이와 같은 오픈챗에선 일반적인 오픈챗 대비 트래픽이 100배 이상 급증할 수 있습니다. 아래 오른쪽 사진을 보면 5천 명이 참여해 1초에 수백 개의 메시지가 전송될 정도로 활발하게 활동하는 한 오픈챗이 나타나서, 이 챗의 새로운 메시지들을 가져가려는 API 요청 수가 1분에 최대 20만 건에 달하며 급증하는 것을 확인할 수 있습니다. 이와 같이 트래픽이 급증하는 오픈챗을 오픈챗 서버 팀에서는 핫 챗이라고 부릅니다.

 

-Line Blog, 김인제 개발자님

 

 

기존 Line의 오픈챗?

 

이런 핫챗이 문제가 되는 이유는 Line에서는 오픈챗 서버의 이벤트 기반 아키텍처와 깊은 관련이 있습니다. 이벤트 기반 아키텍처는 EDA라고도 불리며 EDA는 분산된 애플리케이션 서비스들이 이벤트를 기반으로 통신하고 서로의 동작을 야기하는 패턴을 이벤트 기반 아키텍처라고 합니다. (대표적으로 카프카를 이용해서 EDA를 구성하게 됩니다.) 따라서 오픈챗 서버에서는 메시지 전송과 메시지 리액션, 메시지 읽음 등과 같은 오픈챗 내 다양한 행위를 모두 이벤트로 간주하고 이벤트가 생성될 때마다 스토리지에 저장한 후 오픈챗에 참여하고 있는 모든 사용자에게 서버 푸시로 새로운 이벤트를 알립니다. 그리고 서버 푸시를 받은 사용자는 스토리지에 새로 들어온 이벤트를 페치 이벤트 api를 용해 받아 가서 새 이벤트를 화면에 추가하는 액션을 실행합니다.

 

Event Driven Architecture

 

기존 방식의 문제점

 

이벤트가 생성될 때마다 오픈챗에 참여하고 있는 모든 사용자에게 이벤트를 전달해야 하고 5천 명이 한 오픈챗에 참여하고 있다면 이벤트가 하나 생성될 때마다 5천명의 사용자가 이 이벤트를 전달받기 위해 5천 개의 페치 이벤트 API 요청을 호출하게 됩니다. 따라서 1초에 수십 개의 이벤트가 생성되는 핫 챗에서는 그만큼 페치 이벤트 API 요청이 급증하게 됩니다.

 

 

그럼 어떻게 이런 급증하는 트래픽을 LINE에서는 해결하였는가?

 

아래는 기존 오픈챗 서버구조를 조금 더 자세히 그려본 다이어그램입니다.

 

기존 오픈챗 서버에서는 메세지리를 전송하면 오픈챗 서버가 이를 스토리지에 저장하고 Kafka 이벤트를 전달하며, 오픈챗 서버 팀에서 퍼블리시 서버라고 부르는 별도 서버 그룹에서 Kafka이벤트를 소비해서 새로운 이벤트가 생성됐다고 알리는 서버 푸시를 사용자에게 보냅니다.
이러한 구조를 사용하고 있기 때문에 핫챗에서는 페치 이벤트 API 요청 수가 평소 대비 100배 이상 급증하면서 오픈챗 서버에서 사용하는 mysql,redis,hbase와 같은 스토리지에 큰 부하가 발생하는 문제가 있었습니다.

 

관련 지표 - 한 샤드에 전달되는 요청량이 3배 급증하거나 스토리지 부하 때문에 응답 타임아웃이 발생 (하단)

관련 지표 - Kafka오프셋 렉 증가, GC와 CPU 사용량 급증 (하단)

 

 

 

Kafka, Redis, Bucket으로 해결하다.

 

우선 문제를 해결하기 위해서 어떤 챗이 핫 챗인지 탐지할 수 있는 방법이 필요했고, Kafka와 버킷으로 구현하게 됩니다. 페치 이벤트 API가 요청될 때마다 Kafka로 이벤트를 전송하고 퍼블리시 서버에서 이를 소비해 하나의 챗에 최근 몇 초 동안 몇 개의 페치 이벤트 API가 요청됐는지 실시간으로 기록합니다. 만약 페치 이벤트 API 요청이 미리 설정해 둔 임계값보다 더 많이 들어온다면 이를 핫 챗으로 판단하고 해당 챗이 핫 챗이라고 Redis에 잠시 저장합니다. 

 

- Kafka code, 임계점을 넘어서면 hotChatStorage에 기록

 

그 후 퍼블리시 서버에서는 사용자에게 새로운 이벤트가 생성됐다고 알리는 서버 푸시를 보내기 전에 이 이벤트가 생성된 챗이 핫 챗인지 Redis에서 확인을 하게 됩니다. 만약 핫 챗이면 서버 푸시를 확률적으로 스로틀링해서 보내지 않는 방법으로 대량의 페치 이벤트 API 요청이 발생하지 않도록 조절합니다. 

따라서 Line에서는 Redis와 Kafka를 통해서 핫 챗을 구별하고 스로틀링을 통해서 fetch api를 조절하기 때문에 핫 챗을 통해서 오는 서버 부하를 해결할 수 있게 되었습니다.

 

 

끝으로..

 

실제 기업에서 발생한 문제점을 해결하는 방식을 통해서 Kafka를 이해를 하게 되니 왜 Kafka를 공부를 해야 하고 앞으로 문제가 발생했을 때를 고려해서 Kafka를 어떤 식으로 활용해야 되는지에 대한 깊은 이해를 할 수 있어서 더욱 재밌고 몰입해서 공부할 수 있었습니다. 앞으로도 새로운 기술을 공부할 때 그 기술을 도입한 사례와 발생한 문제점들을 해결해나가는 과정들을 같이 보면서 공부를 해야겠다는 생각이 들었습니다.

 

 

https://engineering.linecorp.com/ko/blog/how-line-openchat-server-handles-extreme-traffic-spikes

- 이 블로그는 Line 김인제 개발자님의 기술 블로그를 바탕으로 작성 되었습니다.