쿠팡 기술 블로그를 개인적인 공부를 위해 정리했습니다.
쿠팡의 검색 목표
- 고객이 "쿠팡 없이 어떻게 살았을까?"라고 묻는 세상을 만드는 것
- 고객 검색 키워드를 통해 최고의 프로덕트(연관 상품, 랭킹, 상품평, 가격, 브랜드)를 제공하는 것
- 관련성(relevancy)이 가장 중요한 웹 검색 엔진(ex. Google)과 달리,
상품의 랭킹, 상품평, 가격, 브랜드 등의 요소도 중시
개요
검색 엔진 작동 과정
- query(검색어) 이해
고객의 검색 의도 및 카테고리/브랜드와 같은 부차적인 단어(query annotation) 파악
- 검색
query와 상품 텍스트 정보를 기반으로 대응하는 상품 후보군 검색
- Ranking (순위 부여)
ranking function / ML model을 활용해 후보 상품들의 순위 도출
ranking function : Score = f(텍스트 관련성, 순위, 상품평, 가격, ...) (랭킹 시그널을 통한 스코어링)
- Twiddling
프로모션과 같은 비즈니스 로직에 따라 다시 한번 순위 정렬
인덱싱 플랫폼
- 검색 및 랭킹을 위한 모든 데이터를 제공
- 모든 데이터를 통합해 검색 엔진을 위한 검색 인덱스 생성
⇒ 인덱싱 플랫폼을 잘 구성하는 것이 핵심!
- 랭킹 알고리즘 개발에 필요한 데이터를 위해서는 인덱싱 플랫폼 구축이 잘 되어 있어야 한다.

1) 인덱싱 플랫폼 0.1

- 초기에는 보유 상품 수가 많지 않았다.
- Ground Truth (원본 데이터)를 가격, 카테고리, 브랜드 등과 같은 RDBMS에 저장했고,
SQL을 활용해서 상품키를 통한 table join 방식으로 비정규화된 테이블에 통합
- 생성된 비정규화 테이블을 온라인 서빙 검색 클러스터 에 전달해 다이나믹 인덱스 생성
(비정규화 테이블을 검색 클러스터에 전달해서 이를 인덱싱 플랫폼으로 활용 했다는 의미?)
- 상품의 텍스트와 간단한 시그널 정보를 통한 기초 랭킹을 바탕으로 검색 기능 제공
- 문제점
- 관계형 데이터베이스의 수십 개의 테이블을 조인하는 과정이 너무 느리고 불안정하다.
- RDMBS와 온라인 서빙 서치 클러스터를 단순 연결할 뿐 플랫폼이 아니다.
- 많은 양의 데이터 처리를 위한 확장이 불가능
- 온라인 서빙 검색 클러스터에서 인덱스를 구축하는 것이 매우 오랜 시간 걸리며, replica(복제본)를 생성시 같은 데이터를 복제하는 것이기 때문에 자원이 많이 낭비됐다.
- 랭킹 엔지니어가 검색/랭킹 시그널을 단기간(며칠)에 추가하는 것이 불가능한 수준이다.
2) 인덱싱 플랫폼 1.0

- 모든 원본 데이터(ground truth)는 하이브(Hive. 하둡의 데이터 웨어하우스)로 복제
랭킹 시그널도 하이브 테이블로 생성됨
- Index Merger : Spark Job (모든 데이터를 Product Join으로 병합)
Product Join : protobuf 구조 (상품에 대한 모든 것을 갖춤)
- 병합된 데이터는 Hbase에 저장
- 다른 Index Builder가 hbase에서 Product Join을 사용해 검색 인덱스를 생성하고 이를 분산 스토리지에 저장
- 문제점
- 랭킹 개발자의 작업량
- 랭킹 시그널 구축에 대한 향상성 문제 (신속한 시그널 구축과는 거리가 멂)
- 주니어 랭킹 개발자가 개발한 신규 시그널 같은 경우,
병합할 데이터 소스를 찾고, 데이터 파이프 라인을 처리하고, 워크 플로우 일정을 관리하는데 리소스 소요가 컸다.
3) 인덱싱 플랫폼 2.0

인덱싱 플랫폼 2.0은 랭킹 개발자가 데이터 소스, 데이터 파이프 라인 및 워크 플로우 일정 관리에 대한 걱정없이 오롯이 시그널의 로직에 집중할 수 있도록 해주는 인덱싱 버스(Indexing Bus)
-
대부분의 시그널이 플랫폼 내부에서 생성됨
(인덱싱 플랫폼 1.0의 경우 외부 하이브 테이블에서 시그널 병합)
-
모든 원본 데이터가 Ground Truth Merger에 의해 병합돼 Session Log Parser로 모든 고객 행동을 parsing하고 merge. (모두 Spark Job)
-
Product Joiner 와 Query Joiner는 원본 데이터 및 세션 로그를 기반으로 모든 시그널 파생 (강력)
ex. Query Join을 구축할 때 Product Join의 가격 정보를 활용해서 쿼리 가격 분포를 구축한 뒤, 상품 가격과 쿼리 가격 분포를 바탕으로 상품을 boosting / demote 하는 시그널을 생성할 수 있다.
-
Query Join을 통한 시그널 생성 프로세스
- 원본 데이터 및 파싱된 세션 로그를 포함한 모든 소스 데이터를 로드
- 노출, 클릭, 구매와 같은 기본적으로 집계된 원시 고객 행동 데이터를 쿼리 수준 및 상품 쿼리 수준으로 생성
- 모든 시그널 프로세서를 실행해 시그널을 생성
- 모든 시그널을 갖춘 Query Join을 Hbase에 저장
-
장점
- 신규 랭킹 시그널 구축이 빠르게 진행되기 때문에, 시그널 로직에만 집중할 수 있다.
- 클러스터 자원이 절약되며, 신규 시그널 추가 과정에 리소스 소모가 거의 없다.
- 시그널 품질 테스트가 제공된다.
References