본문으로 건너뛰기

Search 서비스

개요

Search 서비스는 OpenSearch를 활용한 상품 검색 기능을 제공합니다. Kafka를 통해 Product Catalog의 변경 이벤트를 수신하여 검색 인덱스를 자동으로 동기화하며, Secondary 리전에서는 DocumentDB 변경 스트림을 통해 데이터를 동기화합니다.

항목내용
언어Go 1.21+
프레임워크Gin
데이터베이스OpenSearch, DocumentDB (Change Stream)
캐시ElastiCache (Valkey)
네임스페이스core-services
포트8080
헬스체크/healthz, /readyz

아키텍처

주요 기능

1. 상품 검색

  • 멀티 필드 검색 (이름, 설명, SKU)
  • 카테고리 필터링
  • 가격 범위 필터링
  • 페이지네이션

2. 검색 결과 캐싱

  • Valkey를 통한 검색 결과 캐싱 (5분 TTL)
  • 캐시 키 기반 중복 쿼리 방지

3. 실시간 인덱스 동기화

  • Kafka 이벤트를 통한 인덱스 업데이트
  • DocumentDB Change Stream을 통한 Secondary 리전 동기화

API 엔드포인트

상품 검색

메서드경로설명
GET/api/v1/search상품 검색

요청 파라미터

파라미터타입필수설명기본값
qstringN검색 키워드-
categorystringN카테고리 ID-
min_pricefloatN최소 가격-
max_pricefloatN최대 가격-
pageintN페이지 번호1
sizeintN페이지 크기 (최대 100)20

요청 예시

GET /api/v1/search?q=노트북&category=electronics&min_price=500000&max_price=2000000&page=1&size=20

응답 예시

{
"products": [
{
"id": "prod-001",
"name": "삼성 갤럭시북 프로",
"description": "15.6인치 AMOLED 디스플레이 노트북",
"sku": "SGB-PRO-15",
"price": 1590000,
"currency": "KRW",
"category_id": "electronics",
"images": [
"https://cdn.example.com/products/sgb-pro-1.jpg"
],
"attributes": {
"brand": "Samsung",
"display_size": "15.6",
"memory": "16GB"
},
"is_active": true
}
],
"total": 42,
"page": 1,
"size": 20
}

데이터 모델

Product (검색 인덱스)

type Product struct {
ID string `json:"id"`
Name string `json:"name"`
Description string `json:"description"`
SKU string `json:"sku"`
Price float64 `json:"price"`
Currency string `json:"currency"`
CategoryID string `json:"category_id"`
Images []string `json:"images"`
Attributes map[string]string `json:"attributes"`
IsActive bool `json:"is_active"`
}

SearchParams

type SearchParams struct {
Query string // 검색 키워드
Category string // 카테고리 필터
MinPrice *float64 // 최소 가격
MaxPrice *float64 // 최대 가격
Page int // 페이지 번호
Size int // 페이지 크기
}

SearchResult

type SearchResult struct {
Products []Product `json:"products"`
Total int64 `json:"total"`
Page int `json:"page"`
Size int `json:"size"`
}

OpenSearch 인덱스 매핑

{
"mappings": {
"properties": {
"id": {"type": "keyword"},
"name": {"type": "text", "analyzer": "standard"},
"description": {"type": "text", "analyzer": "standard"},
"sku": {"type": "keyword"},
"price": {"type": "float"},
"currency": {"type": "keyword"},
"category_id": {"type": "keyword"},
"is_active": {"type": "boolean"}
}
}
}

이벤트 (Kafka)

구독하는 토픽

토픽설명Consumer Group
catalog.product.created상품 생성 이벤트search-indexer
catalog.product.updated상품 수정 이벤트search-indexer
catalog.product.deleted상품 삭제 이벤트search-indexer

이벤트 페이로드 예시

product.created / product.updated

{
"event": "product.created",
"product": {
"id": "prod-001",
"name": "삼성 갤럭시북 프로",
"description": "15.6인치 AMOLED 디스플레이 노트북",
"sku": "SGB-PRO-15",
"price": 1590000,
"currency": "KRW",
"category_id": "electronics",
"images": ["https://cdn.example.com/products/sgb-pro-1.jpg"],
"attributes": {"brand": "Samsung"},
"is_active": true
}
}

product.deleted

{
"event": "product.deleted",
"product_id": "prod-001"
}

환경 변수

변수명설명기본값
PORT서버 포트8080
AWS_REGIONAWS 리전us-east-1
REGION_ROLE리전 역할 (PRIMARY/SECONDARY)PRIMARY
OPENSEARCH_ENDPOINTOpenSearch 엔드포인트http://localhost:9200
CACHE_HOSTElastiCache 호스트localhost
CACHE_PORTElastiCache 포트6379
KAFKA_BROKERSKafka 브로커 주소localhost:9092
DOCUMENTDB_HOSTDocumentDB 호스트 (Secondary)localhost
DOCUMENTDB_PORTDocumentDB 포트27017
LOG_LEVEL로그 레벨info

서비스 의존성

의존하는 서비스

서비스용도
OpenSearch검색 인덱스 저장 및 쿼리
ElastiCache (Valkey)검색 결과 캐싱
MSK (Kafka)상품 변경 이벤트 수신
DocumentDBChange Stream (Secondary 리전)

이 서비스에 의존하는 컴포넌트

컴포넌트용도
API Gateway검색 API 라우팅
웹/모바일 클라이언트상품 검색

멀티 리전 동작

Primary 리전 (us-east-1)

  • Kafka 이벤트를 통해 Product Catalog 변경사항 수신
  • OpenSearch 인덱스 업데이트

Secondary 리전 (us-west-2)

  • Kafka 이벤트 + DocumentDB Change Stream 이중 동기화
  • DocumentDB Global Cluster의 복제 데이터를 Change Stream으로 감지
  • 로컬 OpenSearch 인덱스 업데이트

캐싱 전략

검색 결과는 Valkey에 5분간 캐싱됩니다.

캐시 키 형식

search:{query}:{category}:{page}:{size}[:min{price}][:max{price}]

예시:

search:노트북:electronics:1:20:min500000:max2000000