Software Development ๊ด€๋ จ ๊ณต๋ถ€ํ•œ ๋‚ด์šฉ์„ ์•„๋ž˜์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

Versioning

  • SemVer(Semantic Versioning): {major}.{minor}.{patch}๋กœ ์˜๋ฏธ๋ฅผ ๋ถ€์—ฌํ•œ ๋ฒ„์ €๋‹ ์‹œ์Šคํ…œ. ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š” ์†Œํ”„ํŠธ์›จ์–ด ๋ฒ„์ €๋‹ ๋ฐฉ์‹
    • major: ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” API ๋ณ€๊ฒฝ์ด ์žˆ์„ ๋•Œ ์ฆ๊ฐ€. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ธฐ์กด ํ•จ์ˆ˜์˜ ์‹œ๊ทธ๋‹ˆ์ฒ˜๋ฅผ ๋ฐ”๊พธ๊ฑฐ๋‚˜, ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ฑฐํ•˜๋Š” ๋“ฑ์˜ ๋ณ€๊ฒฝ์ด ํฌํ•จ๋  ์ˆ˜ ์žˆ์Œ. 'breaking change'๋ผ๋Š” ๊ฒฝ๊ณ ์„ฑ ์˜๋ฏธ๋กœ ์„ค์ •
    • minor: ๊ธฐ๋Šฅ์ด ์ถ”๊ฐ€๋˜์—ˆ์œผ๋‚˜, ํ•˜์œ„ ํ˜ธํ™˜์„ฑ์€ ์œ ์ง€๋  ๋•Œ ์ฆ๊ฐ€. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ƒˆ๋กœ์šด ํ•จ์ˆ˜๋‚˜ ์˜ต์…˜์ด ์ถ”๊ฐ€๋  ๊ฒฝ์šฐ, ํ•ด๋‹น ๋ฒ„์ „ ๋ฒˆํ˜ธ๊ฐ€ ์ฆ๊ฐ€
    • patch: ํ•˜์œ„ ํ˜ธํ™˜์„ฑ์„ ์œ ์ง€ํ•˜๋Š” ๋ฒ„๊ทธ ์ˆ˜์ •์ด ์žˆ์„ ๋•Œ ์ฆ๊ฐ€. ๊ธฐ์กด ๊ธฐ๋Šฅ์˜ ๋™์ž‘์„ ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•˜๋Š” ๋ณ€๊ฒฝ์ด ํฌํ•จ
    • ์˜ˆ์‹œ: ์ƒˆ๋กœ์šด ๊ธฐ๋Šฅ ์ถ”๊ฐ€ ์‹œ 1.3.0 / ๋ฒ„๊ทธ ์ˆ˜์ • ์‹œ 1.2.4 / ํ•˜์œ„ ํ˜ธํ™˜์„ฑ์ด ์—†๋Š” ๋ณ€๊ฒฝ ์‹œ 2.0.0
  • HeadVer: {head}.{yearweek}.{build}๋กœ ์˜๋ฏธ๋ฅผ ๋ถ€์—ฌํ•œ ๋ฒ„์ €๋‹ ์‹œ์Šคํ…œ. SemVer๋Š” API๋ฅผ ์œ„ํ•œ ๋ฒ„์ €๋‹ ์‹œ์Šคํ…œ์ด๋ผ๋Š” ์ ์„ ์ง€์ ํ•˜๋ฉฐ, ์ตœ์ข… ์‚ฌ์šฉ์ž(end-user)๋ฅผ ๋” ์—ผ๋‘์— ๋‘๊ณ  ๋ฒ„์ €๋‹ํ•œ ๋ฐฉ์‹. ํ•œ ํšŒ์‚ฌ์˜ ๋ชจ๋“  ์•ฑ์„ ๋ชจ๋‘๊ฐ€ ๊ฐ™์€ ๊ทœ์น™์œผ๋กœ ํ•ด์„. ์ด๋ฆ„์€ '์ด ๋ฒ„์ €๋‹์—์„œ ์‹ ๊ฒฝ ์“ธ ๊ฒƒ์€ Head ๋ฐ–์— ์—†๋‹ค. ๋‚˜๋จธ์ง€๋Š” ์ž๋™์ด๋‹ค'๋ผ๋Š” ์˜๋ฏธ
    • head: SemVer์™€ ๋‹ฌ๋ฆฌ ์ฒซ์งธ ์ž๋ฆฌ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ๊ฒƒ์„ ๊ถŒํ•จ. ์‚ฌ์šฉ์ž์—๊ฒŒ ๋„๋‹ฌํ•˜๋Š” ํšŸ์ˆ˜๋งˆ๋‹ค ์ฆ๊ฐ€ํ•˜๋ฉด ์ข‹๋‹ค๊ณ  ํ•จ
    • yearweek: ์ฃผ ์ฐจ(week number) ์ •๋ณด. ์ž๋™์œผ๋กœ ์ฆ๊ฐ€ํ•˜๋„๋ก ์„ค์ •
    • build: ๋นŒ๋“œ ๋ฒˆํ˜ธ. ์ž๋™์œผ๋กœ ์ฆ๊ฐ€ํ•˜๋„๋ก ์„ค์ •
  • GitHub release: ํ”„๋กœ์ ํŠธ์˜ ํŠน์ • ๋ฒ„์ „(e.g., v1.0, v2.1)์„ ์‰ฝ๊ฒŒ ๋ฐฐํฌํ•˜๊ณ  ๊ด€๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์„ ์ œ๊ณต. ์†Œํ”„ํŠธ์›จ์–ด์˜ ํŠน์ • ์ƒํƒœ(์ผ๋ฐ˜์ ์œผ๋กœ ์ฃผ์š” ๋ฒ„์ „์ด๋‚˜ ์ค‘์š”ํ•œ ์—…๋ฐ์ดํŠธ)๋ฅผ 'release'๋กœ ์ •์˜ํ•˜๊ณ , ํ•ด๋‹น ์‹œ์ ์˜ ์†Œ์Šค ์ฝ”๋“œ์™€ ํ•จ๊ป˜ ๋ฆด๋ฆฌ์Šค ๋…ธํŠธ, ๋ฐ”์ด๋„ˆ๋ฆฌ ํŒŒ์ผ ๋“ฑ์„ ํ•จ๊ป˜ ์ œ๊ณต
Versioning for ML
  • Labeling rule versioning: GitBook๊ณผ ๊ฐ™์€ git ๊ธฐ๋ฐ˜ documentation ํˆด์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ผ๋ฒจ๋ง ๊ฐ€์ด๋“œ๋ผ์ธ ๋ฌธ์„œ๋ฅผ ์ž‘์„ฑํ•œ ๋’ค์—, ํ•ด๋‹น ๋ผ๋ฒจ๋ง ๊ฐ€์ด๋“œ๋ผ์ธ ์ €์žฅ์†Œ๋ฅผ ๋ฒ„์ €๋‹. ๋ฒ„์ €๋‹ ์‹œ์Šคํ…œ์€ SemVer ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ ์ข‹์•„๋ณด์ž„

  • Data versioning: Data Version Control (DVC), Delta Lake์˜ Time Travel๋“ฑ์˜ ๊ธฐ๋Šฅ ํ™œ์šฉํ•ด๋ณผ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™์Œ

  • Model versioning: MLflow Model Registry ํ™œ์šฉํ•ด์„œ ๋ฐฐํฌ ๋ชจ๋ธ ๋ฒ„์ €๋‹ ํ•˜๋Š” ๊ฒƒ ์ข‹์•„๋ณด์ž„

Exception

Exception(์˜ˆ์™ธ)์€ ์˜ˆ๊ธฐ์น˜ ์•Š์€ ์˜ค๋ฅ˜๋‚˜ ๋น„์ •์ƒ์ ์ธ ์ƒํ™ฉ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋ฉฐ, ํ”„๋กœ๊ทธ๋žจ์ด ๊ฐ‘์ž‘์Šค๋Ÿฝ๊ฒŒ ์ค‘๋‹จ๋˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜๊ณ , ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•œ ์ƒํ™ฉ์„ ์ ์ ˆํ•˜๊ฒŒ ์ฒ˜๋ฆฌํ•˜์—ฌ ํ”„๋กœ๊ทธ๋žจ์ด ์•ˆ์ „ํ•˜๊ฒŒ ์ข…๋ฃŒ๋˜๊ฑฐ๋‚˜ ๊ณ„์† ์‹คํ–‰๋  ์ˆ˜ ์žˆ๋„๋ก ๋•์Šต๋‹ˆ๋‹ค.

์˜ˆ์™ธ๋Š” ์˜ค๋ฅ˜ ์ƒํ™ฉ์„ ์ฒ˜๋ฆฌํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด์ง€ ์ผ๋ฐ˜์ ์ธ ํ”„๋กœ๊ทธ๋žจ์˜ ํ๋ฆ„ ์ œ์–ด๋ฅผ ์œ„ํ•œ ๊ฒƒ์ด ์•„๋‹ˆ๊ธฐ์— ํ๋ฆ„ ์ œ์–ด์— ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์œผ๋ฉฐ, ์กฐ๊ฑด๋ฌธ์œผ๋กœ ์ถฉ๋ถ„ํžˆ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ๋Š” ์ƒํ™ฉ์—์„œ๋Š” ์˜ˆ์™ธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

Python Exceptions

Python exception ์ข…๋ฅ˜์— ๋Œ€ํ•ด ์•„๋ž˜์— ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค.

  • Exception: ํŠน์ • ์˜ˆ์™ธ๋ฅผ ์ง€์ •ํ•˜์ง€ ์•Š๊ณ  ๋ชจ๋“  ์˜ˆ์™ธ๋ฅผ ์žก์•„์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ

  • ArithmeticError: ๋ชจ๋“  ์‚ฐ์ˆ  ๊ณ„์‚ฐ ์˜ค๋ฅ˜์˜ ๊ธฐ๋ณธ ํด๋ž˜์Šค. ZeroDivisionError, OverflowError, FloatingPointError ๋“ฑ์˜ ์ƒ์œ„ ํด๋ž˜์Šค. ์ง์ ‘์ ์œผ๋กœ ์‚ฌ์šฉ๋˜์ง€ ์•Š๊ณ , ํ•˜์œ„ ํด๋ž˜์Šค๊ฐ€ ์ฃผ๋กœ ์‚ฌ์šฉ๋จ

  • ZeroDivisionError: ์ˆซ์ž๋ฅผ 0์œผ๋กœ ๋‚˜๋ˆ„๋ ค๊ณ  ํ•  ๋•Œ ๋ฐœ์ƒ

  • ValueError: ํ•จ์ˆ˜๋‚˜ ์—ฐ์‚ฐ์ž๊ฐ€ ์ž˜๋ชป๋œ ๊ฐ’์„ ๋ฐ›์•˜์„ ๋•Œ ๋ฐœ์ƒ. ์˜ˆ๋ฅผ ๋“ค์–ด, int() ํ•จ์ˆ˜์— ์ˆซ์ž๊ฐ€ ์•„๋‹Œ ๋ฌธ์ž์—ด์„ ์ „๋‹ฌํ•˜๋ฉด ๋ฐœ์ƒ

  • TypeError: ์—ฐ์‚ฐ ๋˜๋Š” ํ•จ์ˆ˜๊ฐ€ ์ž˜๋ชป๋œ ํƒ€์ž…์˜ ๊ฐ์ฒด๋ฅผ ๋ฐ›์•˜์„ ๋•Œ ๋ฐœ์ƒ

  • IndexError: ๋ฆฌ์ŠคํŠธ๋‚˜ ํŠœํ”Œ ๋“ฑ์˜ ์‹œํ€€์Šค์—์„œ ์ž˜๋ชป๋œ ์ธ๋ฑ์Šค๋ฅผ ์ฐธ์กฐํ•  ๋•Œ ๋ฐœ์ƒ

  • KeyError: ๋”•์…”๋„ˆ๋ฆฌ์—์„œ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ํ‚ค๋ฅผ ์ฐธ์กฐํ•  ๋•Œ ๋ฐœ์ƒ

  • AttributeError: ๊ฐ์ฒด์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์†์„ฑ์— ์ ‘๊ทผํ•˜๋ ค๊ณ  ํ•  ๋•Œ ๋ฐœ์ƒ

  • ImportError: ๋ชจ๋“ˆ์„ ๊ฐ€์ ธ์˜ค๋ ค๊ณ  ํ•  ๋•Œ, ๋ชจ๋“ˆ์ด ์—†๊ฑฐ๋‚˜ ๋ชจ๋“ˆ ๋‚ด์— ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋ ค๊ณ  ํ•  ๋•Œ ๋ฐœ์ƒ

  • FileNotFoundError: ํŒŒ์ผ์„ ์—ด๋ ค๊ณ  ํ•  ๋•Œ ํ•ด๋‹น ํŒŒ์ผ์ด ์กด์žฌํ•˜์ง€ ์•Š์œผ๋ฉด ๋ฐœ์ƒ

  • OSError: ์‹œ์Šคํ…œ ๊ด€๋ จ ์—๋Ÿฌ๋กœ, ํŒŒ์ผ ์‹œ์Šคํ…œ์ด๋‚˜ ์šด์˜ ์ฒด์ œ์™€ ์ƒํ˜ธ์ž‘์šฉํ•  ๋•Œ ๋ฐœ์ƒ

  • RuntimeError: ๋‹ค๋ฅธ ๋ฒ”์ฃผ์— ์†ํ•˜์ง€ ์•Š๋Š” ์ผ๋ฐ˜์ ์ธ ์‹คํ–‰ ์‹œ ์˜ค๋ฅ˜๋ฅผ ๋‚˜ํƒ€๋ƒ„. ๊ตฌ์ฒด์ ์ธ ์˜ˆ์™ธ๋กœ ์„ค๋ช…๋˜์ง€ ์•Š๋Š” ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ ์‚ฌ์šฉ

  • StopIteration: next() ํ•จ์ˆ˜๊ฐ€ ๋” ์ด์ƒ ์•„์ดํ…œ์„ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์—†์„ ๋•Œ ๋ฐœ์ƒ. ์ฃผ๋กœ ๋ฐ˜๋ณต์ž์˜ ์ข…๋ฃŒ๋ฅผ ์•Œ๋ฆฌ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ

  • KeyboardInterrupt: ์‚ฌ์šฉ์ž๊ฐ€ ํ”„๋กœ๊ทธ๋žจ์„ ๊ฐ•์ œ ์ข…๋ฃŒํ•˜๋ ค๊ณ  Ctrl+C๋ฅผ ์ž…๋ ฅํ–ˆ์„ ๋•Œ ๋ฐœ์ƒ

  • MemoryError: ์‹œ์Šคํ…œ์—์„œ ๋” ์ด์ƒ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•  ์ˆ˜ ์—†์„ ๋•Œ ๋ฐœ์ƒ

Logging

Python Log Libraries
  • loguru: ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šด API์™€ ๊ธฐ๋ณธ ์ œ๊ณต๋˜๋Š” ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ๋“ค๋กœ ๋น ๋ฅด๊ฒŒ ๋กœ๊น… ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Œ. ํ‘œ์ค€์ด ์•„๋‹ˆ๊ธฐ ๋•Œ๋ฌธ์— ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด์•ผ ํ•จ
  • logging: Python์˜ ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, ๋ณต์žกํ•œ ์š”๊ตฌ ์‚ฌํ•ญ์— ๋งž๋Š” ์œ ์—ฐํ•œ ์„ค์ •์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์ดˆ๊ธฐ ์„ค์ •์ด ๋ณต์žกํ•  ์ˆ˜ ์žˆ์Œ
  • logbook: logging์˜ ๋ณต์žก์„ฑ์„ ์ค„์ด๋ฉด์„œ๋„ ๊ฐ•๋ ฅํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๋Œ€์•ˆ์œผ๋กœ, ๋น„๋™๊ธฐ ๋กœ๊น…์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์œ ์šฉ (๋น„๋™๊ธฐ ๋กœ๊น…์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜์—ฌ, ๊ณ ์„ฑ๋Šฅ ๋กœ๊น…์ด ๊ฐ€๋Šฅ)
Log Level

loguru ๊ธฐ์ค€์œผ๋กœ ์‚ดํŽด๋ณธ log level์€ ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • TRACE(5): ํ”„๋กœ๊ทธ๋žจ์˜ ๋…ผ๋ฆฌ ํ๋ฆ„์— ๋Œ€ํ•œ ์ €์ˆ˜์ค€ ์ •๋ณด
  • DEBUG(10): ๋””๋ฒ„๊น… ์ค‘์— ๋„์›€์ด ๋˜๋Š” ์ •๋ณด
  • INFO(20): ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์˜ˆ์ƒ๋Œ€๋กœ ์ž‘๋™ํ•˜๊ณ  ์žˆ์Œ์„ ํ™•์ธ
  • SUCCESS(25): ์ž‘์—…์ด ์„ฑ๊ณตํ–ˆ์Œ์„ ํ‘œ์‹œ
  • WARNING(30): ์ถ”ํ›„์— ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋ฌธ์ œ๋ฅผ ์ผ์œผํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์ด์Šˆ๋ฅผ ํ‘œ์‹œ
  • ERROR(40): ์ฆ‰๊ฐ์ ์ธ ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•˜์ง€๋งŒ ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒ์‹œํ‚ค์ง€ ์•Š๋Š” ์ด์Šˆ
  • CRITICAL(50): OOM๊ณผ ๊ฐ™์ด, ํ”„๋กœ๊ทธ๋žจ์„ ์ข…๋ฃŒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋Š” ์‹ฌ๊ฐํ•œ ์ด์Šˆ

ํŠน์ • log level ์ด์ƒ๋งŒ ํ‘œ์ถœํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ์–ด์„œ, ๋””๋ฒ„๊น…ํ™˜๊ฒฝ, Devํ™˜๊ฒฝ, Prod ํ™˜๊ฒฝ ๋“ฑ, ํ™˜๊ฒฝ ๋ณ„๋กœ ๋‹ค๋ฅธ log level์„ ์ ์šฉํ•˜์—ฌ log๋ฅผ ํ™•์ธํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์ถ”๊ฐ€์ ์œผ๋กœ ์ฐธ๊ณ ํ•˜๋ฉด ์ข‹์„ ๊ธ€๋“ค์˜ ๋งํฌ๋ฅผ ์ฒจ๋ถ€ํ•ฉ๋‹ˆ๋‹ค

Sentry

Sentry๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์˜ค๋ฅ˜ ์ถ”์  ๋ฐ ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง์„ ์ œ๊ณตํ•˜๋Š” ์˜คํ”ˆ ์†Œ์Šค ํ”Œ๋žซํผ์ž…๋‹ˆ๋‹ค. Sentry๋ฅผ ํ†ตํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๋ฐœ์ƒํ•˜๋Š” ์˜ค๋ฅ˜์™€ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๊ฐ์ง€ํ•˜๊ณ  ๋ถ„์„ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์—๋Ÿฌ ์ถ”์  (Error Tracking): ์ฝ”๋“œ์—์„œ ๋ฐœ์ƒํ•œ ์˜ˆ์™ธ(Exception)๋ฅผ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ˆ˜์ง‘ํ•˜์—ฌ ๋Œ€์‹œ๋ณด๋“œ์— ํ‘œ์‹œ. ์—๋Ÿฌ์˜ stack trace, ํ™˜๊ฒฝ ์ •๋ณด, ์‚ฌ์šฉ์ž ์ •๋ณด ๋“ฑ์„ ์ž๋™ ์ˆ˜์ง‘
  • ๋ฆด๋ฆฌ์ฆˆ ํ—ฌ์Šค ๋ชจ๋‹ˆํ„ฐ๋ง (Release Health): ํŠน์ • ๋ฆด๋ฆฌ์ฆˆ ๋ฒ„์ „์—์„œ ๋ฐœ์ƒํ•œ ์ด์Šˆ๋‚˜ ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์ถ”์ . ๊ฐ ๋ฆด๋ฆฌ์ฆˆ์— ๋Œ€ํ•œ crash-free rate, adoption rate ๋“ฑ ํ™•์ธ ๊ฐ€๋Šฅ
  • ์„ฑ๋Šฅ ๋ชจ๋‹ˆํ„ฐ๋ง (Performance Monitoring): ํŠธ๋žœ์žญ์…˜ ๋ณ„ ์‘๋‹ต ์‹œ๊ฐ„, ์ฟผ๋ฆฌ ์ง€์—ฐ, API ์š”์ฒญ ๋ณ‘๋ชฉ ๋“ฑ ์ถ”์ . APM(Application Performance Monitoring) ์ˆ˜์ค€์˜ ๊ธฐ๋Šฅ ์ œ๊ณต
  • ์•Œ๋ฆผ ์‹œ์Šคํ…œ: ์Šฌ๋ž™, ์ด๋ฉ”์ผ, MS Teams, Discord ๋“ฑ๊ณผ ์—ฐ๋™ํ•ด ์•Œ๋ฆผ ์ „์†ก ๊ฐ€๋Šฅ. ํŠน์ • ์กฐ๊ฑด(์˜ˆ: ๋™์ผ ์—๋Ÿฌ ๋ฐ˜๋ณต, ํŠน์ • ์‚ฌ์šฉ์ž ๋ฐœ์ƒ)์— ๋”ฐ๋ฅธ ์•Œ๋ฆผ ์„ค์ •
  • ์ด์Šˆ ๊ทธ๋ฃนํ•‘ ๋ฐ ์ž๋™ํ™”: ๊ฐ™์€ ์ข…๋ฅ˜์˜ ์—๋Ÿฌ๋ฅผ ํ•˜๋‚˜์˜ ์ด์Šˆ๋กœ ๋ฌถ์–ด์„œ ๊ด€๋ฆฌ. ํŠน์ • ์ด์Šˆ์— ํƒœ๊ทธ ์ง€์ •, ์šฐ์„ ์ˆœ์œ„ ์„ค์ •, ๋‹ด๋‹น์ž ํ• ๋‹น ๊ฐ€๋Šฅ

์˜ˆ๋ฅผ ๋“ค์–ด ์›น์‚ฌ์ดํŠธ์—์„œ ์‚ฌ์šฉ์ž๊ฐ€ ๋ฒ„ํŠผ์„ ํด๋ฆญํ–ˆ์„ ๋•Œ JS ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด:

  1. ์—๋Ÿฌ๊ฐ€ Sentry SDK๋ฅผ ํ†ตํ•ด ์ž๋™์œผ๋กœ ์ „์†ก๋จ
  2. ๋Œ€์‹œ๋ณด๋“œ์—์„œ ํ•ด๋‹น ์˜ค๋ฅ˜์˜ ๊ฒฝ๋กœ, ํ™˜๊ฒฝ, ์‚ฌ์šฉ์ž ID ๋“ฑ ํ™•์ธ
  3. ์Šฌ๋ž™์œผ๋กœ ์—๋Ÿฌ ๋ฐœ์ƒ ์•Œ๋ฆผ ์ˆ˜์‹ 
  4. ํŠน์ • ์ปค๋ฐ‹๊ณผ ์—ฐ๊ฒฐํ•ด ์–ด๋–ค ์ฝ”๋“œ ๋ณ€๊ฒฝ์ด ๋ฌธ์ œ๋ฅผ ์ผ์œผ์ผฐ๋Š”์ง€๋„ ์ถ”์  ๊ฐ€๋Šฅ

Data Libraries

Encoding

UTF-8(8-bit Unicode Transformation Format)๋Š” ๋ฌธ์ž ์ธ์ฝ”๋”ฉ์˜ ์ผ์ข…์œผ๋กœ, ์ „ ์„ธ๊ณ„์˜ ๊ฑฐ์˜ ๋ชจ๋“  ๋ฌธ์ž๋ฅผ ํ‘œํ˜„ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฐ€๋ณ€ ๊ธธ์ด ๋ฌธ์ž ์ธ์ฝ”๋”ฉ ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. Python์—์„œ๋Š” ํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ์ธ์ฝ”๋”ฉํ•˜๊ฑฐ๋‚˜ ๋””์ฝ”๋”ฉํ•  ๋•Œ str๊ณผ bytes ํƒ€์ž… ๊ฐ„์— ๋ณ€ํ™˜ํ•  ๋•Œ ์ž์ฃผ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ํŠน์ง•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๊ฐ€๋ณ€ ๊ธธ์ด ์ธ์ฝ”๋”ฉ: ASCII ๋ฌธ์ž๋Š” 1๋ฐ”์ดํŠธ, ๊ทธ ์™ธ์˜ ๋ฌธ์ž๋Š” 2๋ฐ”์ดํŠธ์—์„œ 4๋ฐ”์ดํŠธ๊นŒ์ง€ ์‚ฌ์šฉ๋จ
  • ์œ ๋‹ˆ์ฝ”๋“œ ํ˜ธํ™˜: UTF-8์€ ์œ ๋‹ˆ์ฝ”๋“œ์˜ ๋ชจ๋“  ๋ฌธ์ž๋ฅผ ์ง€์›
  • ํ•˜์œ„ ํ˜ธํ™˜์„ฑ: ASCII์™€ ์™„๋ฒฝํ•˜๊ฒŒ ํ˜ธํ™˜๋˜๋ฉฐ, ASCII ๋ฌธ์ž์—ด์€ UTF-8์—์„œ๋„ ๋™์ผํ•˜๊ฒŒ ํ‘œํ˜„๋จ
Compression

blosc2๋Š” ๊ณ ์„ฑ๋Šฅ์˜ ๋ฐ”์ด๋„ˆ๋ฆฌ ๋ฐ์ดํ„ฐ ์••์ถ• ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ, ํŠนํžˆ ๋Œ€๊ทœ๋ชจ ๋ฐฐ์—ด ๋ฐ์ดํ„ฐ๋ฅผ ์••์ถ•ํ•˜๊ณ  ์••์ถ• ํ•ด์ œํ•˜๋Š” ๋ฐ ์ตœ์ ํ™”๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ๋ฐ์ดํ„ฐ ์••์ถ•์„ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ์„ ์ตœ์†Œํ™”ํ•˜๋Š” ๋ฐ ์ค‘์ ์„ ๋‘ . ๋ฐ์ดํ„ฐ ๋ถ„์„, ๋จธ์‹  ๋Ÿฌ๋‹ ๋“ฑ์˜ ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒฝ์šฐ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ํŠน์ง•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ์ŠคํŠธ๋ฆฌ๋ฐ ์••์ถ•: ์—ฐ์†์ ์ธ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆผ์— ๋Œ€ํ•ด ํšจ์œจ์ ์œผ๋กœ ์••์ถ•ํ•  ์ˆ˜ ์žˆ์Œ
  • ๋‹ค์–‘ํ•œ ์••์ถ• ์ฝ”๋ฑ ์ง€์›: LZ4, Zlib, Zstandard ๋“ฑ์˜ ๋‹ค์–‘ํ•œ ์ฝ”๋ฑ์„ ์ง€์›
  • ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ์ง€์›: ๋ฉ€ํ‹ฐ์ฝ”์–ด CPU๋ฅผ ํ™œ์šฉํ•˜์—ฌ ๋ณ‘๋ ฌ๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ์••์ถ•ํ•˜๊ณ  ํ•ด์ œํ•  ์ˆ˜ ์žˆ์Œ
Serialization

orjson๋Š” python์—์„œ ๋งค์šฐ ๋น ๋ฅธ JSON ์ง๋ ฌํ™” ๋ฐ ์—ญ์ง๋ ฌํ™”๋ฅผ ์ œ๊ณตํ•˜๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค.. ๊ธฐ๋ณธ json ๋ชจ๋“ˆ์— ๋น„ํ•ด ํ›จ์”ฌ ๋น ๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋ฉฐ, ํŠนํžˆ ํฐ ๋ฐ์ดํ„ฐ์…‹์„ ์ฒ˜๋ฆฌํ•  ๋•Œ ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ํŠน์ง•์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • ๊ณ ์„ฑ๋Šฅ: JSON ๋ฐ์ดํ„ฐ๋ฅผ ๋งค์šฐ ๋น ๋ฅด๊ฒŒ ์ง๋ ฌํ™”(encode) ๋ฐ ์—ญ์ง๋ ฌํ™”(decode)ํ•  ์ˆ˜ ์žˆ์Œ
  • ์œ ๋‹ˆ์ฝ”๋“œ ์ง€์›: UTF-8 ์ธ์ฝ”๋”ฉ์„ ๊ธฐ๋ณธ์œผ๋กœ ํ•˜์—ฌ ํ…์ŠคํŠธ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌ
  • ์ •ํ™•์„ฑ: ์ •ํ™•ํ•œ ๋‚ ์งœ ๋ฐ ์‹œ๊ฐ„ ์ง๋ ฌํ™”, IEEE 754 ๊ทœ๊ฒฉ์— ๋งž์ถ˜ ๋ถ€๋™์†Œ์ˆ˜์  ํ‘œํ˜„ ๋“ฑ์„ ์ง€์›

Test Code

์œ ๋‹›ํ…Œ์ŠคํŠธ์—์„œ ์‹ค์ œ ๊ฐ์ฒด๋ฅผ ๋Œ€์ฒดํ•˜์—ฌ ์‚ฌ์šฉ๋˜๋Š” ํ…Œ์ŠคํŠธ ๋”๋ธ”(์‹ค์ œ ๊ฐ์ฒด๋ฅผ ๋Œ€์‹ ํ•ด์„œ ํ…Œ์ŠคํŒ…์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋ชจ๋“  ๋ฐฉ๋ฒ•)์˜ ํƒ€์ž…์—๋Š” mock๊ณผ stub ๋“ฑ์ด ์žˆ์œผ๋ฉฐ, ์ด ๋‘˜์€ ๋ชฉ์ ๊ณผ ํŠน์„ฑ ์ธก๋ฉด์—์„œ ์กฐ๊ธˆ ์ฐจ์ด๋ฅผ ๊ฐ€์ง‘๋‹ˆ๋‹ค.

  • Dummy Object: ์•„๋ฌด ๋™์ž‘๋„ ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋‹จ์ง€ ์ธ์Šคํ„ด์Šค๊ฐ€ ํ•„์š”ํ•  ๋•Œ ์ž๋ฆฌ๋ฅผ ์ฑ„์šฐ๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ์‹œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๊ฐ์ฒด๊ฐ€ ์š”๊ตฌ๋˜์ง€๋งŒ ์‹ค์ œ๋กœ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ์— ๋”๋ฏธ ๊ฐ์ฒด๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ

  • Stub: ๋ฏธ๋ฆฌ ์ •์˜๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๋Š” ๊ฐ์ฒด. ํŠน์ • ๋ฉ”์„œ๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๋•Œ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋„๋ก ์„ค์ •ํ•  ์ˆ˜ ์žˆ์Œ

  • Spy: ์Šคํ…๊ณผ ๋น„์Šทํ•˜์ง€๋งŒ, ์ŠคํŒŒ์ด๋Š” ํ˜ธ์ถœ๋œ ๋ฉ”์„œ๋“œ๋‚˜ ์ „๋‹ฌ๋œ ์ธ์ˆ˜์™€ ๊ฐ™์€ ์ถ”๊ฐ€์ ์ธ ์ •๋ณด๋ฅผ ๊ธฐ๋กํ•˜๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ. ์ด๋ฅผ ํ†ตํ•ด ํ…Œ์ŠคํŠธ ํ›„์— ํŠน์ • ๋ฉ”์„œ๋“œ๊ฐ€ ์–ผ๋งˆ๋‚˜ ์ž์ฃผ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ๋˜๋Š” ์–ด๋–ค ์ธ์ˆ˜๊ฐ€ ์ „๋‹ฌ๋˜์—ˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Mock: ๋ชจํฌ๋Š” ํ–‰๋™ ๊ธฐ๋ฐ˜ ํ…Œ์ŠคํŠธ์— ์‚ฌ์šฉ๋จ. ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ์™€ ๊ทธ ํ˜ธ์ถœ ํšŸ์ˆ˜, ํ˜ธ์ถœ ์ˆœ์„œ ๋“ฑ์„ ๋ฏธ๋ฆฌ ์„ค์ •ํ•˜๊ณ , ํ…Œ์ŠคํŠธ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์ด ๋ชจ๋“  ์กฐ๊ฑด์ด ์ถฉ์กฑ๋˜์—ˆ๋Š”์ง€ ๊ฒ€์ฆ

  • Fake: ์‹ค์ œ ๊ตฌํ˜„์ด ์•„๋‹Œ ํ…Œ์ŠคํŠธ ๋ชฉ์ ์œผ๋กœ ๊ฐ„๋‹จํ•˜๊ฒŒ ๊ตฌํ˜„๋œ ๊ฐ์ฒด. ์˜ˆ๋ฅผ ๋“ค์–ด, ์‹ค์ œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๋Œ€์‹  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ€์งœ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์ด๋กœ์จ ํ…Œ์ŠคํŠธ ํ™˜๊ฒฝ์—์„œ ๋”์šฑ ๊ฐ€๋ณ๊ณ  ๋น ๋ฅด๊ฒŒ ํ…Œ์ŠคํŠธํ•  ์ˆ˜ ์žˆ์Œ

Stub and Mock

Stub์€ ํ…Œ์ŠคํŠธ ์ค‘์— ํŠน์ • ํ˜ธ์ถœ์— ๋Œ€ํ•ด ๋ฏธ๋ฆฌ ์ •์˜๋œ ์‘๋‹ต์„ ์ œ๊ณตํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. (์ƒํƒœ ๊ฒ€์ฆ)

  • ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๊ฐ€ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š” ์‹ค์ œ ๊ตฌ์„ฑ ์š”์†Œ์˜ ๋™์ž‘์„ ์‹œ๋ฎฌ๋ ˆ์ดํŠธํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋จ
  • ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ณ ์ •๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•˜๊ฑฐ๋‚˜ ํŠน์ • ์ฝ”๋“œ ๊ฒฝ๋กœ๋ฅผ ํŠธ๋ฆฌ๊ฑฐ. '์–ด๋–ป๊ฒŒ' ์‚ฌ์šฉ๋˜๋Š”์ง€์— ๋Œ€ํ•ด ํŠธ๋ž˜ํ‚น์€ ํ•˜์ง€ ์•Š์Œ
  • ์ฆ‰, ํ˜ธ์ถœ ํšŸ์ˆ˜๋‚˜ ํ˜ธ์ถœ ์ˆœ์„œ์— ๋Œ€ํ•ด์„œ๋Š” ์‹ ๊ฒฝ์“ฐ์ง€ ์•Š๊ณ , ๊ธฐ๋Œ€๋˜๋Š” ๊ฒฐ๊ณผ๋ฅผ '๋ฆฌํ„ด'ํ•˜๋Š” ๊ฒƒ์ด ์ฃผ์š” ์—ญํ• ์ž„
  • ๋”ฐ๋ผ์„œ stub์€ ํ…Œ์ŠคํŠธ๊ฐ€ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ์˜ ๋Œ€์ƒ์— ์ง‘์ค‘ํ•˜๊ณ , ๊ตฌ์„ฑ ์š”์†Œ ๊ฐ„์˜ ์ƒํ˜ธ์ž‘์šฉ์ด ์•„๋‹ˆ๋ผ ํ…Œ์ŠคํŠธ์˜ ์ดˆ์ ์„ ๋งž์ถœ ๋•Œ ์‚ฌ์šฉ
class UserRepositoryStub:
    def get_user(self, user_id):
        return {"id": user_id, "name": "John Doe"}

def test_get_user():
    user_repo_stub = UserRepositoryStub()
    user_service = UserService(user_repo_stub)
    user = user_service.get_user(1)
    assert user == {"id": 1, "name": "John Doe"}

Mock์€ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ๋Œ€์ƒ๊ณผ ๊ทธ ์˜์กด์„ฑ ๊ฐ„์˜ ์ƒํ˜ธ์ž‘์šฉ์„ ๊ฒ€์ฆํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. (ํ–‰๋™ ๊ฒ€์ฆ)

  • ๋ฏธ๋ฆฌ ์ •์˜๋œ ์‘๋‹ต์„ ์ œ๊ณตํ•  ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ '์–ด๋–ป๊ฒŒ' ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€๋„ ๊ธฐ๋ก
  • Mock์€ ํŠน์ • ๋ฉ”์†Œ๋“œ๊ฐ€ ํŠน์ • ํšŸ์ˆ˜๋งŒํผ, ํŠน์ • ์ธ์ˆ˜๋กœ, ํŠน์ • ์ˆœ์„œ๋Œ€๋กœ ํ˜ธ์ถœ๋˜์—ˆ๋Š”์ง€ ๋“ฑ์„ ํ™•์ธ
  • ๋”ฐ๋ผ์„œ mock์€ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ ๋Œ€์ƒ์ด ๋‹ค๋ฅธ ๊ตฌ์„ฑ ์š”์†Œ์™€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ƒํ˜ธ์ž‘์šฉํ•˜๋Š”์ง€ ํ™•์ธํ•˜๋Š”๋ฐ ์‚ฌ์šฉ
from unittest.mock import Mock

def test_get_user():
    user_repo_mock = Mock()
    user_repo_mock.get_user.return_value = {"id": 1, "name": "John Doe"}
    user_service = UserService(user_repo_mock)
    user = user_service.get_user(1)
    user_repo_mock.get_user.assert_called_once_with(1)
    assert user == {"id": 1, "name": "John Doe"}

Branching Strategy

GitFlow

GitFlow๋Š” Vincent Driessen์ด ์ œ์•ˆํ•œ ๋ชจ๋ธ๋กœ, ๋ณต์žกํ•œ ํ”„๋กœ์ ํŠธ์— ์ ํ•ฉํ•œ ๋งค์šฐ ๊ตฌ์กฐํ™”๋œ branching ์ „๋žต์ž…๋‹ˆ๋‹ค. GitFlow์˜ ํ•ต์‹ฌ์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋ธŒ๋žœ์น˜๋ฅผ ์‚ฌ์šฉํ•ด ์ฝ”๋“œ์˜ ์ƒํƒœ๋ฅผ ๊ด€๋ฆฌํ•˜๊ณ , ๋ช…ํ™•ํ•˜๊ฒŒ ์—ญํ• ์„ ๋ถ„๋‹ดํ•˜๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค.

  • main: ์ตœ์ข…์ ์œผ๋กœ ๋ฐฐํฌ๋œ ์•ˆ์ •์ ์ธ ์ฝ”๋“œ๋ฅผ ์œ ์ง€ํ•˜๋Š” ๋ธŒ๋žœ์น˜. ๋ชจ๋“  ๋ฐฐํฌ ๋ฒ„์ „์€ ์ด ๋ธŒ๋žœ์น˜์—์„œ ๊ด€๋ฆฌ๋จ

  • develop: ๊ฐœ๋ฐœ ์ค‘์ธ ์ตœ์‹  ์ฝ”๋“œ๋ฅผ ์œ ์ง€ํ•˜๋Š” ๋ธŒ๋žœ์น˜. ์ƒˆ ๊ธฐ๋Šฅ์ด๋‚˜ ์ˆ˜์ • ์‚ฌํ•ญ์€ ์ด ๋ธŒ๋žœ์น˜์—์„œ ๋ณ‘ํ•ฉ๋˜๋ฉฐ, ๋‹ค์Œ ๋ฆด๋ฆฌ์Šค์˜ ๊ธฐ์ดˆ๊ฐ€ ๋จ

  • feature: ์ƒˆ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ์„ ์œ„ํ•œ ๋ธŒ๋žœ์น˜. develop ๋ธŒ๋žœ์น˜์—์„œ ๋ถ„๊ธฐํ•˜์—ฌ ์ž‘์—…์„ ์ง„ํ–‰ํ•˜๊ณ , ์™„๋ฃŒ๋˜๋ฉด ๋‹ค์‹œ develop ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉ

  • release: ๋‹ค์Œ ๋ฆด๋ฆฌ์Šค๋ฅผ ์ค€๋น„ํ•˜๋Š” ๋ธŒ๋žœ์น˜. develop ๋ธŒ๋žœ์น˜์—์„œ ๋ถ„๊ธฐํ•˜์—ฌ, ํ…Œ์ŠคํŠธ์™€ ๋ฒ„๊ทธ ์ˆ˜์ •์„ ์ง„ํ–‰ํ•œ ํ›„ main ๋ธŒ๋žœ์น˜์™€ develop ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉ

  • hotfix: ๋ฐฐํฌ๋œ ์ฝ”๋“œ์—์„œ ๋ฐœ์ƒํ•œ ๊ธด๊ธ‰ํ•œ ๋ฒ„๊ทธ ์ˆ˜์ •์„ ์œ„ํ•œ ๋ธŒ๋žœ์น˜. main ๋ธŒ๋žœ์น˜์—์„œ ๋ถ„๊ธฐํ•˜์—ฌ ์ˆ˜์ • ํ›„, main๊ณผ develop ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉ

์œ„์˜ ๋ธŒ๋žœ์น˜๋“ค์„ ํ™œ์šฉํ•˜์—ฌ ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๊ฐœ๋ฐœ์ด ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.

  1. ์ƒˆ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ: develop ๋ธŒ๋žœ์น˜์—์„œ ์ƒˆ ๊ธฐ๋Šฅ์„ ์œ„ํ•ด feature ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ์ด ์™„๋ฃŒ๋˜๋ฉด, feature ๋ธŒ๋žœ์น˜๋ฅผ develop ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉํ•ฉ๋‹ˆ๋‹ค.
  2. ๋ฆด๋ฆฌ์Šค ์ค€๋น„: ๋ฆด๋ฆฌ์Šค๋ฅผ ์ค€๋น„ํ•  ๋•Œ, develop ๋ธŒ๋žœ์น˜์—์„œ release ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋ฆด๋ฆฌ์Šค ๋ธŒ๋žœ์น˜์—์„œ๋Š” ํ…Œ์ŠคํŠธ ๋ฐ ๋ฒ„๊ทธ ์ˆ˜์ •์ด ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด, release ๋ธŒ๋žœ์น˜๋ฅผ main๊ณผ develop ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉํ•˜๊ณ , main ๋ธŒ๋žœ์น˜์—์„œ ํƒœ๊ทธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
  3. ๊ธด๊ธ‰ ๋ฒ„๊ทธ ์ˆ˜์ •: ๋ฐฐํฌ๋œ ๋ฒ„์ „์—์„œ ์‹ฌ๊ฐํ•œ ๋ฒ„๊ทธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, main ๋ธŒ๋žœ์น˜์—์„œ hotfix ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ๋ฒ„๊ทธ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. ์ˆ˜์ •์ด ์™„๋ฃŒ๋˜๋ฉด, hotfix ๋ธŒ๋žœ์น˜๋ฅผ main๊ณผ develop ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉํ•˜๊ณ , main ๋ธŒ๋žœ์น˜์—์„œ ํƒœ๊ทธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.
Trunk-Based Development (TBD)

Trunk-Based Development(TBD)๋Š” GitFlow์™€๋Š” ๋Œ€์กฐ์ ์œผ๋กœ ๋‹จ์ˆœํ•œ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง„ ์ „๋žต์ž…๋‹ˆ๋‹ค. ์ด ๋ฐฉ์‹์€ ๋ชจ๋“  ๊ฐœ๋ฐœ์ž๊ฐ€ ์ค‘์•™ ๋ธŒ๋žœ์น˜(์ฃผ๋กœ main ๋ธŒ๋žœ์น˜)์— ์ž‘์€ ๋‹จ์œ„๋กœ ์ž์ฃผ ๋ณ‘ํ•ฉํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค.

  • ์ค‘์•™ ๋ธŒ๋žœ์น˜(Trunk): main ๋ธŒ๋žœ์น˜ ๋˜๋Š” trunk ๋ธŒ๋žœ์น˜๊ฐ€ ์œ ์ผํ•œ ์ค‘์•™ ๋ธŒ๋žœ์น˜๋กœ, ๋ชจ๋“  ์ฝ”๋“œ๊ฐ€ ์ด ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉ๋จ
  • ์งง์€ ์ˆ˜๋ช… ๋ธŒ๋žœ์น˜: feature ๋ธŒ๋žœ์น˜๊ฐ€ ์กด์žฌํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋งค์šฐ ์งง์€ ๊ธฐ๊ฐ„ ๋™์•ˆ๋งŒ ์œ ์ง€๋˜๋ฉฐ, ๋น ๋ฅด๊ฒŒ main ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉ๋จ
  • ์ง€์†์  ํ†ตํ•ฉ(CI): TBD์—์„œ๋Š” ์ง€์†์  ํ†ตํ•ฉ(CI)์ด ํ•„์ˆ˜์ ์ž„. ๋ชจ๋“  ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ CI ํŒŒ์ดํ”„๋ผ์ธ์„ ํ†ตํ•ด ์ž๋™์œผ๋กœ ๋นŒ๋“œ๋˜๊ณ  ํ…Œ์ŠคํŠธ๋˜๋ฉฐ, ๋ณ‘ํ•ฉ ์ „์— ์ฝ”๋“œ์˜ ์•ˆ์ •์„ฑ์ด ํ™•์ธ๋จ

TBD์—์„œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ ๊ฐœ๋ฐœ์ด ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.

  1. ์ƒˆ ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ: ๊ธฐ๋Šฅ ๊ฐœ๋ฐœ์„ ์œ„ํ•ด ์งง์€ ์ˆ˜๋ช…์˜ feature ๋ธŒ๋žœ์น˜๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋Šฅ์„ ๊ฐœ๋ฐœํ•œ ํ›„, ๋น ๋ฅด๊ฒŒ main ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ๋ณ‘ํ•ฉ ์‹œ, CI ํŒŒ์ดํ”„๋ผ์ธ์„ ํ†ตํ•ด ์ž๋™์œผ๋กœ ๋นŒ๋“œ์™€ ํ…Œ์ŠคํŠธ๊ฐ€ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.
  2. ์ง€์†์  ๋ณ‘ํ•ฉ: ๋ชจ๋“  ๊ฐœ๋ฐœ์ž๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ž์ฃผ main ๋ธŒ๋žœ์น˜์— ๋ณ‘ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ๋ณ‘ํ•ฉ ์ฃผ๊ธฐ๋Š” ํ•˜๋ฃจ๋‚˜ ๋ฉฐ์น  ๋‹จ์œ„๋กœ ๋งค์šฐ ์งง์Šต๋‹ˆ๋‹ค. ํฐ ๋ณ€๊ฒฝ ์‚ฌํ•ญ๋„ ์ž‘์€ ๋‹จ์œ„๋กœ ๋‚˜๋ˆ„์–ด ์ ์ง„์ ์œผ๋กœ ๋ณ‘ํ•ฉํ•ฉ๋‹ˆ๋‹ค.
  3. ๋ฐฐํฌ: main ๋ธŒ๋žœ์น˜๊ฐ€ ํ•ญ์ƒ ๋ฐฐํฌ ๊ฐ€๋Šฅํ•œ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๋ฏ€๋กœ, ํ•„์š”ํ•  ๋•Œ ๋ฐ”๋กœ ๋ฐฐํฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฐฐํฌ๋Š” ์ฃผ๊ธฐ์ ์œผ๋กœ ๋˜๋Š” ๊ธฐ๋Šฅ ๋‹จ์œ„๋กœ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค.

Concurrecny and Parallelism

  • Concurrency: ๋™์‹œ์„ฑ์€ ์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋™์‹œ์— ์ง„ํ–‰ํ•˜๋Š” ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์ด๊ฒŒ ๋งŒ๋“œ๋Š” ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ๋Š” ํ•˜๋‚˜์˜ ์ž‘์—…์ด ์กฐ๊ธˆ์”ฉ ๊ต์ฐจํ•˜๋ฉฐ ์‹คํ–‰๋˜๋Š” ๋ฐฉ์‹์œผ๋กœ, ์ž‘์—…์ด ์งง์€ ์‹œ๊ฐ„ ๋™์•ˆ ๋ฒˆ๊ฐˆ์•„ ๊ฐ€๋ฉฐ ์‹คํ–‰๋ฉ๋‹ˆ๋‹ค. ์ฆ‰, ๋™์‹œ์— ์—ฌ๋Ÿฌ ์ž‘์—…์„ ์‹œ์ž‘ํ•˜์ง€๋งŒ, ํŠน์ • ์‹œ์ ์—์„œ๋Š” ํ•˜๋‚˜์˜ ์ž‘์—…๋งŒ ์‹คํ–‰๋˜๊ณ  ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค
  • Parallelism: ๋ณ‘๋ ฌ์„ฑ์€ ์—ฌ๋Ÿฌ ์ž‘์—…์„ ์ •๋ง๋กœ ๋™์‹œ์— ์‹คํ–‰ํ•˜๋Š” ๊ฐœ๋…์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ CPU ์ฝ”์–ด์—์„œ ๊ฐ๊ฐ์˜ ์ž‘์—…์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•จ์œผ๋กœ์จ ์ด๋ฃจ์–ด์ง‘๋‹ˆ๋‹ค. ๋ณ‘๋ ฌ์„ฑ์€ ์‹ค์ œ ํ•˜๋“œ์›จ์–ด์˜ ์ง€์›์ด ํ•„์š”ํ•˜๋ฉฐ, ์—ฌ๋Ÿฌ CPU ์ฝ”์–ด ๋˜๋Š” ์—ฌ๋Ÿฌ ์‹œ์Šคํ…œ์ด ๋™์‹œ์— ์ผ์„ ์ฒ˜๋ฆฌํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
Multi-Threading

๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋”ฉ์€ ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค ๋‚ด์—์„œ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜์—ฌ ์ž‘์—…์„ ๋™์‹œ์— ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. GIL(Global Interpreter Lock) ๋•Œ๋ฌธ์— CPU ๋ฐ”์šด๋“œ ์ž‘์—…์—์„œ๋Š” ์„ฑ๋Šฅ ํ–ฅ์ƒ์ด ํฌ์ง€ ์•Š์ง€๋งŒ, I/O ๋ฐ”์šด๋“œ ์ž‘์—…์—์„œ๋Š” ์ด์ ์„ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import threading
import time

def task(name, delay):
    for i in range(3):
        time.sleep(delay)
        print(f"Task {name} running")

# ์Šค๋ ˆ๋“œ ์ƒ์„ฑ
thread1 = threading.Thread(target=task, args=("A", 1))
thread2 = threading.Thread(target=task, args=("B", 2))

# ์Šค๋ ˆ๋“œ ์‹œ์ž‘
thread1.start()
thread2.start()

# ๋ฉ”์ธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋“ค์ด ๋๋‚˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆผ
thread1.join()
thread2.join()

print("All tasks completed.")
Multi-Processing

๋ฉ€ํ‹ฐ ํ”„๋กœ์„ธ์‹ฑ์€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ‘๋ ฌ๋กœ ์ž‘์—…์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. ๋ฉ€ํ‹ฐ ํ”„๋กœ์„ธ์‹ฑ์€ CPU ๋ฐ”์šด๋“œ ์ž‘์—…์—์„œ ์„ฑ๋Šฅ ์ด์ ์„ ํฌ๊ฒŒ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

import multiprocessing
import time

def task(name, delay):
    for i in range(3):
        time.sleep(delay)
        print(f"Process {name} running")

if __name__ == '__main__':
    # ํ”„๋กœ์„ธ์Šค ์ƒ์„ฑ
    process1 = multiprocessing.Process(target=task, args=("A", 1))
    process2 = multiprocessing.Process(target=task, args=("B", 2))

    # ํ”„๋กœ์„ธ์Šค ์‹œ์ž‘
    process1.start()
    process2.start()

    # ๋ฉ”์ธ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๋‹ค๋ฅธ ํ”„๋กœ์„ธ์Šค๋“ค์ด ๋๋‚˜๊ธฐ๋ฅผ ๊ธฐ๋‹ค๋ฆผ
    process1.join()
    process2.join()

    print("All processes completed.")
Multi-Threading vs. Multi-Processing

GIL๋กœ ์ธํ•ด Python์˜ ์Šค๋ ˆ๋“œ๋Š” ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ Python ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ I/O ๋ฐ”์šด๋“œ ์ž‘์—…, ์˜ˆ๋ฅผ ๋“ค์–ด ๋„คํŠธ์›Œํฌ ์š”์ฒญ ์ฒ˜๋ฆฌ, ํŒŒ์ผ ์ž…์ถœ๋ ฅ ๋“ฑ์˜ ์ž‘์—…์—์„œ๋Š” ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋”ฉ์ด ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด์™€ ๋‹ค๋ฅด๊ฒŒ ๋ฉ€ํ‹ฐ ํ”„๋กœ์„ธ์‹ฑ์€ GIL์˜ ์ œ์•ฝ์„ ๋ฐ›์ง€ ์•Š๊ณ , ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์–ด CPU ๋ฐ”์šด๋“œ ์ž‘์—…, ์˜ˆ๋ฅผ ๋“ค์–ด ๊ณ„์‚ฐ ์ง‘์•ฝ์ ์ธ ์ž‘์—…์—์„œ ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค.

Asyncio

Asyncio๋Š” ๋น„๋™๊ธฐ ํ”„๋กœ๊ทธ๋ž˜๋ฐ์„ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•ด์ฃผ๋Š” Python์˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์ž…๋‹ˆ๋‹ค. ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋Œ€์‹ , ์ž‘์—…์„ ์ž ๊น ๋ฉˆ์ถ”๊ณ (์˜ˆ: I/O ๋Œ€๊ธฐ) ๊ทธ ์‹œ๊ฐ„ ๋™์•ˆ ๋‹ค๋ฅธ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์ž…๋‹ˆ๋‹ค. Asyncio๋Š” GIL์— ํฌ๊ฒŒ ์˜ํ–ฅ์„ ๋ฐ›์ง€ ์•Š์œผ๋ฉฐ, ์ฃผ๋กœ I/O-bound ์ž‘์—…์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ์›น ์„œ๋ฒ„, ๋„คํŠธ์›Œํฌ ์„œ๋ฒ„, ๋น„๋™๊ธฐ ํŒŒ์ผ ์ฒ˜๋ฆฌ ๋“ฑ์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. Asyncio๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ๋‹จ์ผ ์Šค๋ ˆ๋“œ์—์„œ ์ž‘๋™ํ•˜๋ฉฐ, ๋งŽ์€ ์ˆ˜์˜ ์ž‘์—…์„ ํšจ์œจ์ ์œผ๋กœ ์Šค์ผ€์ค„๋งํ•˜์ง€๋งŒ, CPU-bound ์ž‘์—…์—์„œ๋Š” Multi-Processing๋งŒํผ ๊ฐ•๋ ฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Database

CoackroachDB

CockroachDB๋Š” ๋ถ„์‚ฐ SQL ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๋กœ, ์ˆ˜ํ‰ ํ™•์žฅ์„ฑ, ์ž๋™ ๋ณต์ œ ๋ฐ ๋ณต๊ตฌ, ๊ทธ๋ฆฌ๊ณ  ๊ฐ•ํ•œ ์ผ๊ด€์„ฑ(strong consistency)์„ ํŠน์ง•์œผ๋กœ ํ•จ. ์ด๋ฆ„์—์„œ ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด, Cockroach์ฒ˜๋Ÿผ ์‰ฝ๊ฒŒ ์ฃฝ์ง€ ์•Š๋Š”(disaster resilient) ์‹œ์Šคํ…œ์„ ๋ชฉํ‘œ๋กœ ๋งŒ๋“ค์–ด์กŒ์Œ. Google์˜ Spanner์—์„œ ์˜๊ฐ์„ ๋ฐ›์•„ ๊ฐœ๋ฐœ๋˜์—ˆ๊ณ , Go ์–ธ์–ด๋กœ ์ž‘์„ฑ๋˜์—ˆ์Œ

  • ๋ถ„์‚ฐ SQL: ์ „ํ†ต์ ์ธ RDBMS์ฒ˜๋Ÿผ SQL์„ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ๋ฐ์ดํ„ฐ๋Š” ์—ฌ๋Ÿฌ ๋…ธ๋“œ์— ๋ถ„์‚ฐ๋˜์–ด ์ €์žฅ. PostgreSQL wire protocol์„ ์‚ฌ์šฉํ•ด์„œ PostgreSQL ํด๋ผ์ด์–ธํŠธ๋‚˜ ORM๊ณผ ํ˜ธํ™˜
  • ๊ฐ•ํ•œ ์ผ๊ด€์„ฑ: Raft consensus ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ๋…ธ๋“œ ๊ฐ„์˜ ๋ณต์ œ๋ณธ(replica) ๊ฐ„์— ๊ฐ•ํ•œ ์ผ๊ด€์„ฑ์„ ์œ ์ง€. ์ฝ๊ธฐ/์“ฐ๊ธฐ ๋ชจ๋‘ ์ผ๊ด€์„ฑ์ด ๋ณด์žฅ๋˜์–ด, ๋ถ„์‚ฐ ํ™˜๊ฒฝ์—์„œ๋„ ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ์„ ๋ณด์žฅ
  • ์ž๋™ ์ƒค๋”ฉ(Auto-Sharding): ๋ฐ์ดํ„ฐ๋Š” ์ž๋™์œผ๋กœ range ๋‹จ์œ„๋กœ ์ชผ๊ฐœ์ ธ ์—ฌ๋Ÿฌ ๋…ธ๋“œ์— ๋ถ„์‚ฐ. ํŠน์ • range๊ฐ€ ์ปค์ง€๋ฉด ์ž๋™์œผ๋กœ ๋ถ„ํ• 
  • ๋ณต์ œ ๋ฐ ์žฅ์•  ๋ณต๊ตฌ: ๊ฐ range๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ 3๊ฐœ ์ด์ƒ์˜ replica๋ฅผ ๊ฐ€์ง€๋ฉฐ, ๋‹ค์ˆ˜๊ฒฐ(majority)๋กœ ๊ฒฐ์ •. ํŠน์ • ๋…ธ๋“œ๊ฐ€ ์žฅ์• ๊ฐ€ ๋‚˜๋„ ๋‚˜๋จธ์ง€ ๋…ธ๋“œ๋กœ ์ž๋™ ๋ณต๊ตฌ๊ฐ€ ๊ฐ€๋Šฅ
  • Geo-Distribution ์ง€์›: ์—ฌ๋Ÿฌ ์ง€์—ญ์— ๊ฑธ์นœ ๋ฐฐํฌ๊ฐ€ ๊ฐ€๋Šฅํ•˜๊ณ , ์ง€์—ญ ๊ธฐ๋ฐ˜ ๋ ˆ์ดํ„ด์‹œ ์ตœ์ ํ™”๋‚˜ ๋ฐ์ดํ„ฐ ์ง€์—ญ์„ฑ(geo-partitioning) ๊ธฐ๋Šฅ๋„ ์ œ๊ณต

์œ„์™€ ๊ฐ™์€ ํŠน์ง• ๋•Œ๋ฌธ์— ๊ณ ๊ฐ€์šฉ์„ฑ๊ณผ ๋ณต์›๋ ฅ์ด ์ค‘์š”ํ•œ ์‹œ์Šคํ…œ (์˜ˆ: ๊ธˆ์œต, ๊ฒŒ์ž„, ํ—ฌ์Šค์ผ€์–ด) / ๋ฉ€ํ‹ฐ ๋ฆฌ์ „ ๋˜๋Š” ๋ฉ€ํ‹ฐ ๋ฐ์ดํ„ฐ์„ผํ„ฐ ํ™˜๊ฒฝ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ / ๊ธฐ์กด RDBMS์˜ SQL ๊ธฐ๋Šฅ์„ ์œ ์ง€ํ•˜๋ฉด์„œ ๋ถ„์‚ฐ ์‹œ์Šคํ…œ์˜ ์ด์ ์„ ๋ˆ„๋ฆฌ๊ณ  ์‹ถ์€ ๊ฒฝ์šฐ์— ์‚ฌ์šฉ ๊ฐ€๋Šฅ

+----------------+
|    SQL Layer   |   <- PostgreSQL ํ˜ธํ™˜ SQL ์ธํ„ฐํŽ˜์ด์Šค
+----------------+
+-------------------+
| Transaction Layer |   <- ๋ถ„์‚ฐ ํŠธ๋žœ์žญ์…˜, ๊ฐ•ํ•œ ์ผ๊ด€์„ฑ (Raft + MVCC)
+-------------------+
+-----------------------+
|  Distributed KV Layer |  <- Range ๋ถ„ํ• , ์ž๋™ ์ƒค๋”ฉ, ๋ณต์ œ ๊ด€๋ฆฌ
+-----------------------+
+----------------------+
|     Storage Layer    |  <- RocksDB ๊ธฐ๋ฐ˜ ๋กœ์ปฌ ์Šคํ† ๋ฆฌ์ง€
+----------------------+
DuckDB

OLAP(Online Analytical Processing)์— ์ตœ์ ํ™”๋œ ๊ฒฝ๋Ÿ‰ ์ปฌ๋Ÿผ ์ง€ํ–ฅ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค. ์ฃผ๋กœ ๋ถ„์„ ์ฟผ๋ฆฌ๋ฅผ ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋ฉฐ, ๋‹ค์Œ๊ณผ ๊ฐ™์€ ํŠน์ง•์ด ์žˆ์Œ

  • ์ปฌ๋Ÿผ ์ง€ํ–ฅ ์ €์žฅ (Columnar Storage): ๊ฐ ์ปฌ๋Ÿผ์„ ๋ณ„๋„๋กœ ์ €์žฅํ•˜์—ฌ, ํ•„์š”ํ•œ ์ปฌ๋Ÿผ๋งŒ ์ฝ์„ ์ˆ˜ ์žˆ์Œ. ๋Œ€์šฉ๋Ÿ‰ ๋ฐ์ดํ„ฐ์—์„œ ๋ถ„์„ ์ฟผ๋ฆฌ ์†๋„๊ฐ€ ๋น ๋ฆ„. SELECT avg(salary) FROM employees ๊ฐ™์€ ์ฟผ๋ฆฌ์— ์œ ๋ฆฌ
  • ์ž„๋ฒ ๋””๋“œ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค: SQLite์ฒ˜๋Ÿผ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋กœ ์ง์ ‘ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ž„๋ฒ ๋”ฉ ๊ฐ€๋Šฅ (์„œ๋ฒ„ ์—†์ด๋„ ์‹คํ–‰ ๊ฐ€๋Šฅ). Python, C++, R ๋“ฑ ๋‹ค์–‘ํ•œ ์–ธ์–ด์—์„œ import ํ•ด์„œ ๋ฐ”๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • ์ธ๋ฉ”๋ชจ๋ฆฌ + ๋””์Šคํฌ ์ €์žฅ: ๋ฉ”๋ชจ๋ฆฌ์—์„œ ๋น ๋ฅด๊ฒŒ ์—ฐ์‚ฐํ•˜๋˜, ํ•„์š”ํ•œ ๊ฒฝ์šฐ ๋””์Šคํฌ์— ์ €์žฅํ•˜๊ฑฐ๋‚˜ ์ฝ์–ด์˜ค๋Š” ํ•˜์ด๋ธŒ๋ฆฌ๋“œ ๋ชจ๋ธ
  • Parquet, CSV ๋“ฑ ๋‹ค์–‘ํ•œ ํฌ๋งท ์ง€์›: ํŠนํžˆ Parquet๊ณผ์˜ ์—ฐ๋™์ด ์ข‹์•„์„œ, ๋ฐ์ดํ„ฐ๋ฅผ ๊ตณ์ด DuckDB๋กœ importํ•˜์ง€ ์•Š๊ณ ๋„ ๋ฐ”๋กœ ์ฟผ๋ฆฌ ๊ฐ€๋Šฅ
  • Vectorized Execution Engine: SIMD ๋“ฑ์„ ํ™œ์šฉํ•ด ๋‹ค์ˆ˜์˜ ๊ฐ’์„ ํ•œ ๋ฒˆ์— ์ฒ˜๋ฆฌ โ†’ ๋งค์šฐ ๋น ๋ฅธ ์ฟผ๋ฆฌ ์„ฑ๋Šฅ
  • ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์ง€์›: ์ฟผ๋ฆฌ๋ฅผ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰ํ•ด์„œ ๋” ๋น ๋ฅด๊ฒŒ ์ฒ˜๋ฆฌ
ํŠน์ง• DuckDB SQLite Postgres BigQuery
์ €์žฅ ๊ตฌ์กฐ Columnar Row Row Columnar
์‹คํ–‰ ์—”์ง„ Vectorized Row-based Row-based Vectorized
๋ถ„์„ ์ฟผ๋ฆฌ ์„ฑ๋Šฅ ๋งค์šฐ ๋น ๋ฆ„ ๋А๋ฆผ ๋ณดํ†ต ๋งค์šฐ ๋น ๋ฆ„
์„ค์น˜ ๋ฐ ์‹คํ–‰ ๋งค์šฐ ๊ฐ„๋‹จ ๋งค์šฐ ๊ฐ„๋‹จ ๋ณต์žก ํด๋ผ์šฐ๋“œ
์„œ๋ฒ„ ํ•„์š” ์—†์Œ ์—†์Œ ์žˆ์Œ ์žˆ์Œ
๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ์žˆ์Œ ์—†์Œ ์žˆ์Œ ์žˆ์Œ

Message Broker

RabbitMQ
  • ์žฅ์  1. ๋ฉ”์‹œ์ง€ ๋ณด์žฅ: RabbitMQ๋Š” ๋ฉ”์‹œ์ง€ ์ „์†ก, ํ™•์ธ, ์žฌ์‹œ๋„, TTL(Time-to-Live) ์„ค์ • ๋“ฑ ๋ฉ”์‹œ์ง€ ๋ณด์žฅ ๊ธฐ๋Šฅ์ด ๋›ฐ์–ด๋‚จ

  • ์žฅ์  2. ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ฐ ๊ด€๋ฆฌ ๋„๊ตฌ: ๋‹ค์–‘ํ•œ ํ”Œ๋Ÿฌ๊ทธ์ธ ๋ฐ ์›น ๊ธฐ๋ฐ˜์˜ ๊ด€๋ฆฌ ๋„๊ตฌ๋ฅผ ์ œ๊ณตํ•˜์—ฌ ์‚ฌ์šฉ ๋ฐ ๊ด€๋ฆฌ๊ฐ€ ํŽธ๋ฆฌ

  • ์žฅ์  3. ์„ฑ์ˆ™๋„: ์˜ค๋ž˜๋œ ํ”„๋กœ์ ํŠธ๋กœ, ๋‹ค์–‘ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ์ง€์›๊ณผ ์•ˆ์ •์„ฑ์„ ์ œ๊ณต

  • ๋‹จ์  1. ๋†’์€ ์ง€์—ฐ ์‹œ๊ฐ„: Kafka๋‚˜ RedisQ์— ๋น„ํ•ด ์ƒ๋Œ€์ ์œผ๋กœ ์ง€์—ฐ ์‹œ๊ฐ„์ด ๋†’์„ ์ˆ˜ ์žˆ์Œ

  • ๋‹จ์  2. ๋ณต์žก์„ฑ: ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๋Š” ๋งŒํผ ์„ค์ •๊ณผ ์‚ฌ์šฉ์ด ์ƒ๋Œ€์ ์œผ๋กœ ๋ณต์žกํ•  ์ˆ˜ ์žˆ์Œ

  • ๋‹จ์  3. ํ™•์žฅ์„ฑ ํ•œ๊ณ„: RabbitMQ๋Š” ๊ณ ๋„๋กœ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ์‹œ์Šคํ…œ์ด์ง€๋งŒ, Kafka์— ๋น„ํ•ด ํ™•์žฅ์„ฑ ๋ฉด์—์„œ ์ œํ•œ์ ์ž„

Kafka
  • ์žฅ์  1. ํ™•์žฅ์„ฑ: ๋งค์šฐ ๋›ฐ์–ด๋‚œ ํ™•์žฅ์„ฑ์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด, ์ˆ˜๋ฐฑ ํ…Œ๋ผ๋ฐ”์ดํŠธ์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Œ

  • ์žฅ์  2. ๊ณ ์„ฑ๋Šฅ: ์‹ค์‹œ๊ฐ„ ์ŠคํŠธ๋ฆฌ๋ฐ ๋ฐ์ดํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐ ์ตœ์ ํ™”๋˜์–ด ์žˆ์–ด, ๋†’์€ ์ฒ˜๋ฆฌ๋Ÿ‰์„ ์š”๊ตฌํ•˜๋Š” ํ™˜๊ฒฝ์—์„œ ํƒ์›”

  • ์žฅ์  3. ๋‚ด๊ตฌ์„ฑ: ๋ฉ”์‹œ์ง€๊ฐ€ ๋กœ๊ทธ์— ๊ธฐ๋ก๋˜๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ ์†์‹ค ๊ฐ€๋Šฅ์„ฑ์ด ๋‚ฎ์Œ

  • ๋‹จ์  1. ๋ณต์žก์„ฑ: ์ดˆ๊ธฐ ์„ค์ •๊ณผ ์šด์˜์ด ๋ณต์žกํ•˜๋ฉฐ, ํด๋Ÿฌ์Šคํ„ฐ ๊ด€๋ฆฌ๊ฐ€ ๊นŒ๋‹ค๋กœ์šธ ์ˆ˜ ์žˆ์Œ

  • ๋‹จ์  2. ๋†’์€ ํ•™์Šต ๊ณก์„ : Kafka๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋งŽ์€ ํ•™์Šต๊ณผ ์ดํ•ด๊ฐ€ ํ•„์š”

  • ๋‹จ์  3. ์ง€์—ฐ ํ—ˆ์šฉ: ๋งค์šฐ ๋‚ฎ์€ ์ง€์—ฐ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ RabbitMQ๋‚˜ RedisQ๊ฐ€ ๋” ์ ํ•ฉํ•  ์ˆ˜ ์žˆ์Œ

RedisQ
  • ์žฅ์  1. ์†๋„: RedisQ๋Š” ๋ฉ”๋ชจ๋ฆฌ ๊ธฐ๋ฐ˜์ด๊ธฐ ๋•Œ๋ฌธ์— ๋งค์šฐ ๋น ๋ฅธ ์ฒ˜๋ฆฌ ์†๋„๋ฅผ ์ œ๊ณต

  • ์žฅ์  2. ๊ฐ„ํŽธ์„ฑ: Redis ์ž์ฒด๊ฐ€ ๋‹จ์ˆœํ•˜๋ฉฐ, ํ๋ฅผ ์„ค์ •ํ•˜๊ณ  ์‚ฌ์šฉํ•˜๋Š” ๋ฐ ์žˆ์–ด ๋งค์šฐ ๊ฐ„ํŽธ

  • ์žฅ์  3. ๋‹ค์–‘ํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ: Redis๋Š” ํ ์™ธ์—๋„ ์—ฌ๋Ÿฌ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์ œ๊ณตํ•˜์—ฌ ์œ ์—ฐํ•˜๊ฒŒ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ

  • ๋‹จ์  1. ๋ฐ์ดํ„ฐ ์ง€์†์„ฑ ๋ฌธ์ œ: ๊ธฐ๋ณธ์ ์œผ๋กœ ์ธ๋ฉ”๋ชจ๋ฆฌ ์‹œ์Šคํ…œ์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ์˜ ์˜์†์„ฑ์ด ๋ณด์žฅ๋˜์ง€ ์•Š์œผ๋ฉฐ, ์„œ๋ฒ„๊ฐ€ ์žฌ์‹œ์ž‘๋˜๋ฉด ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ฌ๋ผ์งˆ ์ˆ˜ ์žˆ์Œ

  • ๋‹จ์  2. ํ™•์žฅ์„ฑ ์ œํ•œ: Redis๋Š” ์ˆ˜ํ‰์  ํ™•์žฅ์ด ์ œํ•œ์ ์ด๋ฉฐ, ๋ฐ์ดํ„ฐ๊ฐ€ ์ปค์งˆ์ˆ˜๋ก ์„ฑ๋Šฅ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ์Œ

  • ๋‹จ์  3. ๊ธฐ๋Šฅ ์ œํ•œ: RedisQ๋Š” ๋‹ค๋ฅธ ๋ฉ”์‹œ์ง€ ๋ธŒ๋กœ์ปค์— ๋น„ํ•ด ๊ธฐ๋Šฅ์ด ์ œํ•œ์ ์ž„

Summary
  • RabbitMQ๋Š” ๋‹ค์–‘ํ•œ ๊ธฐ๋Šฅ์„ ํ•„์š”๋กœ ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ํ•ฉํ•˜๋ฉฐ, ์•ˆ์ •์ ์ด๊ณ  ๊ด€๋ฆฌ ๋„๊ตฌ๊ฐ€ ํ’๋ถ€ํ•˜์ง€๋งŒ, ์ƒ๋Œ€์ ์œผ๋กœ ๋ณต์žกํ•˜๊ณ  ํ™•์žฅ์„ฑ์— ์ œํ•œ์ด ์žˆ์Œ

  • Kafka๋Š” ๋†’์€ ์ฒ˜๋ฆฌ๋Ÿ‰๊ณผ ํ™•์žฅ์„ฑ์„ ํ•„์š”๋กœ ํ•˜๋Š” ๋Œ€๊ทœ๋ชจ ๋ฐ์ดํ„ฐ ์ŠคํŠธ๋ฆฌ๋ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ํ•ฉํ•ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์„ค์ •๊ณผ ์šด์˜์ด ๋ณต์žกํ•  ์ˆ˜ ์žˆ์Œ

  • RedisQ๋Š” ๋งค์šฐ ๋น ๋ฅธ ์„ฑ๋Šฅ๊ณผ ๋‹จ์ˆœํ•œ ์‚ฌ์šฉ์„ ํ•„์š”๋กœ ํ•˜๋Š” ๊ฒฝ์šฐ์— ์ ํ•ฉํ•˜๋ฉฐ, ์˜์†์„ฑ์ด ์ค‘์š”ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—๋Š” ๋ถ€์ ํ•ฉํ•  ์ˆ˜ ์žˆ์Œ

Celery

Celery๋Š” Python์œผ๋กœ ์ž‘์„ฑ๋œ ๋ถ„์‚ฐ ์ž‘์—… ํ ์‹œ์Šคํ…œ์œผ๋กœ, ๋Œ€๊ทœ๋ชจ ๋น„๋™๊ธฐ ์ž‘์—… ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋‚˜ ๋ฐฑ์—”๋“œ ์‹œ์Šคํ…œ์—์„œ ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…์„ ๋น„๋™๊ธฐ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๊ณ , ์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜, ์ง€์—ฐ๋œ ์ž‘์—…์„ ์˜ˆ์•ฝํ•˜๋Š” ๋ฐ ์ฃผ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

  • Task: Celery์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ํ•จ์ˆ˜. ์ด ์ž‘์—…์€ worker์— ์˜ํ•ด ๋น„๋™๊ธฐ์ ์œผ๋กœ ์‹คํ–‰๋จ
  • Worker: Celery์—์„œ ์ž‘์—…์„ ์‹ค์ œ๋กœ ์‹คํ–‰ํ•˜๋Š” ํ”„๋กœ์„ธ์Šค. ์ผ๋ฐ˜์ ์œผ๋กœ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์›Œ์ปค๊ฐ€ ๋™์‹œ์— ์ž‘๋™ํ•˜์—ฌ ์ž‘์—…์„ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌ
  • Broker: ์ž‘์—…์„ ํ์— ๋„ฃ๊ณ , ์›Œ์ปค๊ฐ€ ์ด ํ์—์„œ ์ž‘์—…์„ ๊ฐ€์ ธ๊ฐ€๋Š” ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘. ๋Œ€ํ‘œ์ ์ธ ๋ธŒ๋กœ์ปค๋กœ๋Š” Redis, RabbitMQ ๋“ฑ์ด ์žˆ์Œ
  • Backend: ์ž‘์—… ๊ฒฐ๊ณผ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜๋Š” ์‹œ์Šคํ…œ. Redis, RabbitMQ, Memcached, ๋˜๋Š” DB๋ฅผ ๋ฐฑ์—”๋“œ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Œ

Monitoring

Hardware Monitoring

Prometheus๋Š” ์‹œ์Šคํ…œ ๋ชจ๋‹ˆํ„ฐ๋ง ๋ฐ ๊ฒฝ๊ณ ๋ฅผ ์œ„ํ•ด ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉ๋˜๋Š” ์˜คํ”ˆ ์†Œ์Šค ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. Prometheus๋Š” ๊ฐ ํƒ€๊ฒŸ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ์ง์ ‘ ๊ฐ€์ ธ์˜ค๋Š”(Pull) ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ž์ฒด์ ์œผ๋กœ ๋‹ค์–‘ํ•œ ์‹œ์Šคํ…œ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐ ์„œ๋น„์Šค์—์„œ ๋ฉ”ํŠธ๋ฆญ์„ ์ˆ˜์ง‘ํ•˜๊ธฐ ์œ„ํ•ด Exporter๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

Node Exporter๋Š” Prometheus์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋˜๋Š” ๊ฐ€์žฅ ์ผ๋ฐ˜์ ์ธ Exporter ์ค‘ ํ•˜๋‚˜๋กœ, ์„œ๋ฒ„์˜ ํ•˜๋“œ์›จ์–ด ๋ฐ ์šด์˜์ฒด์ œ ๊ด€๋ จ ๋ฉ”ํŠธ๋ฆญ์„ ์ˆ˜์ง‘ํ•˜๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. Prometheus๊ฐ€ ์ˆ˜์ง‘ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฉ”ํŠธ๋ฆญ์—๋Š” CPU ์‚ฌ์šฉ๋Ÿ‰, ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰, ๋””์Šคํฌ I/O, ๋„คํŠธ์›Œํฌ ํŠธ๋ž˜ํ”ฝ ๋“ฑ์˜ ์ •๋ณด๊ฐ€ ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

Prometheus, Node Exporter, Grafana๋ฅผ ํ™œ์šฉํ•˜์—ฌ ํ•˜๋“œ์›จ์–ด ๋ชจ๋‹ˆํ„ฐ๋ง์„ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ด๊ณณ์— ๋” ์ž์„ธํžˆ ๊ธฐ๋กํ•˜์˜€์Šต๋‹ˆ๋‹ค.

Deployment

ArgoCD

ArgoCD๋Š” Kubernetes ํ™˜๊ฒฝ์—์„œ GitOps ๋ฐฉ์‹์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ ๋ฐ ๊ด€๋ฆฌ๋ฅผ ์ž๋™ํ™”ํ•˜๋Š” ๋„๊ตฌ์ž…๋‹ˆ๋‹ค. ArgoCD๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด Git ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ์ €์žฅ๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ •์˜(Manifest)๋ฅผ ๊ธฐ์ค€์œผ๋กœ Kubernetes ํด๋Ÿฌ์Šคํ„ฐ์— ์ž๋™์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฐฐํฌํ•˜๊ณ , ํด๋Ÿฌ์Šคํ„ฐ ์ƒํƒœ๋ฅผ ์ง€์†์ ์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋งํ•˜๋ฉด์„œ Git์˜ ์ƒํƒœ์™€ ์ผ์น˜ํ•˜์ง€ ์•Š๋Š” ๊ฒฝ์šฐ ์ด๋ฅผ ๋™๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • Application ์˜ค๋ธŒ์ ํŠธ: Application์€ Git ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์™€ Kubernetes ํด๋Ÿฌ์Šคํ„ฐ ๊ฐ„์˜ ์—ฐ๊ฒฐ ๊ณ ๋ฆฌ๋กœ, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ •์˜์™€ ํด๋Ÿฌ์Šคํ„ฐ์— ์ ์šฉ๋  ๋ฆฌ์†Œ์Šค, ๋™๊ธฐํ™” ์ •์ฑ… ๋“ฑ์„ ํฌํ•จ
  • App Controller: Kubernetes ํด๋Ÿฌ์Šคํ„ฐ์˜ ์ƒํƒœ์™€ Git ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์˜ ์ƒํƒœ๋ฅผ ์ง€์†์ ์œผ๋กœ ๋ชจ๋‹ˆํ„ฐ๋ง. ๋‘ ์ƒํƒœ๊ฐ€ ๋‹ค๋ฅด๋ฉด ๋™๊ธฐํ™” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์—ฌ ํด๋Ÿฌ์Šคํ„ฐ ์ƒํƒœ๋ฅผ Git ์ƒํƒœ์™€ ์ผ์น˜์‹œํ‚ค๋ ค ํ•จ
  • Repository Server: Git ๋ฆฌํฌ์ง€ํ† ๋ฆฌ์— ์ ‘๊ทผํ•˜๊ณ  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฐฐํฌ์— ํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค๋ฅผ ์ฝ์–ด์˜ค๋Š” ์—ญํ• 
  • Dex: ์ธ์ฆ ์„œ๋น„์Šค๋กœ, ArgoCD๋Š” ์™ธ๋ถ€ ์ธ์ฆ ์‹œ์Šคํ…œ(Google, GitHub, LDAP ๋“ฑ)๊ณผ ํ†ตํ•ฉํ•˜์—ฌ ์‚ฌ์šฉ์ž ์ธ์ฆ ๋ฐ ๊ถŒํ•œ์„ ๊ด€๋ฆฌ

๋กค๋ฐฑ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ์—” ArgoCD UI์—์„œ ๋ฐฐํฌ๋œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๊ณ , ํŠน์ • ํžˆ์Šคํ† ๋ฆฌ(๋ฐฐํฌ ์ด๋ ฅ)๋ฅผ ์„ ํƒํ•˜์—ฌ ํ•ด๋‹น ๋ฒ„์ „์œผ๋กœ ๋กค๋ฐฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Supabase

Supabase๋Š” ์˜คํ”ˆ์†Œ์Šค ๋ฐฑ์—”๋“œ ์„œ๋น„์Šค ํ”Œ๋žซํผ(BaaS, Backend as a Service)์œผ๋กœ, Firebase์˜ ์˜คํ”ˆ์†Œ์Šค ๋Œ€์•ˆ์œผ๋กœ ์ž์ฃผ ์–ธ๊ธ‰๋ฉ๋‹ˆ๋‹ค. Supabase๋Š” ํŠนํžˆ PostgreSQL์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•˜๋ฉฐ, ๋น ๋ฅด๊ฒŒ ํ˜„๋Œ€์ ์ธ ์›นยท๋ชจ๋ฐ”์ผ ์•ฑ์˜ ๋ฐฑ์—”๋“œ๋ฅผ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋„์™€์ค๋‹ˆ๋‹ค. ์ฃผ์š” ๊ตฌ์„ฑ ์š”์†Œ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • PostgreSQL: ๊ฐ•๋ ฅํ•œ ๊ด€๊ณ„ํ˜• ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค, ํ™•์žฅ์„ฑ๊ณผ ์ •ํ•ฉ์„ฑ ์ œ๊ณต
  • Realtime: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์˜ ๋ณ€ํ™” ์‚ฌํ•ญ์„ ์‹ค์‹œ๊ฐ„์œผ๋กœ ์ŠคํŠธ๋ฆฌ๋ฐ
  • Authentication: OAuth, email/password, magic link ๋“ฑ์„ ํ†ตํ•œ ์ธ์ฆ
  • Storage: ํŒŒ์ผ ์Šคํ† ๋ฆฌ์ง€ (์ด๋ฏธ์ง€, ๋™์˜์ƒ ๋“ฑ) ์ง€์›
  • Edge Functions: ์„œ๋ฒ„๋ฆฌ์Šค ํ•จ์ˆ˜, Vercel์˜ Edge Functions์ฒ˜๋Ÿผ ์‚ฌ์šฉ ๊ฐ€๋Šฅ
  • ์ž๋™ API ์ƒ์„ฑ: ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์Šคํ‚ค๋งˆ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ RESTful + GraphQL API ์ž๋™ ์ƒ์„ฑ

Layered Architecture

์ด ๋ถ€๋ถ„์€ ์ธํ”„๋Ÿฐ ๊ฐ•์˜ '์ œ๋ฏธ๋‹ˆ์˜ ๊ฐœ๋ฐœ์‹ค๋ฌด' ๋ฌด๋ฃŒ ๊ฐ•์˜๋ฅผ ์ฐธ๊ณ ํ•œ ๋‚ด์šฉ์ž…๋‹ˆ๋‹ค. ์งง๊ณ  ์œ ์ตํ•œ ๋‚ด์šฉ์ด ์žˆ์œผ๋‹ˆ ๋“ค์–ด๋ณด์‹œ๋Š” ๊ฒƒ์„ ์ถ”์ฒœ๋“œ๋ฆฝ๋‹ˆ๋‹ค.

  • Presentation Layer: ์‚ฌ์šฉ์ž์˜ ์š”์ฒญ์„ ๋ฐ›์•„ API๋กœ ์‘๋‹ตํ•˜๋Š” ์˜์—ญ. ์ฆ‰, Controller์™€ ๊ฐ™์ด API์˜ ๋…ธ์ถœ์„ ๋‹ด๋‹นํ•˜๋Š” ์˜์—ญ
  • Business Layer: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ํ•ต์‹ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์˜์—ญ
  • Implementation Layer: ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์‚ฌ์šฉํ•˜๋Š” ๋„๋ฉ”์ธ ๊ฐ์ฒด์™€ ์œ ํ‹ธ๋ฆฌํ‹ฐ ํด๋ž˜์Šค๊ฐ€ ํฌํ•จ๋œ ์˜์—ญ
  • Data Access Layer: DB, ์บ์‹œ ๋“ฑ ์™ธ๋ถ€ ๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ์™€ ํ†ต์‹ ํ•˜๋Š” ์˜์—ญ
graph TD
    A["Presentation Layer"] --> B["Business Layer"]
    B --> C["Implementation Layer"]
    C --> D["Data Access Layer<br>(DB, Cache, Storage)"]

์ด๋Ÿฌํ•œ ๋ ˆ์ด์–ด๋“œ ์•„ํ‚คํ…์ณ์—์„œ ์ง€์ผœ์•ผ ํ•  ๊ทœ์น™์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  1. ๋ ˆ์ด์–ด๋Š” ์œ„์—์„œ ์•„๋ž˜๋กœ ์ˆœ๋ฐฉํ–ฅ์œผ๋กœ๋งŒ ์ฐธ์กฐ
  2. ๋ ˆ์ด์–ด์˜ ์ฐธ์กฐ ๋ฐฉํ–ฅ์ด ์—ญ๋ฅ˜๋˜์ง€ ์•Š์Œ
  3. ๋ ˆ์ด์–ด์˜ ์ฐธ์กฐ๊ฐ€ ํ•˜์œ„ ๋ ˆ์ด์–ด๋ฅผ ๊ฑด๋„ˆ ๋›ฐ์ง€ ์•Š์Œ
  4. ๋™์ผ ๋ ˆ์ด์–ด ๊ฐ„์—๋Š” ์„œ๋กœ ์ฐธ์กฐํ•˜์ง€ ์•Š์•„์•ผ ํ•œ๋‹ค. (๋‹ค๋งŒ implement layer๋Š” ์˜ˆ์™ธ)
    • ๋น„์ฆˆ๋‹ˆ์Šค ๋ ˆ์ด์–ด๊ฐ€ ์˜ค์—ผ๋˜์ง€ ์•Š์œผ๋ฉด์„œ๋„ ๊ตฌํ˜„์ฑ„์˜ ์žฌ์‚ฌ์šฉ์„ฑ ๋†’์ผ ์ˆ˜ ์žˆ์Œ

Domain-Driven Development

๊ด€๋ จํ•œ ๊ฐœ๋ฐœ ๋ฐฉ๋ฒ•๋ก ์œผ๋กœ๋Š” DDD๊ฐ€ ์žˆ์œผ๋ฉฐ ์ด์™€ ๊ด€๋ จํ•ด์„œ๋Š” ์นด์นด์˜คํŽ˜์ด ํ…Œํฌ ๋ธ”๋กœ๊ทธ์— ์ž˜ ๋‚˜์™€์žˆ์œผ๋‹ˆ ์ฐธ๊ณ ํ•˜์‹œ๋ฉด ์ข‹์Šต๋‹ˆ๋‹ค.

  • Layered Architecture: ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์—ฌ๋Ÿฌ ์—ญํ• (๋ ˆ์ด์–ด, ๊ณ„์ธต)๋กœ ๋‚˜๋ˆ„์–ด ๊ฐ ๊ณ„์ธต์ด ํŠน์ • ์ฑ…์ž„๋งŒ์„ ๊ฐ–๊ณ  ๋™์ž‘ํ•˜๋„๋ก ํ•˜๋Š” ์„ค๊ณ„ ํŒจํ„ด
  • Domain-Driven Development(DDD): '๋น„์ฆˆ๋‹ˆ์Šค ๋„๋ฉ”์ธ(ํ•ต์‹ฌ์—…๋ฌด)'์— ์ง‘์ค‘ํ•˜์—ฌ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์„ค๊ณ„ยท๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•๋ก 
  • DDD๋Š” Layered Architecture๋ฅผ ๊ถŒ์žฅํ•˜๋ฉฐ, ์ด๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ๋„๋ฉ”์ธ ๋ชจ๋ธ์„ ์ตœ๋Œ€ํ•œ ๋ช…ํ™•ํ•˜๊ฒŒ ์œ ์ง€. ์ฆ‰, DDD์—์„œ๋Š” ์‹ค์ œ๋กœ Layered Architecture ๊ตฌ์กฐ๋ฅผ ๋”ฐ๋ผ ์†Œํ”„ํŠธ์›จ์–ด๋ฅผ ์„ค๊ณ„ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ์Œ
  • DDD๋Š” Layered Architecture๋ฅผ ์‚ฌ์šฉํ•ด ๋„๋ฉ”์ธ(๋น„์ฆˆ๋‹ˆ์Šค ๊ทœ์น™)๊ณผ ๊ธฐ์ˆ  ์„ธ๋ถ€์‚ฌํ•ญ, ์ž…์ถœ๋ ฅ ๋“ฑ์„ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„ํ•˜์—ฌ, ๋ณต์žกํ•œ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์„ ํšจ๊ณผ์ ์œผ๋กœ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•๋ก