๐จ Redis ์บ์ฑ - ixi-U/ixi-U-be GitHub Wiki
๐ ๋ฌธ์ ๋ถ์ ๋ฐ ์์ธ ํ์
- ๋ชจ๋ ์กฐํ ์์ฒญ๋ง๋ค DB/Neo4j ์ง์ ํธ์ถ
- ๋ฐ๋ณต ์กฐํ ๋ถํ๋ก ๋ ์ดํด์ ์์น
๐ ๊ฐ์ ์ ๋ต ๋ฐ ์คํ ๊ณผ์
1. Cache-Aside (Look-Aside) ํจํด ๋์
@Cacheable(cacheNames="plans", key="#โฆ")
@Cacheable(cacheNames="planCounts", key="#โฆ")
2. Redis ์ค์ ์ต์ ํ
planListPages, planCounts ๋ชจ๋ TTL 10๋ถ์ผ๋ก ์ค์
TTL 10๋ถ ์ค์ ๊ทผ๊ฑฐ
-
์๊ธ์ ๋ณ๊ฒฝ ๋น๋
- ์๊ธ์ ์ ๊ท ๋ฑ๋ก, ์์ ๋ ํ๋ฃจ ์ค์๋ ์์ฃผ ๋ฐ์ํ์ง ์์
- 10๋ถ ์ด๋ด๋ฉด ์ถฉ๋ถํ ์ต์ ๋ณ๊ฒฝ ์ฌํญ์ ๋ฐ์ํ ์ ์์ด ๋น์ฆ๋์ค ์๊ตฌ ์ถฉ์กฑ
-
์บ์ ์ ์ค๋ฅ vs. ์ ์ ๋ ๊ท ํ
- ๋๋ฌด ์งง์ผ๋ฉด ์บ์ ์ ์ค๋ฅ ์ด ๋จ์ด์ ธ DB ์กฐํ๊ฐ ์ฆ์์ง๊ณ ,
- ๋๋ฌด ๊ธธ๋ฉด ์ฌ์ฉ์์๊ฒ ์ค๋๋ ๋ฐ์ดํฐ๋ฅผ ์ ๊ณตํ ์ ์์ผ๋ฏ๋ก
- 10๋ถ์ โDB ๋ถํ ๊ฐ์โ์ โ๋ฐ์ดํฐ ๊ฐฑ์ ์์ โ ์ฌ์ด์ ์ ์ ํ ์ ์ถฉ์
3. Eviction ์ ์ฑ ์ ์ฉ
@CacheEvict(cacheNames={"planListPages","planCounts"}, allEntries=true)
- Plan ์์ฑ, ์์ ์ ์ ์ฒด ์บ์ ๋ฌดํจํ
4. ์บ์ ์ ์ฅ ๊ฐ ๋ฐ ํค ์ค๊ณ
findPlans(Pageable, GetPlansRequest)
- ์ด๋ ธํ ์ด์
@Transactional(readOnly = true)
@Cacheable(
value = "planListPages",
key = "'planListPages:' + #pageable.pageNumber + '-' +
#request.planTypeStr() + '-' +
#request.planSortOptionStr() + '-' +
#request.searchKeyword() + '-' +
(#request.planId() != null ? #request.planId() : '') + '-' +
#request.cursorSortValue()"
)
- ํค ํฌ๋งท: ์๊ธ์ ์กฐํ ์ ํ์ด์ง ๋ฒํธ, ์๊ธ์ ํ์ , ์๊ธ์ ์ ๋ ฌ ์กฐ๊ฑด, ๊ฒ์ ํค์๋, ํ์ด์ง๋ค์ด์ ์์ ํ์ํ planId, cursorSortValue๋ฅผ key๊ฐ์ผ๋ก ์ค์
planListPages:
{pageNumber}-{pageSize}-{planType}-{sortOption}-{searchKeyword}-{planId}-{cursorSortValue}
countPlans()
- ์ด๋ ธํ ์ด์
@Transactional(readOnly = true)
@Cacheable(value = "planCounts", key = "'all'")
public PlansCountResponse countPlans() {
return PlansCountResponse.from(planRepository.countPlans());
}
- ํค ํฌ๋งท: countPlans๋ ๋จ์ผ ํค๋ก ์ค์
planCounts:
all
5. ์ธ๋ฑ์ฑ ํ๋ (์๊ธ์ ํ์ ํํฐ & ์ ๋ ฌ ํ๋ ์ฌ๊ตฌ์ฑ)
CREATE INDEX plan_type_index IF NOT EXISTS FOR (p:Plan) ON (p.planType);
๐ ์ฑ๋ฅ ํ ์คํธ
ํ ์คํธ ํ๊ฒฝ
- Concurrent Users: 1,000
- Test Duration: 60์ด
- Dataset Size: ์ฝ 5,000๊ฐ ์๊ธ์
๋ถํ ์ค์ ๊ทผ๊ฑฐ
- LG U+ ์ฌ์ดํธ ์ผ์ผ ๋ฐฉ๋ฌธ์: ์ฝ 25,200๋ช
- ํ๊ท ์ธ์ (5๋ถ) ๋์์ ์์: (25,200 ร 300) รท 86,400 โ 87.5๋ช
- ํผํฌ ๊ณ์(1.52) ์ ์ฉ ์: 135~175๋ช
- ์์ ์ฑ ๊ฒ์ฆ์ ์ํด 1๋ถ 1,000๋ช ํ๊ฒฝ์ผ๋ก ์ค์
ํ ์คํธ ์๋๋ฆฌ์ค
- Baseline (Pre-Cache): ์บ์ยท์ธ๋ฑ์ค ๋ฏธ์ ์ฉ
- Optimized (With Cache): ์บ์ + ์ธ๋ฑ์ค ์ ์ฉ
โป ๋์ผํ ์ค๋ ๋, ์์ฒญ ๋น๋, ํ๋ผ๋ฏธํฐ ์กฐ๊ฑด์ผ๋ก ๋น๊ต
๊ฒฐ๊ณผ ์์ฝ
๊ตฌ๋ถ | ํ๊ท ์ง์ฐ (Avg) | P95 ์ง์ฐ | ๊ฐ์ ์จ |
---|---|---|---|
๋ชฉ๋ก ์กฐํ (Pre) | 31 ms | 38 ms | โ |
๋ชฉ๋ก ์กฐํ (With) | 6 ms | 12 ms | Avg โ80%, P95 โ68% |
๊ฐ์ ์กฐํ (Pre) | 13 ms | 18 ms | โ |
๊ฐ์ ์กฐํ (With) | 4 ms | 6 ms | Avg โ69%, P95 โ66% |
์ต์ข ๊ฒฐ๋ก
์บ์ ๋ฐ ์ธ๋ฑ์ค ์ ์ฉ์ผ๋ก ๋ชฉ๋ก ์กฐํ ํ๊ท ์๋ต์ด 31 ms โ 6 ms(80%โ), P95 38 ms โ 12 ms(68%โ), ๊ฐ์ ์กฐํ ํ๊ท 13 ms โ 4 ms(69%โ), P95 18 ms โ6 ms(66%โ) ๋ก ๋ํญ ๊ฐ์