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는 데이터 송수신이나 스키마 변경 감지등에 더 최적화된 포맷
ㄴ 실시간 처리 데이터 포맷으로 최적, 레이턴시가 적음
주요 데이터 파일 포맷 비교
공부하며 어려웠던 내용
'프로그래머스 데브코스-데이터 엔지니어 > TIL(Today I Learned)' 카테고리의 다른 글
07/13 69일차 Kafka CLI, Topic, Consumer, ksqlDB (0) | 2023.07.13 |
---|---|
07/12 68일차 Kafka (0) | 2023.07.12 |
07/10 66일차 스트리밍 데이터 (0) | 2023.07.10 |
07/07 65일차 Spark EMR과 Spark 요약 (0) | 2023.07.07 |
07/06 64일차 Spark의 내부동작 | ML | 클라우드 (0) | 2023.07.06 |