diff --git a/docs/performance/Catalog_TO-BE_2.0_Redis_Cache_Performance_Report.md b/docs/performance/Catalog_TO-BE_2.0_Redis_Cache_Performance_Report.md new file mode 100644 index 0000000..7b77c97 --- /dev/null +++ b/docs/performance/Catalog_TO-BE_2.0_Redis_Cache_Performance_Report.md @@ -0,0 +1,61 @@ +# ๐Ÿ“Š [Catalog Service] Redis ์บ์‹œ ๋„์ž…์„ ํ†ตํ•œ ์ฝ๊ธฐ(Read) ์„ฑ๋Šฅ ์ตœ์ ํ™” ๋ฆฌํฌํŠธ (2์ฐจ ๋ถ€ํ•˜ํ…Œ์ŠคํŠธ) + +๋ณธ ๋ฌธ์„œ๋Š” AS-IS ์•„ํ‚คํ…์ฒ˜์—์„œ ๋ฐœ์ƒํ–ˆ๋˜ MongoDB Disk I/O ๋ณ‘๋ชฉ ํ˜„์ƒ(153 TPS ํ•œ๊ณ„)์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด **Redis ์ธ๋ฉ”๋ชจ๋ฆฌ ์บ์‹œ (Cache-Aside ํŒจํ„ด)๋ฅผ** ๋„์ž…ํ•œ ํ›„, ์นดํƒˆ๋กœ๊ทธ ์กฐํšŒ +์„ฑ๋Šฅ์ด ์–ผ๋งˆ๋‚˜ ํ–ฅ์ƒ๋˜์—ˆ๋Š”์ง€ ๊ฒ€์ฆํ•œ TO-BE ๋ฆฌํฌํŠธ์ž…๋‹ˆ๋‹ค. + +--- + +## 1. ์บ์‹œ ๋„์ž… ํ›„ ์ฝ๊ธฐ ์„ฑ๋Šฅ ์ธก์ • ๋ฐ 'Cache Warming' ํšจ๊ณผ ๋ถ„์„ + +> **ํ…Œ์ŠคํŠธ ๋ชฉ์ :** ์นดํƒˆ๋กœ๊ทธ ๋ฉ”์ธ ํ™”๋ฉด ๋ฐ ๋‹จ๊ฑด ์กฐํšŒ API์— Redis ์บ์‹œ(`@Cacheable`)๋ฅผ ์ ์šฉํ•œ ํ›„, Disk I/O ํ•œ๊ณ„๋ฅผ ๋ŒํŒŒํ•˜์—ฌ ๋ชฉํ‘œ์น˜์ธ 200 TPS๋ฅผ ์•ˆ์ •์ ์œผ๋กœ ์ƒํšŒํ•˜๋Š”์ง€ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. + +### ๐Ÿ“Œ ๋ถ€ํ•˜ํ…Œ์ŠคํŠธ ๊ฒฐ๊ณผ (JMeter) + +์ด๋ฒˆ ํ…Œ์ŠคํŠธ์—์„œ๋Š” ์บ์‹œ ์ ์ค‘ ์ƒํƒœ์— ๋”ฐ๋ผ ๋ช…ํ™•ํ•œ ์„ฑ๋Šฅ ์ฐจ์ด๊ฐ€ ๋‚˜ํƒ€๋‚˜๋Š” 'Cache Warming' ํ˜„์ƒ์ด ๋šœ๋ ทํ•˜๊ฒŒ ๊ด€์ธก๋˜์—ˆ์Šต๋‹ˆ๋‹ค. + +- **๋ถ€ํ•˜ ๊ทœ๋ชจ:** 100 Threads ๋™์‹œ ์š”์ฒญ (์ด 1,000๊ฑด ์ŠคํŒŒ์ดํฌ) +- **1์ฐจ ํƒ€๊ฒฉ ๊ฒฐ๊ณผ (Cold Cache / Partial Hit):** + - **์ฒ˜๋ฆฌ๋Ÿ‰:** `์•ฝ 394 TPS` + - ๋ถ„์„: Redis์— ๋ฐ์ดํ„ฐ๊ฐ€ ์™„์ „ํžˆ ์ ์žฌ๋˜์ง€ ์•Š์•„ ์ผ๋ถ€ ์š”์ฒญ์ด MongoDB๋กœ ํ˜๋Ÿฌ ๋“ค์–ด๊ฐ„(Cache Miss) ์ƒํƒœ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  ๊ธฐ์กด AS-IS(153 TPS) ๋Œ€๋น„ 2.5๋ฐฐ ์ด์ƒ์˜ ์„ฑ๋Šฅ์„ + ๊ธฐ๋กํ–ˆ์Šต๋‹ˆ๋‹ค. + +แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2026-05-18 แ„‹แ…ฉแ„’แ…ฎ 7 10 54 + +- **2์ฐจ ํƒ€๊ฒฉ ๊ฒฐ๊ณผ (Warm Cache / Full Hit) - ์ตœ์ข… ์ง€ํ‘œ:** + - **์ฒ˜๋ฆฌ๋Ÿ‰(Throughput):** `993.0 / sec` **(AS-IS ๋Œ€๋น„ ์•ฝ 646% ์„ฑ๋Šฅ ํ–ฅ์ƒ)** + - **ํ‰๊ท  ์ง€์—ฐ ์‹œ๊ฐ„(Average):** `25.8 ms` **(AS-IS ๋Œ€๋น„ ์•ฝ 95% ์ง€์—ฐ ์‹œ๊ฐ„ ๋‹จ์ถ•)** + - **์ตœ์†Œ / ์ตœ๋Œ€ ์ง€์—ฐ ์‹œ๊ฐ„:** `1 ms` / `170 ms` + - **์—๋Ÿฌ์œจ(Error %):** `0.0%` + +แ„‰แ…ณแ„แ…ณแ„…แ…ตแ†ซแ„‰แ…ฃแ†บ 2026-05-18 แ„‹แ…ฉแ„’แ…ฎ 7 11 05 + +### ๐Ÿ” ์„ฑ๋Šฅ ์ตœ์ ํ™” ๋ฐ ์›Œ๋ฐ(Warming) ํšจ๊ณผ ๋ถ„์„ + +1์ฐจ ํƒ€๊ฒฉ(394 TPS)์—์„œ 2์ฐจ ํƒ€๊ฒฉ(993 TPS)์œผ๋กœ์˜ ์„ฑ๋Šฅ ์ƒ์Šน์€ MSA ํ™˜๊ฒฝ์—์„œ **์บ์‹œ ์›Œ๋ฐ(Cache Warming)** ์ „๋žต์˜ ํšจ๊ณผ๋ฅผ ๋ฐ์ดํ„ฐ๋กœ ๋ณด์—ฌ์ค๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ๊ฐ€ Redis ๋ฉ”๋ชจ๋ฆฌ์— ์™„์ „ํžˆ ์บ์‹ฑ๋œ( +Full Hit) 2์ฐจ ํ…Œ์ŠคํŠธ์—์„œ๋Š” MongoDB์— ๋Œ€ํ•œ ์ถ”๊ฐ€ I/O๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š์•„, ํ‰๊ท  ์‘๋‹ต ์‹œ๊ฐ„์ด 25.8ms๋ฅผ ๊ธฐ๋กํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋Œ€๊ทœ๋ชจ ํŠธ๋ž˜ํ”ฝ์ด ์˜ˆ์ƒ๋˜๋Š” ์ด๋ฒคํŠธ(์„ ์ฐฉ์ˆœ ์˜คํ”ˆ ๋“ฑ) ๋ฐœ์ƒ ์ง์ „์— ์ฃผ์š” ๋ฐ์ดํ„ฐ๋ฅผ +๋ฉ”๋ชจ๋ฆฌ์— ๋ฏธ๋ฆฌ ์ ์žฌํ•˜๋Š” ์ „๋žต์ด ์„œ๋น„์Šค ์•ˆ์ •์„ฑ์— ์ง๊ฒฐ๋จ์„ ์‹œ์‚ฌํ•ฉ๋‹ˆ๋‹ค. + +--- + +## 2. ์„ฑ๋Šฅ ์ง€ํ‘œ ๋น„๊ต (AS-IS vs TO-BE) + +| ์ง€ํ‘œ | AS-IS (MongoDB ์ง์ ‘ ์กฐํšŒ) | TO-BE (Redis Cache Full Hit) | ๊ฐœ์„  ํšจ๊ณผ (์ฆ๊ฐ๋ฅ ) | +|:-----------------|:----------------------|:-----------------------------|:-------------------| +| **Throughput** | 153.5 TPS | **993.0 TPS** | **`+ 646% ์ˆ˜์ง ์ƒ์Šน`** | +| **Average Time** | 539 ms | **25.8 ms** | **`- 95.2% ๋‹จ์ถ•`** | +| **Max Time** | 2,153 ms | **170 ms** | **`- 92.1% ๋‹จ์ถ•`** | +| **Error Rate** | 0.0% | **0.0%** | ์œ ์ง€ (์•ˆ์ •์„ฑ ๋ณด์žฅ) | + +--- + +## 3. ์ข…ํ•ฉ ๊ฒฐ๋ก  ๋ฐ ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ ๋ฐฉ์–ด ์ „๋žต (Cache Eviction) + +1. **์••๋„์ ์ธ ์ฝ๊ธฐ ์„ฑ๋Šฅ ํ™•๋ณด:** ์ธ๋ฉ”๋ชจ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์ธ Redis๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์นดํƒˆ๋กœ๊ทธ์˜ ์ฝ๊ธฐ ๋ณ‘๋ชฉ์„ ํ•ด์†Œํ–ˆ์Šต๋‹ˆ๋‹ค. 993 TPS๋ผ๋Š” ์ˆ˜์น˜๋Š” ๋‹จ์ผ ์„œ๋น„์Šค์˜ ์„ฑ๋Šฅ ํ–ฅ์ƒ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์ด์™€ ๊ฐ™์€ ๋ฐฉ์‹์œผ๋กœ + ๊ตฌ์„ฑ๋œ API๋ฅผ ๋™๊ธฐ์ ์œผ๋กœ + ํ˜ธ์ถœํ•˜๋Š” ์˜ค๋”(Order) ์„œ๋น„์Šค์˜ ๋ณ‘๋ชฉ๊นŒ์ง€ ์—ฐ์‡„์ ์œผ๋กœ ํ•ด๊ฒฐํ•˜๋Š” ํ•ต์‹ฌ ํ‚ค๊ฐ€ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. +2. **์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ์ •ํ•ฉ์„ฑ(Consistency) ์œ ์ง€:** ์„ฑ๋Šฅ์„ ์œ„ํ•ด ์บ์‹œ๋ฅผ ๋„์ž…ํ•  ๋•Œ ๊ฐ€์žฅ ๊ฒฝ๊ณ„ํ•ด์•ผ ํ•  ๋ฌธ์ œ๋Š” ๊ณผ๊ฑฐ ๋ฐ์ดํ„ฐ๊ฐ€ ๋…ธ์ถœ๋˜๋Š” 'Stale Data' ํ˜„์ƒ์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ๋ฐฉ์–ดํ•˜๊ธฐ ์œ„ํ•ด ์ ์ฃผ๊ฐ€ ์ƒํ’ˆ ์ •๋ณด๋ฅผ + ์ˆ˜์ •ํ•˜๊ฑฐ๋‚˜(`product.updated`), ํ’ˆ์ ˆ ์ฒ˜๋ฆฌ(`product.status-changed`)๋ฅผ ํ•  ๊ฒฝ์šฐ, **Kafka ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์‹ ํ•˜์—ฌ ์ฆ‰๊ฐ์ ์œผ๋กœ ๋‹ค์ค‘ ์บ์‹œ(๋ชฉ๋ก ์บ์‹œ, ๋‹จ๊ฑด ์บ์‹œ)๋ฅผ ๋ฌดํšจํ™”( + `@CacheEvict`)ํ•˜๋„๋ก** ์„ค๊ณ„ํ–ˆ์Šต๋‹ˆ๋‹ค. + +๊ฒฐ๊ณผ์ ์œผ๋กœ Miche-Let์˜ ์นดํƒˆ๋กœ๊ทธ ์„œ๋น„์Šค๋Š” 1,000 TPS์— ์œก๋ฐ•ํ•˜๋Š” ์ฒ˜๋ฆฌ ์„ฑ๋Šฅ์„ ํ™•๋ณดํ–ˆ์œผ๋ฉฐ, Kafka ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ๋ฌดํšจํ™”๋กœ ๋ฐ์ดํ„ฐ ์ •ํ•ฉ์„ฑ ๋ฆฌ์Šคํฌ๋ฅผ ๋‚ฎ์ท„์Šต๋‹ˆ๋‹ค. +์ •ํ•ฉ์„ฑ์€ ์šด์˜ ํ™˜๊ฒฝ์—์„œ ์ด๋ฒคํŠธ ์ง€์—ฐ/๋ˆ„๋ฝ ๋ชจ๋‹ˆํ„ฐ๋ง ์ง€ํ‘œ์™€ ํ•จ๊ป˜ ์ง€์† ๊ฒ€์ฆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.