Skip to content

System-Deep-Dive/Bitly-Jungeun

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 

History

22 Commits
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Design Doc: ๋‹จ๊ณ„๋ณ„ ์„ฑ๋Šฅ ์ตœ์ ํ™” ์‹คํ—˜ - URL ๋‹จ์ถ•๊ธฐ

๋ณธ ๋ฌธ์„œ๋Š” ์‹ค์ œ ์„ฑ๋Šฅ ์ธก์ •์„ ํ†ตํ•ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์ตœ์ ํ™”์™€ ์บ์‹ฑ ์ „๋žต์˜ ํšจ๊ณผ๋ฅผ ๊ฒ€์ฆํ•˜๋Š” ์‹คํ—˜์„ ์œ„ํ•œ ๋””์ž์ธ ๋ฌธ์„œ์ž…๋‹ˆ๋‹ค.

1. Context & Scope

  • ๋ฌธ์ œ ๋ฐฐ๊ฒฝ: URL ๋‹จ์ถ•๊ธฐ์˜ ํ•ต์‹ฌ ๋ณ‘๋ชฉ์€ ๋‹จ์ถ• ์ฝ”๋“œ โ†’ ์›๋ณธ URL ์กฐํšŒ ์„ฑ๋Šฅ์ž…๋‹ˆ๋‹ค.
  • ์‹คํ—˜ ๋ชฉํ‘œ: ๋™์ผํ•œ ์›Œํฌ๋กœ๋“œ์—์„œ ์ธ๋ฑ์Šค์™€ ์บ์‹ฑ์˜ ์„ฑ๋Šฅ ๊ฐœ์„  ํšจ๊ณผ๋ฅผ k6๋กœ ์ธก์ •
  • ํ˜„์žฌ ๊ฐ€์ • ํŠธ๋ž˜ํ”ฝ: 1,000 DAU ร— 10ํšŒ/์ผ โ‰ˆ 10,000/์ผ โ†’ ํ‰๊ท  ~0.12 RPS (์‹คํ—˜์šฉ ์†Œ๊ทœ๋ชจ)
  • ์Šค์ฝ”ํ”„: ๋‹จ์ถ• ์ฝ”๋“œ ์กฐํšŒ ๊ฒฝ๋กœ ์ตœ์ ํ™” (DB ์ธ๋ฑ์Šค + Redis ์บ์‹œ)
  • ๋น„์Šค์ฝ”ํ”„: ๋‹จ์ถ• URL ์ƒ์„ฑ ์•Œ๊ณ ๋ฆฌ์ฆ˜, CDN/์—ฃ์ง€ ์ตœ์ ํ™”

2. Goals / Non-Goals

  • Goals
    • ๊ฐ ์ตœ์ ํ™” ๋‹จ๊ณ„๋ณ„ ์‘๋‹ต ์‹œ๊ฐ„ ์ธก์ • (p95, p99)
    • ์บ์‹œ ํžˆํŠธ์œจ 90%+ ๋‹ฌ์„ฑ (์บ์‹œ ๋‹จ๊ณ„)
    • ๋‹จ๊ณ„๋ณ„ ์„ฑ๋Šฅ ๊ฐœ์„ ์œจ ์ •๋Ÿ‰์  ์ธก์ •
  • Non-Goals
    • ํ”„๋กœ๋•์…˜ ๋ ˆ๋ฒจ ํŠธ๋ž˜ํ”ฝ ์ฒ˜๋ฆฌ (60๋งŒ RPS)
    • CDN/์—ฃ์ง€ ์ปดํ“จํŒ… ๊ตฌํ˜„
    • ๊ณ ๊ฐ€์šฉ์„ฑ/์žฅ์•  ๋ณต๊ตฌ

3. System Context Diagram (์‹คํ—˜์šฉ)

  • ์‚ฌ์šฉ์ž๋Š” http://localhost:8080/api/v1/urls/{shortUrl} ๋กœ ์ ‘์†
  • Phase 1: Spring Boot โ†’ PostgreSQL (์ธ๋ฑ์Šค ์—†์Œ)
  • Phase 2: Spring Boot โ†’ PostgreSQL (์ธ๋ฑ์Šค ์žˆ์Œ)
  • Phase 3: Spring Boot โ†’ Redis โ†’ PostgreSQL (์บ์‹œ + ์ธ๋ฑ์Šค)

4. APIs

4.1 ๊ธฐ๋ณธ API

  • GET /api/v1/urls/{shortUrl}: ์ฝ”๋“œ๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธ ์ˆ˜ํ–‰ (302)
  • POST /api/v1/urls: ์›๋ณธ URL โ†’ ๋‹จ์ถ• ์ฝ”๋“œ ์ƒ์„ฑ

4.2 Phase๋ณ„ ํ…Œ์ŠคํŠธ API๋“ค

  • GET /api/v1/urls/baseline/{shortUrl}: Phase 1 - DB ์ง์ ‘ ์กฐํšŒ (์ธ๋ฑ์Šค ์—†์Œ)
  • GET /api/v1/urls/indexed/{shortUrl}: Phase 2 - ์ธ๋ฑ์Šค ํ™œ์šฉ ์กฐํšŒ
  • GET /api/v1/urls/cached/{shortUrl}: Phase 3 - Redis ์บ์‹œ ์šฐ์„  ์กฐํšŒ

5. Data Storage

5.1 ํ…Œ์ด๋ธ” ๋ถ„๋ฆฌ ๊ตฌ์กฐ (Phase๋ณ„ ์„ฑ๋Šฅ ์ธก์ •์šฉ)

  • url_mapping_baseline: Phase 1์šฉ (์ธ๋ฑ์Šค ์—†์Œ)

    • id (PK, Auto Increment)
    • short_url (varchar, unique) โ€” ์ธ๋ฑ์Šค ์—†์Œ (Full Table Scan)
    • original_url (varchar, 2000์ž)
  • url_mapping_indexed: Phase 2์šฉ (์ธ๋ฑ์Šค ์žˆ์Œ)

    • id (PK, Auto Increment)
    • short_url (varchar, unique) โ€” B-tree ์ธ๋ฑ์Šค ์žˆ์Œ (Index Scan)
    • original_url (varchar, 2000์ž)
    • ์ธ๋ฑ์Šค: idx_short_url_indexed on short_url

5.2 ๋ฐ์ดํ„ฐ ๋™๊ธฐํ™” ์ „๋žต

  • URL ์ƒ์„ฑ ์‹œ: 2๊ฐœ ํ…Œ์ด๋ธ”์— ๋™์‹œ ์ €์žฅ (๋™์ผํ•œ shortUrl, originalUrl)
  • Phase๋ณ„ ์กฐํšŒ: ๊ฐ๊ฐ ๋‹ค๋ฅธ ํ…Œ์ด๋ธ”์—์„œ ์กฐํšŒํ•˜์—ฌ ์„ฑ๋Šฅ ์ฐจ์ด ์ธก์ •
  • ์บ์‹œ ๋ ˆ์ด์–ด: Phase 3์—์„œ Redis ์บ์‹œ ์ถ”๊ฐ€ (ํ…Œ์ด๋ธ”์€ indexed ์‚ฌ์šฉ)

6. Performance Optimization Phases

6.1 Phase 1: Baseline (์ธ๋ฑ์Šค ์—†์Œ)

  • ์•„ํ‚คํ…์ฒ˜: Spring Boot โ†’ PostgreSQL
  • ํŠน์ง•: ๊ฐ€์žฅ ๋‹จ์ˆœํ•œ ๊ตฌํ˜„, DB ์ง์ ‘ ์กฐํšŒ
  • ์˜ˆ์ƒ ์„ฑ๋Šฅ: 50-200ms per request (Full table scan)
  • ๋ชฉ์ : ๊ธฐ์ค€ ์„ฑ๋Šฅ ์ธก์ •

6.2 Phase 2: Database Indexing (์ธ๋ฑ์Šค ์žˆ์Œ)

  • ์•„ํ‚คํ…์ฒ˜: Spring Boot โ†’ PostgreSQL (with index)
  • ์ตœ์ ํ™”: short_url ์ปฌ๋Ÿผ์— B-tree ์ธ๋ฑ์Šค ์ถ”๊ฐ€
  • ํŠน์ง•: O(log n) ์กฐํšŒ ์‹œ๊ฐ„
  • ์˜ˆ์ƒ ์„ฑ๋Šฅ: 10-50ms per request (5-10x ๊ฐœ์„ )
  • ๋ชฉ์ : ์ธ๋ฑ์‹ฑ ํšจ๊ณผ ๊ฒ€์ฆ

6.3 Phase 3: Redis Caching (์บ์‹œ + ์ธ๋ฑ์Šค)

  • ์•„ํ‚คํ…์ฒ˜: Spring Boot โ†’ Redis โ†’ PostgreSQL
  • ์บ์‹œ ์ „๋žต:
    • ํ‚ค ํฌ๋งท: url:{shortCode}
    • TTL: 15๋ถ„ (๋‹จ์ผ ์ •์ฑ…์œผ๋กœ ๋‹จ์ˆœํ™”)
    • ์—๋น„์…˜: LRU (Redis ๊ธฐ๋ณธ)
  • ํŠน์ง•: O(1) ์บ์‹œ ์กฐํšŒ, DB ํด๋ฐฑ
  • ์˜ˆ์ƒ ์„ฑ๋Šฅ: 1-5ms per request (100x ๊ฐœ์„ )
  • ์บ์‹œ ํžˆํŠธ์œจ ๋ชฉํ‘œ: 90%+

6.4 ์บ์‹œ ์ •์ฑ… ๋ฐ ์ผ๊ด€์„ฑ

  • ์—๋น„์…˜ ์ •์ฑ…: Redis LRU (์ตœ๊ทผ ์‚ฌ์šฉ ์šฐ์„ )
  • TTL ์ „๋žต: 15๋ถ„ ๊ณ ์ • (๋‹จ์ˆœํ™”๋œ ์ •์ฑ…)
  • ์ผ๊ด€์„ฑ: Read-only ์›Œํฌ๋กœ๋“œ๋กœ ์บ์‹œ ๋ฌดํšจํ™” ์ตœ์†Œํ™”
  • ๋ชจ๋‹ˆํ„ฐ๋ง: ํžˆํŠธ์œจ, ๋ฏธ์Šค์œจ ์‹ค์‹œ๊ฐ„ ์ถ”์ 

7. Test Strategy & Tools

7.1 k6 Load Testing

  • ํ…Œ์ŠคํŠธ ์‹œ๋‚˜๋ฆฌ์˜ค: ๋™์ผํ•œ 1,000๊ฐœ ๋‹จ์ถ• URL์— ๋Œ€ํ•œ ๋ฐ˜๋ณต ์กฐํšŒ
  • ๋ถ€ํ•˜ ํŒจํ„ด: 10 VU ร— 30์ดˆ (์ด 300ํšŒ ์š”์ฒญ)
  • ์ธก์ • ์ง€ํ‘œ:
    • Response time (avg, p95, p99)
    • Requests per second
    • Error rate
    • Throughput

7.2 Performance Comparison Matrix

Phase Architecture Expected p95 Expected RPS Cache Hit Rate
1 DB Only 100-200ms ~10-20 N/A
2 DB + Index 20-50ms ~50-100 N/A
3 Redis + DB 5-20ms ~200-500 90%+

8. Metrics & Success Criteria

8.1 Performance Targets

  • Phase 1: Baseline ์ธก์ • (ํ˜„์žฌ ์„ฑ๋Šฅ)
  • Phase 2: Phase 1 ๋Œ€๋น„ 5x ์ด์ƒ ์„ฑ๋Šฅ ๊ฐœ์„ 
  • Phase 3: Phase 1 ๋Œ€๋น„ 20x ์ด์ƒ ์„ฑ๋Šฅ ๊ฐœ์„ , ์บ์‹œ ํžˆํŠธ์œจ 90%+

8.2 Monitoring Metrics

  • ์‘๋‹ต ์‹œ๊ฐ„: p95, p99, ํ‰๊ท 
  • ์ฒ˜๋ฆฌ๋Ÿ‰: RPS, ์ด ์š”์ฒญ ์ˆ˜
  • ์บ์‹œ ํšจ์œจ: ํžˆํŠธ์œจ, ๋ฏธ์Šค์œจ
  • ์—๋Ÿฌ์œจ: HTTP 4xx/5xx ๋น„์œจ

Local Dev Setup (Docker Compose)

Prerequisites

  • Docker Desktop (Compose v2)

Services

  • PostgreSQL 16, Redis 7(alpine). Spring Boot ์•ฑ์€ ์ถ”ํ›„ api ์„œ๋น„์Šค๋กœ ์ถ”๊ฐ€ ์˜ˆ์ •.

Memory Limits in Compose

  • deploy.resources.limits.memory๋Š” Swarm ์šฉ ํ•„๋“œ์ž…๋‹ˆ๋‹ค. ๋กœ์ปฌ Compose์—์„œ ๊ฐ•์ œํ•˜๋ ค๋ฉด docker compose --compatibility up ๋˜๋Š” ์„œ๋น„์Šค๋ณ„ mem_limit(๋ ˆ๊ฑฐ์‹œ) ์‚ฌ์šฉ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.
  • JVM(์Šคํ”„๋ง) ์ปจํ…Œ์ด๋„ˆ๋Š” -XX:+UseContainerSupport -XX:MaxRAMPercentage=<N>๋กœ ์ปจํ…Œ์ด๋„ˆ ๋ฉ”๋ชจ๋ฆฌ ํ•œ๋„๋ฅผ ์ธ์ง€์‹œ์ผœ์•ผ OOM์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

How to Run

์ „์ฒด ๋ชจ๋‹ˆํ„ฐ๋ง ์Šคํƒ ์‹คํ–‰

# ๋ชจ๋“  ์„œ๋น„์Šค ์‹คํ–‰ (Spring Boot + ๋ชจ๋‹ˆํ„ฐ๋ง)
docker compose --compatibility up -d

# ๋˜๋Š” ๋ชจ๋‹ˆํ„ฐ๋ง๋งŒ ์‹คํ–‰
docker compose --compatibility up -d prometheus grafana node-exporter postgres-exporter cadvisor

Grafana Dashboard

1. Spring Boot ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ชจ๋‹ˆํ„ฐ๋ง

  • Dashboard ID: 4701 (JVM Micrometer) - Spring Boot 3.x ํ˜ธํ™˜

2. ์‹œ์Šคํ…œ ๋ชจ๋‹ˆํ„ฐ๋ง

  • Dashboard ID: 11074 (Node Exporter for Prometheus Dashboard)

3. PostgreSQL ๋ชจ๋‹ˆํ„ฐ๋ง

  • Dashboard ID: 9628 (PostgreSQL Database)
  • Dashboard ID: 455 (PostgreSQL Overview)

4. Redis ๋ชจ๋‹ˆํ„ฐ๋ง

  • Dashboard ID: 763 (Redis Dashboard)
  • Dashboard ID: 11835 (Redis Exporter)

k6 ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ๋Œ€์‹œ๋ณด๋“œ

  • Dashboard ID: 2587 (k6 Performance Testing)
  • ์šฉ๋„: k6 ์„ฑ๋Šฅ ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ ์‹œ๊ฐํ™”
  • ๋ฐ์ดํ„ฐ์†Œ์Šค: InfluxDB (k6 ๋ฉ”ํŠธ๋ฆญ)

๋Œ€์‹œ๋ณด๋“œ Import ๋ฐฉ๋ฒ•

  1. Grafana ์ ‘์†: http://localhost:3000
  2. ์ขŒ์ธก ๋ฉ”๋‰ด โ†’ Dashboards โ†’ + New โ†’ Import
  3. Import via grafana.com ํƒญ ์„ ํƒ
  4. Dashboard ID ์ž…๋ ฅ (์˜ˆ: 4701, 2587)
  5. Load โ†’ Prometheus ๋˜๋Š” InfluxDB ๋ฐ์ดํ„ฐ์†Œ์Šค ์„ ํƒ โ†’ Import

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors