기록 블로그

프로그래머스 데브코스-데이터 엔지니어/TIL(Today I Learned)

07/11 67일차 Udemy의 데이터 처리

usiohc 2023. 7. 11. 13:53

Udemy 데이터 처리


주요 메모 사항


Udemy 데이터팀 빌딩

2014년 8월 데이터 엔지니어링팀 처음 빌딩

-데이터 웨어하우스 도입 (Redshift)

- ETL 프로세스 개발

ㄴ 처음에는 crontab으로 관리하다가 Pinterest의 Pinball로 이전

    ㄴ 파이썬을 기본 개발 언어로 사용, 지금은 Airflow 사용

ㄴ 처음에는 데이터 복사만 하다가 점차 중요 프로세스 개발도 시작

    ㄴ B2B 강사 보수 계산 (소비율에 따라 나눠줌)

    ㄴ 중요 파이프라인의 경우 SLA (Service Level Agreement) 설정하고 지표로 계산

- 데이터 소스 추가 요청을 받는 슬랙 채널 개설

- 백엔드/프런트엔드 엔지니어링팀과 다양한 협업 시작

ㄴ Incremental Update를 하기위해 프로덕션 DB 테이블 스키마 변경

    ㄴ updated_at과 deleted 필드 추가

ㄴ 사용자 이벤트 로그를 프로덕션 DB에서 nginx 로그로 빼는 작업 수행

    ㄴ 처음에는 이를 파이썬 스크립트로 처리

    ㄴ 나중에 이를 Hadoop 클러스터를 만들고 HDFS로 복사한 다음에 Hive로 처리

    ㄴ 궁극적으로는 Kafka에 적재하고 다수의 consumer로 처리 (Connect 사용)

    ㄴ 사용자 이벤트를 처리하는 마이크로서비스를구현하고 K8s 위에서 실행함

 

 

2015년 4월 데이터 분석팀 설립

- BI 툴 도입 (ChartIO => Tableau)

- 데이터 분석 요구 프로세스 도입

ㄴ 티켓의 수와 카테고리가 데이터 관련 만족도와 개선 방향의 중요 지표가 됨

ㄴ 투명성의 중요성

- 지표 표준화

ㄴ 매출, Active Students, Active Instructors 등등

ㄴ 지표 기반 의사결정 방법 교육 -> Next Feature Fallacy

- 내부 직무 전환 제도를 이용해서 디지털 마케터들을 분석가로 많이 뽑았음

- B2C 마케팅 기여도 분석 프로세스 정립

- B2B 세일즈 파이프라인 분석 프로세스 정립

- 현업 팀들과 협업 가속화

 

 

2015년 4월 데이터 사이언스 팀 설립

- ML 모델을 프로덕션에 사용하기 시작

- A/B 프로세스 도입

- ML 모델 배포 프로세스 도입

ㄴ 다른 엔지니어링 팀과 긴밀한 협업 시작 (문화의 중요성)

ㄴ MLOps 프로세스 정착

다양한 조직에서 ML 관련 도움 쇄도

ㄴ 인력 부족 -> 분산 환경으로 전환 필요성 절감!

 

 


Udemy 추천엔진 1기

2015년 5월 ML 추천 모델 개발 시작

Hadoop 클러스터 도입

- 클라우드가 아닌 On-prem에 직접 설치

- 배치 처리에 초점을 맞춤

- Hive와 Python 기반 UDF로 사용자 이벤트 데이터 처리

ㄴ Nginx란?

보통 웹서버 들의 앞단에 로드밸런서(Load Balancer)로 사용

동시에 요청을 로그하는데 사용 (HTTP 요청헤더와 응답헤더 내용을 기록)

ㄴ 보통 이 로그를 logstash등의 툴을 사용해서 HDFS나 Kafka로 푸시

 

먼저 A/B 프로세스 도입

ㄴ 뒤에서 다시 설명. Data Driven Decision의 정점

ㄴ 객관적인 비교 프로세스를 도입하기 위함

ㄴ 자세한 분석을 위해 Tableau를 대시보드툴로 도입

 

동시에 모델 배포 프로세스에 대한 협의 시작

ㄴ 회사 문화의 중요성

ㄴ 처음에는 사용자별 추천 강의를 하루에 한번 저장하는 걸로 시작

    ㄴ Daily Batch Processing

    ㄴ 이 때 MLOps 프로세스 도입하여 매일 모델을 새로 훈련

    ㄴ 하둡 클러스터의 도입없이는 불가능했음

 

모델 배포 프로세싱 과정

1. R로 만든 모델 빌딩: 훈련 데이터는 Hive로 정제해서 만듬

2. 이를 PMML이란 포맷으로 덤프

3. PMML을 자바로 만든 추천 마이크로서비스에서 API 형태로 서빙

ㄴ 이를 백엔드 엔지니어링팀이 호출하고 모든 정보를 기록 (Impressions, Clicks, …)

ㄴ PMML을 자바에서 로딩해주는 오픈소스를 사용

 

A/B 테스트란?

- 온라인 서비스에서 새 기능의 임팩트를 객관적으로 측정하는 방법

- 새로운 기능을 론치함으로 생기는 위험부담을 줄이는 방법

ㄴ 100%의 사용자에게 론치하는 것이 아니라 작게 시작하고 관찰 후 결정

ㄴ 실제 예제: 추천을 기계학습기반으로 바꾼 경우

    ㄴ 먼저 5%의 사용자에게 론치 후 나머지 95%의 사용자와 매출액 등 중요 지표 기반 비교

    ㄴ 5%, 10%, 20% 이런 식으로 점진적으로 높이고 최종적으로 100%로 론치

 

- 보통 사용자들을 2개의 그룹으로 나누고 시간을 두고 관련 지표를 비교

ㄴ 한 그룹은 기존 기능에 그대로 노출 (control)

ㄴ 다른 그룹은 새로운 기능에 노출 (test)

 

- 가설에서 영향받는 지표를 미리 정하고 시작하는 것이 일반적

ㄴ 지표의 경우 성공/실패 기준까지 생각해보는 것이 필요

 

 


Udemy 추천엔진 2기

2016년 데이터 레이크와 Spark 도입

- Hive 중심의 YARN/Hadoop 환경에서 Hive+Spark 중심으로 변화

ㄴ Spark 트레이닝 과정을 모든 데이터 엔지니어들과 원하는 데이터 과학자들에게 제공

ㄴ S3를 데이터 레이크와 HDFS를 사용

ㄴ Hive meta-store 중심으로 테이블들을 저장

- 여전히 Redshift를 정제된 구조화 데이터 분석을 위한 DW로 사용

- Data Engineer들을 중심으로 Spark 교육 시작

ㄴ 처음에는 Scala로 개발하다가 나중에 PySpark으로 넘어감

ㄴ Notebook 환경으로 데이터 과학자들도 Spark ML을 직접 사용하기 시작

    ㄴ 주피터 노트북과 제플린 노트북

 

 

2016년 Kafka 도입

점점더 실시간 데이터 처리에 대한 요구 증대 -> Kafka 도입

ㄴ 모든 사용자 이벤트 데이터는 모두 먼저 Kafka에 저장

 

2016년 Kafka 기반으로 여러가지 기능 구현

- 이를 바탕으로 추천을 실시간으로 변경 (하루 한번 배치에서 실시간)

ㄴ 변경하는데 1년 이상 걸림. 인력 부족과 경험 부족. 모니터링 책임 논의도 오래 걸림

- 이 위에 Fraud detection 시스템도 추가

- CS 팀과 연동 => 특정 사용자가 어떤 페이지를 보았는지 확인 가능

 

 

2016년 Spark ML과 Spark Streaming 사용

- Spark이 도입되면서 ML 모델링과 스트림 데이터 처리도 시작

ㄴ Scikit-learn과 R 기반 모델링에서 Spark ML 기반으로 변경

 

- Spark-Streaming을 사용해서 추천 모델을 실시간으로 변경 (2017년 여름)

ㄴ Kafka를 사용했고 운영상의 이슈로 처음에는 쉽지 않았음 (문화의 중요성 절감)

ㄴ 일부 feature들은 배치로 계산해서 Cassandra에 저장

    ㄴ Pre-computed features라 부르고 이는 Spark SQL과 UDF를 사용

ㄴ 일부 feature들은 실시간으로 계산해서 사용

    ㄴ 이는 Spark Streaming과 Kafka 사용

 

 

 

실시간 추천 엔진 아키텍처

미리 지난 90일간 로그인한 사용자를 대상으로 계산 -> 사용자가 나타나는 순간 실시간으로 추천 계산

 

 

프로덕션 환경

 


실제로 사용자가 유데미를 방문(로그인) 한다면?

user accesses Udemy Site

Django 프레임웍은 추천 마이크로서비스의 홈 피드 API를 호출하고 새로운 방문자가 생겼음을 카프카의 특정 토픽으로 기록 (Kafka Producer 역할)

 

Input and output to the Microservice

 

Inside the Microservice

- 마이크로서비스는 먼저 사용자의 행동 및 기타 요인을 기반으로 생성할 유닛 수를 파악

ㄴ 일단 있는 정보를 바탕으로 추천 유닛과 강의 생성

ㄴ 해당 정보를 JSON 형태로 리턴

 

- 백그라운드에서 Spark Streaming Consumer가 해당 사용자에 대한 추천 강의 내용 업데이트 시작

 

 

 

Javascripts in the page starts sending logs to Nginx

-강의 노출 (impression) 로그가 Nginx로 보내짐 (hidden pixel)

ㄴ 이 정보는 추천시 필요한 negative feedback을 위해서 필요

 

-Log aggregate server에 설치된 logstash가 이를 Kafka Topic으로 로딩

 

-또한 Log aggregate server에 있는 Flume이 해당 정보를 S3로 매시간 저장

ㄴ 사실 이 부분은 Kakfa Connect 등을 이용해서 대체 가능 (나중에대체

 

 

 

강의를 선택했을때

 

 

Udemy 이벤트 처리 시스템 2기

Nginx를 기반으로 수집되던 사용자 행동 이벤트가 어떻게 발전했는지 살펴보자

 

이벤트 처리 시스템 1기 시스템 구조

- 추천 엔진 2기 개발 때부터 2021년까지 사용한 구조 - 바로 위에서 설명했던 Nginx의 구조

- Nginx를 사용해서 사용자 이벤트 수집

- 실시간처리와 배치처리를 위한 두 개의 시스템 존재

- 여러가지 문제점들이 존재

ㄴ 별도의 이벤트 수집 팀이 만들어지면서 Refactoring 시작

 

- 실시간처리와 배치처리를 위한 두 개의 시스템 존재

ㄴ 배치 처리는 syslog와 Flume을 사용 (nginx -> syslog -> Flume -> S3)

ㄴ 실시간 처리는 Kafka를 사용 (nginx -> syslog -> logstash -> Kafka)

 

배치 처리 시스템 구조

 

 


Nginx 기반 시스템 1기의 문제점

낮은 확장성

- 기존 로그 집계 서버는 확장이 쉽지 않은 복잡한 구조. Nginx, Syslog, Logstash, Flume을 사용해서 Kafka와 S3로 별도로 적재

- 이벤트 로깅이 암묵적으로 이뤄지다보니 개발자들이 실수로 삭제하거나 내용을 모르고 수정하는 일이 빈번

낮은 데이터 품질

- 기존 시스템에는 실시간 이벤트 유효성 검사 메커니즘 부재. 스키마 검증 필요!

    ㄴ 다운스트림 소비자에게 장애가 발생해야만 이슈 인지

문서화 부족

Kafka를 더 많이 활용

- Kafka Schema Registry 사용하여 이벤트 데이터 유효성 검증

- Avro를 이벤트 데이터 포맷으로 사용하여 스키마 검증

- 두 개의 이벤트 스트림 Topic을 사용

    ㄴ 하나는 원본, 다른 하나는 데이터가 추가된 버전

    ㄴ 스키마 검증에 실패한 것들만 적재하는 Topic도 운영

Kafka Connect를 사용하여 S3로 적재

이벤트 수집기를 별도 구현

- 프런트 엔드, 백엔드(Python, Kotlin), iOS, Android

- 이벤트 수집기를 K8s위에서 실행 (Auto-Scaling)

    ㄴ AWS EKS(Elastic Kubernetes Service)를 사용

 

이벤트 수집기 구조

 

이벤트 처리 시스템 2기 시스템 구조

 

 

Avro란? kafka에서 선호하는 포맷

Avro는 Row-based 데이터 포맷으로 Binary 포맷

Parquet와 비교

ㄴ Parquet는 Column-based. Avro는 Row-based

ㄴ Parquet는 Spark이나 DW등에서 데이터 분석용으로 배치 쿼리 수행시 더 적합한 포맷

ㄴ Avro는 데이터 송수신이나 스키마 변경 감지등에 더 최적화된 포맷

    ㄴ 실시간 처리 데이터 포맷으로 최적, 레이턴시가 적음

주요 데이터 파일 포맷 비교

 

 

 


공부하며 어려웠던 내용