추천 시스템을 실시간에 가깝게 만들려면 사용자의 행동을 빠르게 모으고, 그 행동을 모델이 이해할 수 있는 형태로 바꾼 뒤, 검색 API에서 바로 활용할 수 있어야 한다. 핵심은 “학습”과 “서빙”을 분리하되, 사용자 행동은 최대한 짧은 지연으로 서빙 쪽에 반영하는 것이다.
사용자가 검색하거나 가게를 클릭하면 행동 이벤트를 Kafka로 보낸다. Kafka Connect를 쓰면 이 이벤트를 MongoDB 같은 저장소에 적재해 이후 분석이나 재처리에 사용할 수 있다. 실시간 집계가 필요하면 Flink가 스트림을 읽어서 최근 행동, 카테고리 선호, 클릭 빈도 같은 특징을 계속 갱신한다.
모델 학습은 보통 별도의 배치 파이프라인에서 처리한다. Airflow로 학습 작업을 스케줄링하고, PyTorch 기반 인코더 모델로 가게나 검색어를 임베딩 벡터로 변환한다. 만들어진 임베딩은 Hive 같은 저장소에 보관한 뒤, 서빙에 필요한 형태로 벡터 데이터베이스에 업로드한다.
실제 추천 요청이 들어오면 FastAPI 서버가 사용자의 최근 행동 이력을 조회하고, 그 행동을 기준으로 비슷한 가게나 검색어 벡터를 찾는다. 이때 벡터 유사도 검색을 사용한다. Exact KNN은 모든 벡터와의 거리를 정확하게 계산하므로 결과는 정확하지만 데이터가 커질수록 비용이 크다. ANN은 근사 최근접 이웃 방식이라 약간의 정확도를 양보하는 대신 훨씬 빠르게 후보를 찾을 수 있다.
PostgreSQL에 pgvector 같은 확장을 붙여 벡터 유사도 검색을 처리할 수도 있다. 규모가 크지 않거나 운영 복잡도를 줄이고 싶다면 좋은 선택이다. 다만 데이터가 커지고 지연 시간이 더 중요해지면 전용 벡터 데이터베이스나 ANN 인덱스를 따로 검토해야 한다.
이 구조에서 가장 조심해야 할 부분은 최신성과 안정성의 균형이다. 행동 이벤트를 너무 늦게 반영하면 “방금 본 것과 관련된 추천”이 나오지 않는다. 반대로 모든 것을 즉시 반영하려고 하면 파이프라인이 복잡해지고 장애 지점이 늘어난다. 그래서 실시간으로 반영할 특징과 배치로 갱신해도 되는 임베딩을 나누는 것이 설계의 출발점이다.