문제 정의
오늘은 대형 소매업체 BigBoxCo의 '인프라' 팀에서의 첫날입니다. 의무적인 인사 관리 활동을 마친 후, 계약자 배지를 받고 새 작업 공간으로 이동했습니다. 팀을 만나고 나서 "추천 시스템" 팀과의 회의가 있다는 소식을 들었습니다. 시스템 접근 권한이 아직 활성화되지 않았지만, 회의 중에 IT 팀이 이 문제를 해결해 줄 것입니다.
회의실에 도착하니, 나와 함께 새 팀의 매니저와 두 명의 엔지니어, 그리고 추천 시스템 팀의 한 명의 엔지니어가 있었습니다. 간단한 소개를 마친 후, 지난주에 있었던 야간 배치 작업 실패에 대해 논의하기 시작했습니다. 이로 인해 현재까지도 영향을 받고 있다고 합니다.
현재의 제품 추천 시스템은 고객 주문에서 수집된 데이터를 기반으로 작동합니다. 각 주문에 대해 제품 간의 연관 관계가 기록되며, 고객이 제품 페이지를 조회할 때, 해당 제품과 함께 다른 고객이 구매한 제품들을 추천해 줍니다.
추천 시스템은 마이크로서비스 계층을 통해 클라우드에서 사용자에게 제공됩니다. 마이크로서비스 계층은 Apache Cassandra를 사용하여 결과를 제공하는데, 이 결과를 수집하고 제공하는 방법은 또 다른 이야기입니다. 제품 간의 연관 관계를 도출하는 작업은 MapReduce 작업을 통해 수행됩니다. 이 배치 프로세스가 지난주에 실패했습니다. 이 배치 프로세스는 원래부터 빠르지 않았지만, 시간이 지남에 따라 더 느리고 불안정해졌습니다. 실제로 이 프로세스는 이틀, 심지어 사흘이 걸리기도 합니다.
개선 방안
회의가 끝난 후, 컴퓨터에 로그인을 시도했는데 드디어 접근 권한이 활성화되었습니다. 이때, 우리의 수석 엔지니어가 다가와서 자신을 소개했습니다. 나는 추천 시스템 팀과의 회의 내용을 설명했고, 그는 추천 서비스의 역사에 대해 좀 더 자세히 설명해 주었습니다.
이 배치 프로세스는 약 10년 전부터 존재해왔으며, 이를 설계한 엔지니어는 이미 회사를 떠났다고 합니다. 현재는 이 시스템을 제대로 이해하는 사람이 거의 없으며, 아무도 이 시스템을 손대고 싶어하지 않는 상황입니다.
또 다른 문제는 추천 데이터를 실시간으로 업데이트할 수 없다는 점입니다. 데이터는 거의 항상 이틀 정도 뒤쳐져 있습니다. 이는 전체적인 문제로 보이지 않을 수 있지만, 마케팅에서 단기 프로모션을 진행할 때는 실시간 데이터가 큰 도움이 될 것입니다.
수석 엔지니어는 시스템 개선에 대한 내 제안에 동의하며, 시스템을 개선할 방법에 대해 열려 있다고 했습니다.
그래프 문제로 접근하기
처음에는 이것이 그래프 문제처럼 보였습니다. 고객이 사이트에 접속해 제품을 구매하면, 이를 통해 "이 제품을 구매한 고객은 다른 어떤 제품도 구매했다"는 형태의 추천을 제공할 수 있습니다. 현재 사이트는 이러한 기능을 제공하고 있으며, 추천 서비스는 정확히 이러한 작업을 수행합니다. 즉, 가장 자주 함께 구매된 네 가지 추가 제품을 반환합니다.
하지만 제품 하나당 2억 명의 고객이 구매한 다른 모든 제품과의 연관 관계를 매핑하려면 데이터 크기가 급격히 커질 것입니다. 따라서 제품이 주문에 나타나는 횟수로 순위를 매길 필요가 있습니다.
실제 데이터 볼륨으로 그래프 데이터베이스에서 모델링한 결과, 이것이 효과적이지 않다는 것을 깨달았습니다. 한 제품에서 인근 고객으로, 그리고 그들의 제품으로의 탐색 및 제품 출현 빈도를 계산하는 데 약 10초가 소요되었습니다. 결국 이틀 걸리는 배치 문제를 각 조회 시 탐색 지연으로 대체하게 되었습니다.
하지만 이 그래프 모델이 우리가 필요한 것에서 크게 벗어나지 않았습니다. 사실, 위에서 설명한 접근 방식은 "협업 필터링"이라는 기계 학습(ML) 기법입니다. 협업 필터링은 다른 사용자와의 활동을 기반으로 특정 데이터 객체의 유사성을 검사하여 예측을 가능하게 합니다. 우리의 경우, 고객의 장바구니/주문 데이터를 암묵적으로 수집하고, 이를 사용해 더 나은 제품 추천을 제공하여 온라인 판매를 증가시키려고 합니다.
구현 방법
먼저, 데이터 수집을 살펴보겠습니다. 쇼핑 "주문 완료" 기능에 추가 서비스 호출을 추가하는 것은 큰 문제가 아닙니다. 사실, 이미 존재하는 기능입니다. 다만, 데이터가 데이터베이스에 저장되고 나중에 처리됩니다. 배치 처리는 계속 유지할 필요가 있습니다. 하지만 그 장바구니 데이터를 실시간으로 처리하여 온라인 데이터 세트에 즉시 반영할 수 있어야 합니다.
이를 위해 Apache Pulsar와 같은 이벤트 스트리밍 솔루션을 도입할 것입니다. 이렇게 하면 모든 새로운 장바구니 활동이 Pulsar 주제로 전달되고, 여기서 소비되어 기본 배치 데이터베이스와 실시간 ML 모델 학습에 사용됩니다.
후자의 경우, 우리의 Pulsar 소비자는 아래와 같이 각 주문의 제품 항목을 저장하는 단순한 테이블에 쓰게 됩니다:
CREATE TABLE order_products_mapping (
id text,
added_product_id text,
cart_id uuid,
qty int,
PRIMARY KEY (id, added_product_id, cart_id)
) WITH CLUSTERING ORDER BY (added_product_id ASC, cart_id ASC);
그런 다음 특정 제품에 대해 이 테이블을 쿼리할 수 있습니다:
SELECT added_product_id, SUM(qty)
FROM order_products_mapping
WHERE id='DSH915'
GROUP BY added_product_id;
결과는 다음과 같습니다:
added_product_id | system.sum(qty)
------------------+-----------------
APC30 | 7
ECJ112 | 1
LN355 | 2
LS534 | 4
RCE857 | 3
RSH2112 | 5
TSD925 | 1
(7 rows)
이제 상위 네 개 결과를 추천 서비스가 product_id로 쿼리할 수 있도록 제품 추천 테이블에 넣습니다:
SELECT * FROM product_recommendations
WHERE product_id='DSH915';
결과는 다음과 같습니다:
product_id | tier | recommended_id | score
------------+------+----------------+-------
DSH915 | 1 | APC30 | 7
DSH915 | 2 | RSH2112 | 5
DSH915 | 3 | LS534 | 4
DSH915 | 4 | RCE857 | 3
이렇게 하면 새로운 추천 데이터가 지속적으로 최신 상태로 유지됩니다. 또한, 위에서 설명한 모든 인프라 자산은 로컬 데이터 센터에 위치해 있습니다. 따라서 주문에서 제품 관계를 추출하고, 이를 Pulsar 주제를 통해 전송하며, Cassandra에 저장된 추천으로 처리하는 과정이 1초 이내에 완료됩니다. 이 간단한 데이터 모델을 통해 Cassandra는 요청된 추천을 밀리초 단위로 제공할 수 있습니다.
결론 및 다음 단계
장기적으로 Cassandra 테이블에 데이터가 쓰이는 방식을 검토해야 합니다. 이를 통해 무제한 행 증가 및 인플레이스 업데이트와 관련된 잠재적 문제를 사전에 방지할 수 있습니다.
또한, "추천하지 않음" 목록과 같은 추가 휴리스틱 필터를 추가하는 것도 필요할 수 있습니다. 이는 고객이 한 번 또는 드물게 구매하는 제품에 대한 추천을 피하고, 즉흥적으로 구매할 가능성이 더 높은 다른 제품에 공간을 할애하기 위해서입니다. 예를 들어, 세탁기와 같은 가전제품을 추천하는 것은 즉흥 구매를 유도하지 않을 가능성이 큽니다.
향후 개선 사항으로는 제품 관계 스트리밍과 추천 데이터를 서비스에 직접 제공하기 위해 Kaskada와 같은 실시간 AI/ML 플랫폼을 구현하는 것이 있습니다.
다행히도, 우리는 카트 추가 이벤트를 실시간으로 처리하기 위해 Pulsar를 사용하여 기존의 느린 배치 프로세스를 보완하는 방법을 찾아냈습니다. 이 시스템의 장기적인 성능을 파악한 후에는 기존 배치 프로세스를 종료하는 것도 고려해야 합니다. 수석 엔지니어는 새로운 솔루션을 통해 좋은 진전을 이뤘다고 인정했으며, 기술 부채를 줄이기 위한 기초도 마련했다고 평가했습니다. 결국, 모두가 좋은 성과를 냈다고 느꼈습니다.
'SW > 인공지능' 카테고리의 다른 글
LangChain과 대형 언어 모델(LLMs)에 대한 종합 가이드 (0) | 2024.06.26 |
---|---|
레거시 시스템과 기술 부채의 도전 과제 극복하기: Curiosity Software의 LLM 적용 사례 (0) | 2024.06.24 |
CassIO: OpenAI에 영감을 받은 최고의 생성적 AI 라이브러리 (0) | 2024.06.22 |
생성적 AI 시대에 StackOverflow가 적응하는 방법: 포괄적 가이드 (0) | 2024.06.21 |
효율적인 프롬프트 엔지니어가 되는 방법: 종합 가이드 (0) | 2024.06.20 |