if kakao 개발자 컨퍼런스 2018 후기

story Sep 28, 2018

2018년 처음으로 카카오에서 개발자 컨퍼런스를 열었다. 추첨을 통해서 참가자를 뽑았으며, 운이 좋게 참가자로 선정돼서 다녀온 후기를 작성해본다.

참가 티켓은 2018년 9월 1일 QR 코드로 전달이 되었으며, 입장하는 곳에서 QR 코드를 통해서 확인 및 굿즈를 받았다. 굿즈는 스티커, 뱃지, 에코백, if 티셔츠, 노트, 모나미 펜 등으로 구성되었다. 굿즈를 정리하고 세션을 진행하는 장소로 이동했다. 세션은 다음과 같이 구성되었으며, 내가 들은 세션은 bold로 체크했다.

세션

11:00

  • 맵매칭 (부정확한 GPS포인트들로부터 경로 추정하기)
  • 텐서플로로 OCR 개발해보기: 문제점과 문제점과 문제점
  • AI시대에 맞는 서비스 개발
  • 카프카, 산전수전 노하우
  • 다음 모바일 첫 화면 개선기

12:00

  • 카카오의 광고지능 (Intelligence on Kakao Advertising)
  • Query by Image (이미지로 이미지 검색하기)
  • 딥러닝을 이용한 얼굴 인식
  • 카카오 봇 플랫폼 소개
  • Kakao Cloud Native Platform, 9rum
  • 카카오뱅크 모바일앱 개발 이야기

14:00

  • Unify data and model using Apache S2Graph and GraphQL
  • 무엇이든 물어보세요, 지식그래프 : 카카오미니와 검색 적용 소개
  • 눈으로 듣는 음악 추천 시스템
  • 오픈소스를 사용하고, 준비하는 개발자를 위한 가이드
  • Klaytn: Service-Oriented Enterprise-Grade Public - Blockchain Platform
  • 카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개

15:00

  • TOROS N2 - lightweight approximate Nearest Neighbor library
  • 비디오 특성 분석 및 딥러닝을 이용한 실시간 인코딩 효율 최적화
  • 카카오톡의 서버사이드 코틀린
  • 액티브X 없는 블록체인 기반 PKI 시스템
  • 모바일 게임플랫폼과 인프라 구축 경험기

16:00

  • 딥러닝을 활용한 뉴스 메타 태깅
  • 카카오가 가지고 있는 음성처리 기술
  • 스프링5 웹플럭스와 테스트 전략
  • 글로벌 게임 플랫폼에서 무정지, 무점검 서버 개발과 운영 사례
  • 다음웹툰의 UX(Animation, Transition, Custom View)


(11:00) 카프카, 산전수전 노하우

카카오에서 카프카를 운영하면서 생긴 이슈에 관해서 이야기하는 시간이었다. 실제로 운영을 하면서 겪을 수 있는 이슈와 노하우가 공유되어서 좋은 시간이었다. 카카오는 카프카를 7 클러스터/130EA로 운영하고 있으며, 260,000,000,000/day의 요청, 370TB/day의 데이터를 처리하고 있다. 엄청난 요청과 데이터에 놀랐고 언젠가는 나도 저런 데이터를 접해보고 싶다는 생각을 했다. 간단하게 카프카 사용 현황을 설명하고 카프카를 운영하면서 생긴 트러블슈팅에 대해서 설명했다. 카프카를 운영하면서 크게 두 가지의 트러블슈팅이 있었는데 다음과 같다.

1. Shrinking ISR 이슈
2. Rack Power 이슈

1. Shrinking ISR 이슈

Shrinking ISR 이슈에 대해 알아보기 전 간단하게 ISR을 살펴본다.

ISR(In-Sync Replicas)?

ISR은 리플리케이션의 그룹이라고 보면 된다.

  • 리더와 팔로워로 구성
  • 리더만 읽고 쓰기를 할 수 있음
  • 팔로워들은 리더를 주기적으로 동기화
  • ISR의 구성원만이 리더의 자격을 갖음

Shrinking ISR

브로커1(리더), 브로커2, 브로커3이 하나의 ISR로 묶여있다고 가정을 한다. 브로커1(리더)의 장애가 발생했을 시 브로커2, 브로커3이 하나의 ISR로 묶이고 둘 중의 하나가 리더로 지정된다. 이런 과정을 Shrinking ISR이라고 한다.

Shrinking ISR 이슈는 이런 과정을 반복하다가 하나의 브로커가 남게 되고 남은 하나의 브로커가 ISR을 구성하면서 나머지 브로커를 블로킹하는 이슈였다. 카프카 0.10.1.0의 버그였으며 현재에는 fix 되었다. 이런 이슈는 카프카의 인포 로그에서 확인할 수 있으니 인포 로그 레벨도 잘 살펴봐야 한다고 했다.

그리고 0.10.1.0의 버그 때문에 카프카 버전 업그레이드에 대해 이야기를 했다. 보통은 다운타임을 가질 수 없는 환경이기 때문에 클러스터 내 브로커 한대씩 버전 업그레이드를 진행해야 하며, 카카오에서도 다운타임없이 버전 업그레이드를 진행한다고 했다.

2. Rack Power 이슈

카카오는 IDC에 수많은 Rack으로 구성이 되어있다. IDC의 전원 장애가 발생하면 Rack의 브로커가 다운되고 메시지를 유실할 수 있는 상황이 생긴다. 이는 어쩔 수 없이 서비스의 영속성과 데이터의 정합성 둘 중의 하나를 선택해서 운영을 해야 한다고 했다. 카카오에서는 데이터의 정합성보다는 서비스의 영속성을 선택했다고 했다.

다음으로는 카프카의 프로듀서, 컨슈머에 대한 설명이 있었다.

3. 프로듀서

프로듀서는 카프카로 메시지를 전송하는 역할을 한다. 프로듀서는 아래와 같은 특징을 가진다.

  • 파티션의 리더로 직접 메시지를 전송
  • 특정 파티션 또는 랜덤 파티션으로 전송
  • 빠른 전송 속도 보장
  • 효율성이 좋은 배치 처리 가능
  • 설정을 통해 배치 크기나 지연시간 조정

프로듀서 ACKS

ACKS = 0

  • 매우 빠르게 전송할 수 있지만, 파티션의 리더가 받았는지 알 수 없음

ACKS = 1(Strongly Recommend)

  • 매우 빠르게 전송할 수 있지만, 파티션의 리더가 받았는지 알 수 없음

ACKS = ALL

  • 메시지 전송 속도는 가장 느리지만 손실 없이 메시지 전송 가능

프로듀서 ACKS = 1로 세팅, 브로커1(리더) / 브로커2 / 브로커3 이 있다고 가정한다.
프로듀서는 브로커1로 메시지 A를 전송하고 메시지를 받은 브로커1은 메시지를 받았다는 응답을 프로듀서에게 보낸다. 그리고 리더인 브로커1은 브로커2, 브로커3에게 리플리케이션을 한다. 프로듀서는 다음 메시지 B를 브로커1에게 전송하고 브로커1은 메시지를 받았다는 응답을 프로듀서에게 보낸다. 그리고 다시 리플리케이션을 하려던 찰나에 브로커1(리더)에 장애가 일어나면 메시지 손실이 발생한다.

그리고 특정 파티션에 메시지가 몰리지 않게 하려면 프로듀서 키를 None으로 설정하면 된다.

4. 컨슈머

컨슈머는 파티션의 리더에게 Fetch 요청을 하고 오프셋으로부터 메시지를 가져올 수 있다. 컨슈머의 목적은 컨슈머가 가능한 최대 속도로 가져갈 수 있도록 하는 것이다.

여러 개의 파티션에서 오프셋 순서대로 메시지를 가져오기 때문에 순서가 꼬일 수도 있지만 field에 time 값을 입력하는 방법으로 순서를 정렬할 수 있다고 했다.

컨슈머그룹

  • 하나의 토픽을 여러 컨슈머들이 구독
  • 컨슈머 그룹으로 그룹핑해서 컨슈머를 확장할 수 있음
  • 프로듀서가 토픽으로 보내는 메시지 비율을 높이면 컨슈머는 프로듀서의 속도를 따라가지 못하게 됨
  • 하나의 파티션에는 하나의 컨슈머만 가능
  • 컨슈머 그룹을 이용한 스파크(하둡) + 엘라스틱서치 멀티 컨슈머 활용 가능

5. LAG

카프카에서 LAG은 처리를 위해 각 파티션에서 대기하고 있는 데이터 개수이다. LAG을 모니터링이 필요하고 Burrow라는 툴로 카프카 컨슈머 LAG 모니터링을 할 수 있다.

6. 운영

사용하지 않는 토픽에 대해서는 조건을 주고 일치하는 토픽을 삭제하는 것이 좋다.

7. 마무리

좋은 애플리케이션인 카프카를 적극적으로 활용하자!


(12:00) 카카오의 광고지능 (Intelligence on Kakao Advertising)

가장 어려웠던 세션이었다. 수학 때문인지 세션 시작하고 20~30명쯤 나간 거 같다. 나도 세션을 보면서 대학원 때 보던 수식들이 떠올랐다. 주로 광고 노출, 구매 예측 등을 위해 카카오에서 어떤 노력을 하고 있는지 설명하는 세션이었다.

기존의 Reactive method를 사용하지 않고 Predictive method를 사용해서 광고노출 및 랭킹 시스템을 제안한다.

1. Data/Feature

알고리즘보다는 어떤 데이터를 사용할 지 잘 선택해야한다. 개인정보 이슈 때문에 많은 모든 데이터를 사용하지는 못한다. Privacy free audience data를 주로 활용한다고 했다.

2. Embedding

Bayesian을 이용한 Classification과 Topic Modeling(Latent Dirichlet Allocation, LDA)을 사용한다.

3. Prediction

Audience A에게 광고 B를 노출했을 시 Audience A가 광고 B를 클릭할 조건부 확률을 계산하기 위해서 Logistic Regression을 사용한다. Logistic Regression은 최대 엔트로피(Maximum entropy)를 가진다. 대부분 회사의 광고 랭킹 시스템에서 Logistic Regression을 기반해서 사용하고 있다. Logistic Regression은 학습 데이터 세트 (xi, yi)가 주어졌을 때, xi는 0 or 1을 가지는 d차원의 sparse feature vector이고, yi는 -1 또는 1을 가지는 목푯값이다. 광고 랭킹에서는 보통 이산화해서 바이너리 값을 가진다. 이때 d차원의 가중치 벡터 w를 찾는 것이 목적이다. x가 y = 1로 예측할 확률은 다음과 같다.

Softmax of binary (1/0) output

Pr(y = 1|x) = 1 / 1 + exp(−w^T*x) (Logistic Regression (Maximum entropy)
Loss = ∥y − ̂y∥_2

이때 가중치 벡터 w를 구하기 위해서 부정 로그 확률 손실 함수(negative log-likelihood loss)를 사용한다.(w/L_2 regularization를 사용한다.)

그리고 온라인으로 값을 반영하기 위해 Stochastic Gradient Descent로 local minimum에 멈추지 않고 global minimum을 찾는다.

4. Training

온라인 모델 업데이트를 위해서 FTRL-Proximal(Online)을 사용한다. 새로운 Audience와 광고 등이 나타나기 때문에 모델을 학습하면서 변동성을 모두 반영하는 것은 힘들다. 데이터의 변동성과 학습에 대한 효율을 고려해서 시간 단위 분할 학습과 통합 모델 구축을 수행한다. FTRL-Proximal은 아래의 수식으로 가중치를 업데이트한다.



(14:00) 카카오 광고 플랫폼 MSA 적용 사례 및 API Gateway와 인증 구현에 대한 소개

카카오 광고 플랫폼은 카카오 이용자가 있는 어느 서비스에서든 광고 노출을 하고 있다. 광고 등록부터 광고 성과 측정까지 가능한 원스톱 시스템이다. 광고 목적 최적화와 오디언스 타겟팅을 지원한다. 카카오 광고 DSP는 API Gateway를 사용하고 있으며, 그 중에서도 스프링 프레임워크와 잘 연동되며, Netflix에서 실제로 사용 중인 Netflix Zuul을 선택했다. 초기에 카카오 광고 DSP 구성은 다음과 같다.

1. API GATEWAY

API GATEWAY(Zuul) -> L7 -> DSP 모듈 서버

위와 같은 구성으로 잘 돌아가다가 서비스 장애가 발생했다. Elasticsearch에서 Out Of Memory가 발생했고 당시의 RestTemplate의 connection request timeout의 default 값 때문에 무제한 커넥션 대기에 빠졌다. 무제한 커넥션 대기 때문에 전체 서비스에 문제가 생겼다. 이런 문제 때문에 다음과 같이 구성을 변경했다.

API GATEWAY(Zuul) -> Circuit Breaker(Hystrix) -> Load Balancing(Ribbon) -> DSP 모듈 서버

10초이내에 발생한 요청 20번 동안 50% 오류 발생시 Circuit을 오픈해서 isolation 시킨다.

하지만 또 장애가 발생했다. Ribbon은 default가 라운드 로빈 방식이라 서버 상태를 체크하지 않는다. 이는 서버 목록에 주기적으로 Ping을 날려서 리스트에서 제외할 수 있도록 옵션을 조정했다.

그리고 오픈 API 사용 제한에 대한 이야기도 했다. Zuul2, Spring Cloud Gateway에서 Limit Rate를 지원하기 때문에 사용 제한을 걸 수 있다. 현재 카카오에서는 Spring Cloud Gateway를 선택을 했으며, FilterFactory의 필터를 통해 http 요청이나 응답 데이터를 필터링하여 수정하고 있다.

2. 인증 및 인가

마이크로 서비스의 인증 및 권한 부여 방법에 관해서 설명했다. 방법 중에는 분산세션관리(고정세션관리, 세션복제, 중앙 집중식 세션), 클라이언트 토큰, SSO(Single Sign-On), API GATEWAY를 통한 클라이언트 토큰 방법 등이 있으며 그 특징은 다음과 같다.

고정세션관리

  • 특정 사용자의 모든 요청이 동일한 서버로 전송
  • 로드 밸런서에 의해 강제 리로드시 모든 사용자의 세션데이터가 손실되는 위험 존재

세션복제

  • 각 인스턴스가 모든 세션 데이터를 저장하고 네트워크를 통해 동기화
  • 인스턴스가 증가할 수록 많은 대역폭이 필요함

중앙 집중식 세션

  • 공유 세션 저장소에서 사용자 데이터를 액세스
  • 가용성과 확장성이 좋은편
  • 세션 저장소에 대해 보호 매커니즘이 필요

클라이언트 토큰

  • 인증 정보를 사용자 브라우저에 저장(보통 쿠키 형태로 저장)
  • 위조, 변조가 불가하도록 암호화 필요(시스템마다 인증처리 필요)

SSO(Single Sign-On)

  • 사용자는 한번 로그인하면 다른 여러 시스템에 추가 인증 프로세스 없이 접근 가능
  • 유저가 접근 시마다 SSO 서버와 상호 작용 필요
  • 인증을 위한 반복적인 네트워크 트래픽을 사용

API GATEWAY를 통한 클라이언트 토큰 방법

  • 게이트웨이에서 인증정보 처리
  • 위조, 변조가 불가하도록 암호화 필요

2-1. 카카오 광고 플랫폼의 인증

카카오 광고 플랫폼인 moment에서는 다음과 같이 인증을 하고 있다.

로그인 -> 카카오 계정에서 쿠키 발급 -> 광고 플랫폼 로그인 -> API GATEWAY에서 JWT 발급 -> Request에 대해서는 JWT로 처리

JWT(JSON Web Token)는 웹 표준으로서 JSON 객체를 사용해 토큰을 만들어 인증을 처리하는 방식이다. Header, Payload, Signature를 .을 기준으로 구분한다. Signature를 통해 Payload가 위조, 변조되었는지 확인한다. 인증 토큰에는 다음과 같은 정보를 담고 있다.

  • Refresh Token : id, Service type, IP, 생성시간, 만료시간
  • Access Token : id, 사용자 정보, 광고 계정 ID, 권한 정보, 생성시간, 만료시간

로그아웃 시 JWT의 자체 만료시간이 기술되어 있어 강제 무효가 되지 않는 문제가 있다. 카카오에서는 opaque token을 폐기하면 Access Token을 무효로 하고 로그아웃하는 방법을 고려하고 있다.


(15:00) 카카오톡의 서버사이드 코틀린

카카오톡의 서버사이드를 자바에서 코틀린으로 변경하면서 느낀 코틀린의 특징과 카카오톡의 운영 경험에 대해서 들을 수 있는 세션이었다.

카카오톡은 평소 피크 1초당 80만, 최대 650만 요청을 처리하고 있는 생활 속 서비스이다. 카카오톡은 서버 구조 개선을 위해서 개발 언어로 코틀린을 도입했다. 2017년에는 신규 컴포넌트 개발에 코틀린을 사용했고, 2018년에는 기존 컴포넌트 개선에도 코틀린을 사용하고 있다. 성능, 생산성, 개발/운영의 편의성을 모두 고려해서 코틀린을 선택했다.

도입을 고려할 때의 걱정거리

개발환경

이미 안정화 된 언어와 개발환경을 가지고 있다.

  • 하위 버전의 API 지원(코틀린은 1.0 버전이 나온 이후 1.3까지 버전 업데이트 시 변화가 크지 않음)
  • Gradle이나 Maven에서 간단하게 추가를 하면 사용할 수 있음
  • IDE에서도 완벽하게 지원(특히, 자바 코드를 코틀린 코드로 변경 해주는 기능)

생태계(자바와의 호환)

자바와 완전한 호환으로 생태계 공유를 하고 있으며, 프레임워크의 러닝커브가 없다.

  • 자바와 100% 호환
  • 클래스, 인터페이스, 함수의 호환
  • 메소드/필드호환으로 자바의 Runtime Annotation이 동일하게 동작
  • 자바 솔루션과의 연동

문법

문법 부분은 너무 많아 카카오 발표 자료로 대체한다.(카카오톡의 서버사이드 코틀린 발표자료 )

정리

코틀린의 장점 중 하나는 자바와 비교하면 코드의 양이 많이 줄었다는 것이다. 코드의 양이 줄었다는 것은 생산성의 향상을 말한다. 카카오톡도 자바 코드 66%의 양으로 같은 애플리케이션을 만들 수 있다고 이야기 했다. 하지만 바이트코드의 사이즈가 2.2배 늘어나고 컴파일 시간이 자바보다 6.5배 정도 길어졌다. 이는 자바의 컴파일 시간이 빠른 것이기 때문에 딱히 신경쓰지 않는다고 이야기했다. 그리고 한계 상황에서의 안정성이나 성능 측면에서도 자바와 비슷했다.

결론적으로 새로운 프로젝트에는 코틀린을 도입하면 좋고, 굳이 잘 운영하고 있는 자바 시스템을 코틀린으로 바꿀 필요는 없다고 했다.


(16:00) 스프링5 웹 플럭스와 테스트 전략

카카오에서 준비한 세션이지만 이일민(토비)님이 발표를 했다. 토비의 스프링 책으로만 접했는데 실제 오프라인 세션에서 뵙는 것은 처음이었다.

스프링 웹 플럭스

스프링 웹플럭스는 스프링 5.0에 새로 등장한 웹 프레임워크이며, 리액티브 스택이 추가된 것이다.

웹 플럭스는 왜? 어디에 쓰이는가?

  • 100% 논블로킹 개발
  • 확장성과 고효율성이 매우 중요
  • 업/다운 스트리밍과 Back pressure가 필요
  • 고속 서비스 오케스트레이션 개발
  • 유사한 프로그래밍 모델의 경험(node.js 등을 사용해보신 분)
  • 유연하게 커스터마이징이 가능한 웹 프레임워크 구성
  • 본격적인 함수형 프로그래밍 모델 사용

웹 플럭스를 사용하지 않는 게 좋은 이유

  • 웹 플럭스가 왜 필요한지 분명하게 모름
  • 블록킹이 서버, 코드, 라이브러리에 존재
  • SpringMVC로 개발했더니 아무 문제 없음

리액티브(함수형) 프로그래밍

  • 인터넷 시대의 복잡함을 해결하기 위해
  • 연속적으로 일어나는 이벤트를 다루는 프로그래밍 기법
  • 동시성, 비동기/논블록킹 호출을 다루는데 탁월

비동기/논블로킹 API 호출 - 가장 단순한 리액티브

동기 블록킹 API 호출 - RestTemplate

  • 장점 : 쉽고 간단함
  • 단점 : IO동안 블록킹

비동기/논블록킹 API 호출

  • AsyncRestTemplate (Spring 4)
  • Async/Await (Java 8+)
  • WebClient (Spring 5)
  • 장점 : 확장성이 뛰어남, 높은 처리율, 낮은 레이턴시
  • 단점 : 장점을 얻을만한 경우가 잘 없음, 자칫하면 코드가 이해하기 어렵고 복잡해짐

스프링 웹 플럭스와 테스트

리액티브 API의 데이터 시퀀스 검증

subscribe() + assert, block() + assert
  • 테스트를 진행할 수 있지만 동기화/블록킹이 필요
  • Flux를 검증하려면 코드가 복잡해지는 한계
  • 시간과 간격에 대한 검증이 어려움
StepVerifier

비동기/논블록킹으로 동작하는 코드 테스트 툴

  • 데이터 스트림의 검증
  • 예외, 완료도 검증
  • 가상시간을 이용해 오랜 시간의 이벤트 테스트

원격 리액티브 API 호출 테스트

리액티브 HTTP API 호출 테스트

WebClient를 사용해서 진행(웹 플럭스 시작의 첫걸음으로 하기 좋음)

원격 리액티브 API 호출 - 러닝서버 통합테스트
  • Flux 테스트로 작성 - StepVerifier
  • 단위 테스트는 너무 복잡함
  • MockWebServer를 사용

구성 가능한 논블록킹 프레임워크

웹 플럭스의 새로운 아키텍처
  • 기존 MVC는 서블릿 스펙과 서버의 제약 위에 개발
  • 웹 플럭스는 독자적인 아키텍처를 가지는 프레임워크
  • 함수형 엔드포인트

함수형 엔드포인트 테스트 방법

  • bindToRouterFunction
  • @WebFluxTest

cherrypick

체리픽이라는 단어 본연의 뜻은 안 좋은 의미이지만 저는 트렌디하고 많은 기술을 공부하고 내 거로 만들자는 뜻을 가지고 사용하고 있습니다.