증분 처리: 빠른 파이프라인 업데이트

이 문서는 SEO 파이프라인이 어떻게 증분 처리를 사용하여 몇 시간이 아닌 몇 초 만에 실행되는지 설명합니다.

문제점: 전체 재처리는 느리다

파이프라인 전체를 처음부터 실행하는 데는 몇 시간이 걸립니다:

  • 단계 0 (소스 임베딩): 15분 (제품 65,000개)

  • 단계 1 (쿼리 가져오기): 10분 (API 호출)

  • 단계 2 (쿼리 클러스터링): 30분 (65K×65K 유사도 계산)

  • 단계 3 (구문 매핑): 20분 (임베딩 + 매칭)

  • 단계 4 (제품 매칭): 45분 (쿼리 × 제품)

  • 단계 5 (관련 검색어): 25분 (쿼리 × 쿼리 유사도)

총계: 전체 파이프라인 실행 약 2.5시간

문제: 일일 업데이트는 변경되지 않은 데이터를 다시 계산하는 데 2.5시간을 낭비하게 됩니다.

해결책: 3계층 증분 전략

불필요한 작업을 건너뛰기 위해 세 가지 기술을 사용합니다:

1. 단계 건너뛰기 (Coarse-Grained)

출력이 최신 상태이고 스크립트가 변경되지 않았다면 전체 단계를 건너뜁니다.

2. 증분 임베딩 (Medium-Grained)

새롭거나 변경된 항목만 임베딩하고, 캐시된 임베딩을 재사용합니다.

3. 체크포인팅 (Fine-Grained)

긴 작업 중 진행 상황을 저장하고, 실패 시 체크포인트에서 재개합니다.

단계 건너뛰기 전략

작동 방식

각 단계 실행 전에 다음을 확인합니다:

출력이 존재하는가? 없으면 단계를 실행합니다.

출력 연령: 7일보다 오래되었다면 단계를 실행합니다.

스크립트가 변경되었는가? 출력이 생성된 이후 스크립트가 수정되었다면 단계를 실행합니다.

모든 검사를 통과하는가? 단계를 건너뜁니다.

구현

def should_skip_step(output_path, script_path, days=7):
    # Check if output exists
    if not os.path.exists(output_path):
# ... (implementation details omitted)

사용법

각 스크립트는 시작 시 확인합니다:

from seo_common import should_skip_step

if should_skip_step(SEO_SOURCE_EMBEDDINGS_PATH, __file__):
    print("✓ Skipping: Output is fresh and script unchanged")
    return

장점

빠른 일일 실행: 데이터가 변경되지 않았다면 대부분의 단계를 건너뜁니다.

자동 무효화: 스크립트 변경 시 재실행이 트리거됩니다.

구성 가능한 신선도: 단계별 days 매개변수를 조정할 수 있습니다.

증분 임베딩 전략

작동 방식

항목(제품, 쿼리, 구문)을 임베딩할 때:

캐시 로드: 이전에 임베딩된 항목과 해당 키를 읽습니다.

키 비교: 새롭거나 변경되거나 삭제된 항목을 식별합니다.

새 항목만 임베딩: 캐시에 없는 항목만 임베딩합니다.

병합: 캐시된 임베딩과 새로운 임베딩을 올바른 순서로 결합합니다.

저장: 업데이트된 캐시를 기록합니다.

구현

incremental_embed_with_keys 함수가 이를 처리합니다:

def incremental_embed_with_keys(
    items,           # Current items to embed
    keys,            # Unique keys for items
# ... (implementation details omitted)

캐시 적중률

첫 실행 후 일반적인 캐시 적중률:

소스 데이터 (제품, 부품, 문서):

  • 첫 실행: 0% (항목 65,000개 모두 임베딩)

  • 일일 실행: 99.5% (새롭거나 변경된 항목 약 300개만)

쿼리 (GSC, 광고, 실시간):

  • 첫 실행: 0% (쿼리 65,000개 모두 임베딩)

  • 일일 실행: 99.2% (새 쿼리 약 500개만)

구문 매핑:

  • 첫 실행: 0% (구문 5,000개 모두 임베딩)

  • 일일 실행: 99.8% (새 구문 약 10개만)

성능 영향

첫 실행 (콜드 캐시):

  • 소스 임베딩: 15분 (항목 65,000개)

  • 쿼리 임베딩: 10분 (쿼리 65,000개)

  • 구문 임베딩: 2분 (구문 5,000개)

일일 실행 (웜 캐시):

  • 소스 임베딩: 10초 (항목 300개, 적중률 99.5%)

  • 쿼리 임베딩: 5초 (쿼리 500개, 적중률 99.2%)

  • 구문 임베딩: 1초 (구문 10개, 적중률 99.8%)

속도 향상: 90-180배 더 빠름

체크포인팅 전략

작동 방식

장시간 실행되는 작업(항목 65,000개 임베딩)의 경우:

배치 처리: 항목을 배치(예: 1,000개 항목)로 처리합니다.

체크포인트 저장: 각 배치 후 누적 결과를 저장합니다.

실패 시 재개: 프로세스가 중단되면 마지막 체크포인트에서 재개합니다.

최종 저장: 모든 배치 후 완전한 결과를 저장합니다.

구현

체크포인팅은 incremental_embed_with_keys에 내장되어 있습니다:

checkpoint_every = 1000  # Save every 1,000 items

embeddings_list = []
# ... (implementation details omitted)

장점

중단 복구: 처음부터 다시 시작하는 대신 마지막 체크포인트에서 재개합니다.

진행 상황 가시성: 1,000개 항목마다 진행 상황을 확인할 수 있습니다.

메모리 효율성: 배치로 처리하여 한 번에 모두 로드하지 않습니다.

파이프라인 전반의 통합

증분 처리는 여러 단계에서 사용됩니다:

단계 0: 소스 데이터 임베딩

증분: 새롭거나 변경된 제품, 부품, 문서만 임베딩합니다.

체크포인팅: 1,000개 항목마다 저장합니다.

건너뛰기 로직: 출력이 7일 미만이고 스크립트가 변경되지 않았다면 건너뜁니다.

참조: 소스 데이터 임베딩

단계 1: 쿼리 가져오기

증분: API 호출은 (마지막 실행 이후) 새로운 데이터만 가져옵니다.

건너뛰기 로직: 출력이 1일 미만이면 건너뜁니다.

참조: 쿼리 가져오기

단계 3b: 쿼리 임베딩

증분: 새 쿼리만 임베딩합니다.

체크포인팅: 1,000개 쿼리마다 저장합니다.

건너뛰기 로직: 출력이 7일 미만이고 스크립트가 변경되지 않았다면 건너뜁니다.

참조: 쿼리 임베딩

단계 4: 구문 매핑 확장

증분: 새 구문만 임베딩합니다.

체크포인팅: 1,000개 구문마다 저장합니다.

건너뛰기 로직: 출력이 7일 미만이고 스크립트가 변경되지 않았다면 건너뜁니다.

참조: 구문-필터 매핑

단계 6: 제품 매칭

증분: 새 쿼리만 매칭합니다.

건너뛰기 로직: 출력이 7일 미만이고 스크립트가 변경되지 않았다면 건너뜁니다.

참조: 제품 매칭

구성

증분 처리는 단계별로 구성됩니다:

신선도 임계값

# 출력이 7일 미만이면 건너뜁니다 (기본값)
should_skip_step(output_path, script_path, days=7)

# 출력이 1일 미만이면 건너뜁니다 (자주 변경되는 데이터용)
should_skip_step(output_path, script_path, days=1)

체크포인트 빈도

# 1,000개 항목마다 저장 (기본값)
incremental_embed_with_keys(..., checkpoint_every=1000)

# 5,000개 항목마다 저장 (더 빠른 처리, 안전성 감소)
incremental_embed_with_keys(..., checkpoint_every=5000)

배치 크기

# 배치당 32개 항목 임베딩 (기본값, 균형 잡힘)
incremental_embed_with_keys(..., batch_size=32)

# 배치당 64개 항목 임베딩 (GPU에서 더 빠름, 메모리 더 많이 사용)
incremental_embed_with_keys(..., batch_size=64)

모니터링 및 디버깅

캐시 통계

각 단계는 캐시 통계를 출력합니다:

✓ Found existing cache, checking for changes...
  Existing: 65,000 items
  Current:  65,300 items
  Reusing: 64,800 embeddings
  New:     500 items to embed

건너뛰기 메시지

단계가 건너뛰어질 때:

✓ Skipping 0_embed_source_data.py: Output is fresh and script unchanged.

체크포인트 메시지

긴 작업 중:

Embedding 65,000 items (checkpointing every 1,000)...
  Batch 0-1000...
    ✓ Checkpoint saved (1,000 total)
  Batch 1000-2000...
    ✓ Checkpoint saved (2,000 total)
  ...

참고 자료

기술 개념

관련 문서

요약

증분 처리는 파이프라인을 90-180배 더 빠르게 만듭니다:

3계층 전략:

  • ✅ 단계 건너뛰기 (출력이 최신 상태면 전체 단계 건너뛰기)

  • ✅ 증분 임베딩 (새롭거나 변경된 항목만 임베딩)

  • ✅ 체크포인팅 (진행 상황 저장, 실패 시 재개)

성능:

  • ✅ 첫 실행: 약 2.5시간 (전체 파이프라인)

  • ✅ 일일 실행: 약 5분 (증분 업데이트)

  • ✅ 캐시 적중률: 첫 실행 후 99% 이상

장점:

  • ✅ 빠른 일일 업데이트 (시간 대신 분 단위)

  • ✅ 자동 무효화 (스크립트 변경 시 재실행 트리거)

  • ✅ 중단 복구 (체크포인트에서 재개)

  • ✅ 메모리 효율적 (배치 처리)

이 전략은 변경되지 않은 데이터에 대한 컴퓨팅 자원을 낭비하지 않고도 일일 파이프라인 실행을 가능하게 합니다.


← 문서 인덱스로 돌아가기