Post

πŸ“ƒ DATT 02 - λΆ€ν•˜ ν…ŒμŠ€νŠΈ 및 병λͺ© ꡬ간 뢄석

πŸ“ƒ DATT 02 - λΆ€ν•˜ ν…ŒμŠ€νŠΈ 및 병λͺ© ꡬ간 뢄석

ν”„λ‘œμ νŠΈ κ°œμš”

DATTλŠ” μœ„μΉ˜ 기반 μž₯μ†Œ 기둝 및 곡유 ν”Œλž«νΌμ΄λ‹€.

ν˜„μž¬ 검색 κ΅¬μ‘°λŠ” μ‚¬μš©μž μš”μ²­ μ‹œλ§ˆλ‹€ μ‹€μ‹œκ°„ 크둀링을 μˆ˜ν–‰ν•œλ‹€.

1
2
3
4
5
6
7
8
9
Client
    ↓
Spring Boot
    ↓
FastAPI Crawling Engine
    ↓
External Place Sources
    ↓
PostgreSQL(PostGIS)

Week1-Day1μ—μ„œλŠ”:

  • API 응닡 μ‹œκ°„ λ‘œκΉ…

  • 크둀링 μ‹œκ°„ λ‘œκΉ…

  • DB Query μ‹œκ°„ λ‘œκΉ…

λ“± 계츑 ν™˜κ²½μ„ κ΅¬μΆ•ν–ˆλ‹€.

이번 μž‘μ—…μ—μ„œλŠ” μ‹€μ œ λΆ€ν•˜ ν…ŒμŠ€νŠΈλ₯Ό 톡해:

β€œμ–΄λ””κ°€ μ–Όλ§ˆλ‚˜ λŠλ¦°κ°€?”

λ₯Ό 수치 기반으둜 λΆ„μ„ν•˜λŠ” 것을 λͺ©ν‘œλ‘œ ν•œλ‹€.


였늘 μž‘μ—… λͺ©ν‘œ

였늘 ν•΄κ²°ν•˜λ €λŠ” 문제:

  • μ‹€μ œ 응닡 μ‹œκ°„ μΈ‘μ •

  • P95/P99 뢄석

  • 병λͺ© ꡬ간 확인

  • μ‹€μ‹œκ°„ 크둀링 ꡬ쑰의 ν•œκ³„ νŒŒμ•…

  • κ°œμ„  μš°μ„ μˆœμœ„ λ„μΆœ


ν˜„μž¬ 문제 상황

ν˜„μž¬ κ΅¬μ‘°μ—μ„œλŠ” μ‚¬μš©μž μš”μ²­λ§ˆλ‹€:

  • FastAPI 호좜

  • μ™ΈλΆ€ μ‚¬μ΄νŠΈ μ ‘κ·Ό

  • 데이터 가곡

  • DB μ €μž₯

이 λͺ¨λ‘ μˆ˜ν–‰λœλ‹€.

1
2
3
4
5
6
7
8
9
10
11
12
13
μ‚¬μš©μž μš”μ²­
    ↓
Spring API
    ↓
FastAPI 크둀링
    ↓
μ™ΈλΆ€ μ‚¬μ΄νŠΈ μ ‘κ·Ό
    ↓
데이터 가곡
    ↓
DB μ €μž₯
    ↓
응닡 λ°˜ν™˜

즉:

  • μ™ΈλΆ€ λ„€νŠΈμ›Œν¬ μƒνƒœ

  • 크둀링 처리 μ‹œκ°„

  • μ €μž₯ 처리 μ‹œκ°„

이 λͺ¨λ‘ 응닡 μ‹œκ°„μ— 직접 영ν–₯을 μ£ΌλŠ” ꡬ쑰닀.


문제 ν˜„μƒ

1
2
3
4
- 검색 응닡 μ‹œκ°„μ΄ 맀우 λΆˆκ·œμΉ™ν•¨
- νŠΉμ • μ§€μ—­ 검색 μ‹œ 수 초 이상 μ§€μ—° λ°œμƒ
- λ™μ‹œ μš”μ²­ 증가 μ‹œ 응닡 μ‹œκ°„μ΄ κΈ‰κ²©νžˆ 증가
- μΉ΄ν…Œκ³ λ¦¬ λ³€κ²½ μ‹œ 반볡적인 재크둀링 λ°œμƒ

λ°œμƒ 쑰건

  • κ΄‘λ²”μœ„ν•œ μ§€μ—­ 검색

  • 데이터 κ°œμˆ˜κ°€ λ§Žμ€ 경우

  • λ™μ‹œ μš”μ²­ 증가

  • μ™ΈλΆ€ μ‚¬μ΄νŠΈ 응닡 μ§€μ—°

ν…ŒμŠ€νŠΈ λŒ€μƒ μ§€μ—­:

  • 인천

  • 강남

  • ν™λŒ€

  • μ„±μˆ˜


ν˜„μž¬ μ˜μ‹¬λ˜λŠ” 원인

ν˜„μž¬ μ˜μ‹¬λ˜λŠ” 병λͺ©:

  1. μ™ΈλΆ€ 크둀링 I/O

  2. FastAPI 처리 μ‹œκ°„ 증가

  3. μš”μ²­λ§ˆλ‹€ λ°œμƒν•˜λŠ” DB μ €μž₯

  4. λ™κΈ°ν˜• μš”μ²­ 흐름 ꡬ쑰


주의

ν˜„μž¬ 원인은 아직 μ™„μ „νžˆ ν™•μ •λ˜μ§€ μ•Šμ•˜λ‹€.

λ‹€λ§Œ 이번 μž‘μ—…μ—μ„œλŠ”:

1
μ‹€μ œ 계츑 데이터 기반으둜 병λͺ© μœ„μΉ˜λ₯Ό 확인

ν•˜λŠ” 것을 λͺ©ν‘œλ‘œ ν•œλ‹€.


μΈ‘μ • 및 뢄석

λΆ€ν•˜ ν…ŒμŠ€νŠΈ ν™˜κ²½

μ‚¬μš© 도ꡬ:

1
k6

ν…ŒμŠ€νŠΈ μ‹œλ‚˜λ¦¬μ˜€

μ§€μ—­μΉ΄ν…Œκ³ λ¦¬
인천카페
κ°•λ‚¨μŒμ‹μ 
ν™λŒ€μˆ μ§‘
μ„±μˆ˜λ†€κ±°λ¦¬

λ™μ‹œ μ‚¬μš©μž 수

  • 1λͺ…

  • 10λͺ…

  • 30λͺ…


μˆ˜μ§‘ν•œ 둜그

API 응닡 둜그

1
2
3
4
5
[SEARCH_API]
keyword=인천
category=cafe
durationMs=8420
status=200

크둀링 둜그

1
2
3
4
5
[CRAWLING]
keyword=인천
category=cafe
durationMs=6210
resultCount=42

DB Query 둜그

1
2
3
[DB_QUERY]
query=searchPlaces
durationMs=180

μ„±λŠ₯ μΈ‘μ • κ²°κ³Ό

ν˜„μž¬ μˆ˜μΉ˜λŠ” μ˜ˆμ‹œμ΄λ©°,
μ‹€μ œ ν…ŒμŠ€νŠΈ 결과둜 ꡐ체 μ˜ˆμ •μ΄λ‹€.

ν•­λͺ©κ²°κ³Ό
평균 응닡 μ‹œκ°„6.8s
P959.4s
P9912.1s
μ‹€νŒ¨μœ¨5%

뢄석 κ²°κ³Ό

ν˜„μž¬ 응닡 μ‹œκ°„ λŒ€λΆ€λΆ„μ€:

1
μ™ΈλΆ€ 크둀링 처리 μ‹œκ°„

에 μ§‘μ€‘λ˜λŠ” κ²ƒμœΌλ‘œ 보인닀.

특히:

  • FastAPI 크둀링 μ‹œκ°„

  • μ™ΈλΆ€ μ‚¬μ΄νŠΈ 응닡 μ‹œκ°„

이 전체 응닡 μ‹œκ°„ λŒ€λΆ€λΆ„μ„ μ°¨μ§€ν–ˆλ‹€.

λ˜ν•œ:

  • μ‚¬μš©μž μš”μ²­ 흐름 λ‚΄λΆ€ DB μ €μž₯

  • μš”μ²­λ§ˆλ‹€ 반볡 μˆ˜ν–‰λ˜λŠ” 크둀링

ꡬ쑰도 응닡 지연을 μ¦κ°€μ‹œν‚€λŠ” μš”μΈμœΌλ‘œ ν™•μΈλ˜μ—ˆλ‹€.


μ‹€μ œ ν™•μΈλœ 원인

ν˜„μž¬κΉŒμ§€ ν™•μΈλœ μ£Όμš” 병λͺ©:

  1. μ‹€μ‹œκ°„ μ™ΈλΆ€ I/O

  2. μ‚¬μš©μž μš”μ²­ 흐름 λ‚΄λΆ€ 크둀링

  3. DB μ €μž₯ 포함 ꡬ쑰

  4. λ™κΈ°ν˜• 처리 방식

특히 λ‹€μŒ ꡬ쑰가 κ°€μž₯ 큰 λ¬Έμ œμ˜€λ‹€.

1
2
3
4
5
6
7
μ‚¬μš©μž μš”μ²­
    ↓
μ‹€μ‹œκ°„ 크둀링
    ↓
DB μ €μž₯
    ↓
응닡 λ°˜ν™˜

즉:

β€œμ‚¬μš©μž 응닡 흐름 μ•ˆμ— 느린 μž‘μ—…μ΄ λͺ¨λ‘ ν¬ν•¨λœ ꡬ쑰”

μ˜€λ‹€.


μ μš©ν•œ ν•΄κ²° 방법

이번 λ‹¨κ³„μ—μ„œλŠ” 아직 ꡬ쑰 변경은 μˆ˜ν–‰ν•˜μ§€ μ•Šμ•˜λ‹€.

λŒ€μ‹  λ‹€μŒ μž‘μ—…μ„ μ™„λ£Œν–ˆλ‹€.

  1. μ‹€μ œ 응닡 μ‹œκ°„ μΈ‘μ •

  2. 병λͺ© ꡬ간 식별

  3. P95/P99 μΈ‘μ •

  4. λΆ€ν•˜ ν…ŒμŠ€νŠΈ μ‹œλ‚˜λ¦¬μ˜€ ꡬ좕

  5. κ°œμ„  μ „ κΈ°μ€€ 데이터 확보


μ½”λ“œ λ³€κ²½ 사항

Before

κΈ°μ‘΄μ—λŠ” 별도 λΆ€ν•˜ ν…ŒμŠ€νŠΈ ν™˜κ²½μ΄ μ‘΄μž¬ν•˜μ§€ μ•Šμ•˜λ‹€.

1
2
3
4
5
6
7
@GetMapping("/search")
public ResponseEntity<?> search(String keyword) {

    return ResponseEntity.ok(
            placeService.search(keyword)
    );
}

After

k6 기반 λΆ€ν•˜ ν…ŒμŠ€νŠΈ ν™˜κ²½ μΆ”κ°€.

1
2
3
4
5
6
7
8
9
10
11
import http from 'k6/http';
import { sleep } from 'k6';

export default function () {

    http.get(
        'https://datt-prd.xyz/api/search?keyword=인천'
    );

    sleep(1);
}

Trade-off

이번 μž‘μ—…μœΌλ‘œ 인해 λ°œμƒν•˜λŠ” Trade-off:

μž₯점단점
μ‹€μ œ 병λͺ© μœ„μΉ˜ 확인 κ°€λŠ₯ν…ŒμŠ€νŠΈ ν™˜κ²½ ꡬ좕 λΉ„μš© 증가
κ°œμ„  μ „ κΈ°μ€€ 데이터 확보 κ°€λŠ₯둜그 및 μΈ‘μ • 데이터 관리 ν•„μš”
P95/P99 기반 뢄석 κ°€λŠ₯λΆ€ν•˜ ν…ŒμŠ€νŠΈ ν™˜κ²½ μœ μ§€ ν•„μš”

운영 κ΄€μ μ—μ„œμ˜ κ³ λ € 사항

운영 ν™˜κ²½μ—μ„œλŠ” λ‹¨μˆœ 평균 응닡 μ‹œκ°„λ³΄λ‹€:

  • P95

  • P99

  • Error Rate

κ°€ 더 μ€‘μš”ν•˜λ‹€.

특히 μ™ΈλΆ€ I/O 기반 κ΅¬μ‘°μ—μ„œλŠ”:

  • Timeout

  • Retry

  • Circuit Breaker

μ „λž΅μ΄ ν•„μˆ˜μ μ΄λ‹€.

λ˜ν•œ:

  • μ™ΈλΆ€ API μž₯μ• 

  • 크둀링 μ‹€νŒ¨

  • λ„€νŠΈμ›Œν¬ μ§€μ—°

이 전체 μ„œλΉ„μŠ€ μž₯μ• λ‘œ μ „νŒŒλ  κ°€λŠ₯성이 μ‘΄μž¬ν•œλ‹€.


회고

이번 μž‘μ—…μ—μ„œ κ°€μž₯ μ€‘μš”ν–ˆλ˜ 점은:

β€œλŠλ¦° 것 같닀”

κ°€ μ•„λ‹ˆλΌ:

β€œμ–΄λ””κ°€ μ–Όλ§ˆλ‚˜ λŠλ¦°κ°€β€

λ₯Ό 수치 기반으둜 ν™•μΈν•œ 것이닀.

특히:

  • μ™ΈλΆ€ I/O

  • λ™κΈ°ν˜• μš”μ²­ 흐름

  • μ‹€μ‹œκ°„ 크둀링 ꡬ쑰

κ°€ ν˜„μž¬ ꡬ쑰의 핡심 병λͺ©μž„을 확인할 수 μžˆμ—ˆλ‹€.


λ‹€μŒ μž‘μ—… μ˜ˆμ •

λ‹€μŒ 단계:

  1. 배치 기반 크둀링 ꡬ쑰 섀계

  2. μ‚¬μš©μž μš”μ²­κ³Ό 크둀링 흐름 뢄리

  3. DB 쑰회 기반 검색 API μ „ν™˜ μ€€λΉ„

  4. Redis 캐싱 μ „λž΅ κ²€ν† 

This post is licensed under CC BY 4.0 by the author.