본문 바로가기

개발/미분류 IT 지식

[if(kakao)2021] 스마트 메시지 서비스 개발기

스마트 메시지 소개


스마트 메시지 서비스

  • 카카오톡 채널 광고 메시지의 일종
  • 소재 최적화 / 유저 타게팅 ( 예산에 맞추어 )

전반적인 스마트 메시지 서비스 Flow

  • 궁금했던 포인트는 ML 모델 / kafka (streams) 의 사용 방식 - 이미 나도 kafka streams 를 사용하고 있어서 더 호기심이 갔음

 

서비스 설계와 개발


k8s 클러스터 환경에 최적화된 MSA 개발과, 운영 편의성을 최대한 고려한 시스템 설계
  • MSA에 대한 구조는 언제나 정답이 없기에, 배우고 고민해야 한다

Architecture Overview

 

 

주요 시스템 요소


Golan-based Server 

  • Go : MSA 시대의 언어
    • 레거시는 스프링부트
    • 무겁고 복잡한 프레임워크에 대한 필요성 감소
    • 가벼우면서 빠른 성능 보장
    • CI/CD 빠른 빌드, 쉬운 의존성 관리
    • 라이브러리 선택지가 많아서 장점이자 단점... ( 웹프레임워크 - echo, gin 사용 )
  • Legacy Spring -> Go 전환 효과
    • 서버 코드 LOC 60% 감소
    • API 서버 기준 pod 메모리 사용량 1/3 수준으로 감소
항상 공감하고 있는 부분이다. 스프링이 정말 좋은 프레임워크임에는 부정하지 못하지만, 클라우드 네이티브 환경에서 스프링은 정말 좋은 프레임워크인가? 장점이라고 할 부분이 있는지 항상 의문이 든다. 쉬운 인력 수급 정도. 가볍지도 않고, 빠른 성능 보장도 되지않으며, 개발속도가 빠르지도 않고, 메모리 사용량은 높고, 그래서 CI/CD와 CN(Cloud Native)를 고려하면 최악의 선택이 아닌가 싶다.

 

Event-driven Architecture

HTTP 기반 초안 방식

  • 초기에는 API서버와 광고 집행 서버들간 HTTP 통신
  • 이 정보는 민감한 정보 (민감한의 정의가 보안이 아닌, 정합성으로 보임)
  • 유실/중복처리의 가능성 존재 (따닥~)
Kafka 기반 Event Sourcing Architecture 로 전환

  • Event 장애로부터 분리 ( 메인 이유 )
  • Kafka Transaction 사용
    • 처리도중 이슈 발생하더라도 중복은 처리 안됨
  • CQRS 패턴 사용
    • CQRS의 핵심은 명령과 조회의 분리
    • 이를 가능하게 해주는 것이 "이벤트"
    • 결국 API는 조회만, 나머지 서버가 Command 한다
    • 여기서 사용하는 CQRS는 main DB를 결국 공유하는 것처럼 보이기 때문에, 본질적인 CQRS보다는 Saga에 가깝다고 생각된다.
  • REST 기반 CRUD 방식에 비해 event 처리 확인에 소요 시간 증가
    • Latency 에 민감 X, 트래픽이 높지 않음

 

Delay Queue를 이용한 job scheduling

  • 광고는 mini-batch 형태로 진행
    • 모델이 자주 바뀌니까 그때의 모델을 기준으로 배치 job 등록
    • 그래서 interval 존재 ( 위의 그림은 10분 )
    • 시간 맞추어 job 요청
  • 그런데, 장애시 문제가 될 수 있음
    • 장애 시 k8s는 서버를 다시 띄우겠지만, 
    • job이 메모리에만 있으면 유실
    • main DB에 있다면, 아시다시피 k8s의 ReplicaSet의 Replicas는 최소한 'N'을 보장
    • 그러므로, 새로운 pod가 뜨는 순간에 인스턴스 수가 많다면 중복 처리가 될 수도 있음
  • 그래서 DLX를 사용
    • TTL을 각각 다르게 10분, 20분, 30분으로 DelayQueue에 넣고 DLX로 처리
    • 장애가 나고, 새로운 pod가 떠도 문제없이 작동 (prefetch / consumer 고려해야 함)
DLX를 이렇게 사용할 수도 있구나. 라는 생각을 하게 되었음. 나도 DLX를 결국 mini-batch 구조로 사용을 하고 있는데 ( 주기적 mini-batch ), 그 응용 방법을 조금 변형하면 이런 사용방법도 있겠구나 하는 생각.

 


카프카 스트림즈를 선택한 이유

  1. 모든 사용자 반응 로그는 카프카로 모이고 있었고, 카프카와 완벽하게 연동되는 어플리케이션이 필요. 
  2. 상태기반 처리 (Stateful)
    • 비상태기반 처리 - 메시지는 하나의 별개의 처리
    • 상태기반처리 - 시간이 중요하다
  3. 운영
    • 프레임워크의 지속적 지원, 개발중 이슈 트러블슈팅 등의 운영

스트림 데이터 처리 기술 비교 - 2개 중 1개

  • Masterless 배포 - 유연성, 그리고 아파치 카프카에서 릴리즈 하고 있음
결국 모든팀의 고민은 똑같고, 결론은 카프카 스트림즈. 우리도 그래서 카프카 스트림즈!

라이브러리기 때문에, 스프링으로 해도되고, 기본 자바 어플리케이션이어도 상관이 없다는 것이 장점. 여기서는 기본 자바 어플리케이션으로 구현

현재 내가 사용하고 있는 방법과 동일하게, 1) DBMS로의 유입 쓰로틀링, 2) 새로운 데이터 Mapping 으로 주로 사용 중