View a markdown version of this page

모범 사례 - Amazon ElastiCache

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

모범 사례

캐시할 수 있는 데이터 선택

시맨틱 캐싱은 응답이 비교적 안정적인 반복 쿼리에 적합한 반면, 실시간 또는 매우 동적인 응답은 캐싱에 적합하지 않은 경우가 많습니다.

기존 애플리케이션 컨텍스트(예: 제품 ID, 범주, 리전 또는 사용자 세그먼트)에서 파생된 태그 및 숫자 필터를 사용하여 캐싱에 적합한 쿼리 및 응답을 결정하고 캐시 적중의 관련성을 개선합니다.

유사성 임계값 튜닝

유사성 임계값은 캐시 적중률과 응답 품질 간의 균형을 제어합니다. 사용 사례에 맞게 비용 절감과 정확성의 균형을 맞추는 임계값을 선택합니다.

Threshold 적중률 품질 위험 최적의 용도
0.95(엄격) 낮음(~25%) 매우 낮음 의료, 법률, 금융 애플리케이션
0.90(중간) 중간(~55%) 낮음 일반 챗봇
0.80(균형) 높음(~75%) 낮음-중간 FAQ 봇, IT 지원
0.75(릴랙싱됨) 매우 높음(~90%) 중간 대용량 반복 쿼리
중요

더 높은 임계값(0.90~0.95)으로 시작하고 정확도를 모니터링하면서 점진적으로 낮춥니다. A/B 테스트를 사용하여 워크로드에 가장 적합한 균형을 찾습니다.

독립 실행형 쿼리와 대화 비교

  • 독립 실행형 쿼리의 경우 - 사용자 쿼리 텍스트에 직접 의미 체계 캐싱을 적용합니다.

  • 멀티턴 대화의 경우 - 먼저 대화 메모리를 사용하여 현재 턴에 응답하는 데 필요한 주요 사실과 최근 메시지를 검색합니다. 그런 다음 전체 원시 대화를 포함하는 대신 현재 사용자 메시지와 검색된 컨텍스트의 조합에 의미 체계 캐싱을 적용합니다.

캐시 무효화 기간 설정

TTL을 사용하여 캐시 누락 시 재생성되기 전에 캐시된 응답이 제공되는 기간을 제어할 수 있습니다.

데이터 유형 권장 TTL 이론적 근거
정적 사실(문서, 정책) 24시간 팩트가 자주 변경되지 않음
제품 정보 12~24시간 대부분의 카탈로그에서 매일 업데이트됨
일반 어시스턴트 응답 1~4시간 신선도와 적중률의 균형
실시간 데이터(가격, 인벤토리) 5~15분 데이터가 자주 변경됨
대화 컨텍스트 30 분 세션 범위, 단기
# Set TTL with random jitter to spread out cache invalidations import random base_ttl = 82800 # ~23 hours jitter = random.randint(0, 3600) # Up to 1 hour of jitter valkey_client.expire(cache_key, base_ttl + jitter)
작은 정보

애플리케이션 사용 사례 및 데이터 또는 모델 출력 변경 빈도와 일치하는 TTLs을 설정합니다. TTLs 길수록 캐시 적중률이 증가하지만 오래된 답변의 위험이 높아집니다. TTLs 짧을수록 응답이 더 최신 상태로 유지되지만 캐시 적중률은 낮으며 더 많은 LLM 추론이 필요합니다.

모니터링 및 비용 추적

캐시 성능 지표를 추적하여 시간 경과에 따라 의미 체계 캐시를 최적화합니다.

def record_cache_event(valkey_client, event_type: str): """Track cache hits and misses using atomic counters.""" valkey_client.incr(f"cache:metrics:{event_type}") # Also track hourly for time-series analysis from datetime import datetime hour_key = datetime.now().strftime("%Y%m%d%H") counter_key = f"cache:metrics:{event_type}:{hour_key}" valkey_client.incr(counter_key) valkey_client.expire(counter_key, 86400 * 7) # Keep 7 days def get_cache_stats(valkey_client) -> dict: """Get current cache performance metrics.""" hits = int(valkey_client.get("cache:metrics:hit") or 0) misses = int(valkey_client.get("cache:metrics:miss") or 0) total = hits + misses hit_rate = hits / total if total > 0 else 0 avg_cost_per_call = 0.015 # Example: ~$0.015 per LLM call savings = hits * avg_cost_per_call return { "total_requests": total, "hits": hits, "misses": misses, "hit_rate": round(hit_rate, 3), "estimated_savings_usd": round(savings, 2), }

메모리 관리

  • 최대 정책 설정 - 클러스터가 메모리 제한maxmemory-policy allkeys-lru에 도달하면 least-recently-used 캐시 항목을 자동으로 제거하도록 ElastiCache 클러스터에서를 구성합니다.

  • 용량 계획 - 각 캐시 항목에는 일반적으로 약 4~6KB(임베딩 차원 × 4바이트 + 쿼리 텍스트 + 응답 텍스트)가 필요합니다. 1GB ElastiCache 인스턴스는 약 170,000개의 캐시된 항목을 저장할 수 있습니다.

  • 오래된 데이터에 캐시 무효화 사용 - 기본 데이터가 변경될 때 텍스트 검색을 사용하여 관련 캐시 항목을 찾고 무효화합니다.

    def invalidate_by_topic(valkey_client, topic_keyword: str): """Remove cached entries matching a topic after a data update.""" results = valkey_client.execute_command( "FT.SEARCH", "semantic_cache", f"@query:{topic_keyword}", "NOCONTENT", # Only return keys, not fields ) if results[0] > 0: keys = results[1:] for key in keys: valkey_client.delete(key) print(f"Invalidated {len(keys)} cached entries for '{topic_keyword}'")