Skip to content

Latest commit

ย 

History

History
478 lines (300 loc) ยท 21.1 KB

spring boot cache core.md

File metadata and controls

478 lines (300 loc) ยท 21.1 KB

๋ชฉ์ฐจ



๋“ค์–ด๊ฐ€๋ฉฐ

์Šคํ”„๋ง์€ ๋ฒ„์ „ 3.1๋ถ€ํ„ฐ ์บ์‹ฑ์„ ํŽธํ•˜๊ฒŒ ์ ์šฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ์ง€์›ํ•˜๊ณ  ์žˆ๋‹ค.

๊ธฐ์กด์˜ @Transactional์ฒ˜๋Ÿผ ๊ธฐ์กด ์ฝ”๋“œ์— ํฐ ๋ณ€๊ฒฝ์—†์ด ์บ์‹ฑ์„ ์ ์šฉ ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

๋‹ค์‹œ ๋งํ•ด, ์Šคํ”„๋ง์ด ํŠธ๋žœ์žญ์…˜์„ AOP๋ฅผ ์ด์šฉํ•˜์—ฌ ์ถ”์ƒํ™”์‹œํ‚จ ๊ฒƒ๊ณผ ์œ ์‚ฌํ•˜๋‹ค. (๋ฌผ๋ก  IoC๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์šฉํ•œ๋‹ค)

์บ์‹ฑ๋„ ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ์™€ AOP๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์• ๋…ธํ…Œ์ด์…˜๋งŒ ๋ถ™์—ฌ์ฃผ๋ฉด ์‰ฝ๊ฒŒ ์ ์šฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ์ถ”์ƒํ™”ํ•ด๋†“์•˜๋‹ค.

Spring Framwork 4.1 ๋ถ€ํ„ฐ๋Š” JSR-107์„ ์ค€์ˆ˜ํ•˜๋Š” ์–ด๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์„ ์–ธ์ ์ธ ์บ์‹ฑ ๊ตฌํ˜„์ด ๊ฐ€๋Šฅํ•ด์กŒ๋‹ค.

๊ธฐ๋ณธ์ ์€ ๊ฐœ๋…์— ๋Œ€ํ•œ ๋‚ด์šฉ์€ ๋ชจ๋‘ Spring Docs - Cache๋ฅผ ์ฐธ๊ณ ํ•˜์˜€๋‹ค.


์Šคํ”„๋ง ์บ์‹ฑ ์ฝ”์–ด

์ด์ œ ๋ณธ๊ฒฉ์ ์œผ๋กœ ์Šคํ”„๋ง ์บ์‹ฑ ์ฝ”์–ด์— ๋Œ€ํ•ด์„œ ๋‹ค๋ฃฌ๋‹ค.

์šฐ์„  ์Šคํ”„๋ง์—์„œ ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ์บ์‹ฑ์„ ์ฒ˜๋ฆฌํ•˜๊ณ , ์ถ”์ƒํ™” ์‹œ์ผฐ๋Š”์ง€ ์‚ดํŽด๋ณธ๋‹ค.

TIP) ๋ฒ„ํผ์™€ ์บ์‹œ์— ๋Œ€ํ•œ ์ฐจ์ด์ ์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•˜์ž.


์Šคํ”„๋ง์€ ์–ด๋–ป๊ฒŒ ์บ์‹ฑ์„ ์ฒ˜๋ฆฌํ•˜์ง€?


ํ•ต์‹ฌ์„ ๋งํ•˜์ž๋ฉด, ์Šคํ”„๋ง์€ ์บ์‹ฑ์„ ์ ์šฉํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์ถ”์ƒํ™”ํ•˜์—ฌ ์ž๋ฐ” ๋ฉ”์„œ๋“œ์— ์ ์šฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ํ•˜์˜€๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, MySQL๊ณผ ๊ฐ™์€ DB๋กœ๋ถ€ํ„ฐ ์กฐํšŒ ์ฟผ๋ฆฌ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฉ”์„œ๋“œ๊ฐ€ ์กด์žฌํ•œ๋‹ค๊ณ  ๊ฐ€์ •ํ•ด๋ณด์ž.

๊ทธ๋Ÿผ ํ•ด๋‹น ๋ฉ”์„œ๋“œ์— ์บ์‹ฑ ์• ๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ด๋ฉด AOP๋ฅผ ํ†ตํ•ด, ์บ์‹œ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์ด๋•Œ ๋งŒ์•ฝ ์บ์‹œ DB (ex. Redis)์— ์กฐํšŒํ•˜๊ณ ์žํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ๋‹ค๋ฉด ํ•ด๋‹น ํƒ€๊ฒŸ ๋ฉ”์„œ๋“œ์˜ ๋กœ์ง (์‹ค์ œ DB์— ์กฐํšŒ ์ฟผ๋ฆฌ)์€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.

์บ์‹œํ•ด๋‘” ๊ฒฐ๊ณผ๋ฅผ Proxy์—์„œ ๋ฐ˜ํ™˜ํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

๋ฌผ๋ก , ์บ์‹œ DB์— ์กฐํšŒํ•˜๊ณ ์žํ•˜๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋‹ค๋ฉด, ์‹ค์ œ DB์— ์กฐํšŒ ์ฟผ๋ฆฌ๋ฅผ ๋‚ ๋ ค ๋ฐ์ดํ„ฐ๊ฐ€ ๊ฐ€์ ธ์™€์„œ ์บ์‹œ DB์— ์ €์žฅํ›„ ๋ฐ์ดํ„ฐ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

์บ์‹ฑ ์ „๋žต์ค‘ Look aside Cache๋ฅผ ์ƒ๊ฐํ•˜๋ฉด ์ดํ•ดํ•˜๊ธฐ ์‰ฝ๋‹ค.


์ •๋ง ํŽธํ•œ ๊ฒƒ์€ ์บ์‹ฑ ์• ๋…ธํ…Œ์ด์…˜๋งŒ ๋ถ™์ด๋ฉด ์œ„์™€ ๊ฐ™์ด ์บ์‹ฑ ์ „๋žต์€ AOP๋ฅผ ํ†ตํ•ด ์ž๋™์œผ๋กœ ์ ์šฉ๋œ๋‹ค๋Š” ๊ฒƒ์ด๋‹ค.

๊ฐœ๋ฐœ์ž๋Š” ๊ทธ์ € ํ•ต์‹ฌ ๋กœ์ง (์‹ค์ œ DB๋กœ๋ถ€ํ„ฐ ๋ฐ์ดํ„ฐ ์กฐํšŒ)๋งŒ์„ ์ž‘์„ฑํ•˜๋ฉด ๋œ๋‹ค.


๋ฌผ๋ก  ์บ์‹ฑ DB์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์‹ค์ œ DB์™€ ๋™๊ธฐํ™”์‹œํ‚ค๊ธฐ ์œ„ํ•œ ๊ธฐ๋Šฅ๋„ ์ œ๊ณตํ•œ๋‹ค.

์ฆ‰, ์บ์‹ฑ DB์— ์ €์žฅ๋˜๋Š” ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜๋Š” ๊ธฐ๋Šฅ๋„ ์ œ๊ณตํ•œ๋‹ค.

์ด๋Š” ๋ฐ์ดํ„ฐ์˜ ๋ณ€๊ฒฝ์ด ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ๊ต‰์žฅํžˆ ์œ ์šฉํ•˜๊ฒŒ ์‚ฌ์šฉ๋˜๋ฉฐ, ์ด ๋˜ํ•œ ์• ๋…ธํ…Œ์ด์…˜์„ ๋ถ™์ด๋ฉด ์‰ฝ๊ฒŒ ์ ์šฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.


์‰ฝ๊ฒŒ ์–˜๊ธฐํ•ด์„œ get-if-not-found-then-proceed-and-put-eventually code blocks๋ผ๊ณ  ์ดํ•ดํ•˜๋ฉด ์‰ฝ๋‹ค.

์Šคํ”„๋ง์€ ํ”„๋ ˆ์ž„์›Œํฌ๋‹ต๊ฒŒ ๊ฐœ๋ฐœ์ž๋“ค์ด ํ•ต์‹ฌ ๋กœ์ง๋งŒ ์ž‘์„ฑํ•˜๋ฉด ์‰ฝ๊ฒŒ ๋ถ€๊ฐ€์ ์ธ ๊ธฐ๋Šฅ (ex. ํŠธ๋žœ์žญ์…˜, ์บ์‹ฑ)๋“ฑ์„ ์ ์šฉ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋„๋ก ์ถ”์ƒํ™”์‹œ์ผœ๋‘์—ˆ๋‹ค.

๋‹ค์‹œ ํ•œ๋ฒˆ, ์Šคํ”„๋ง์„ ์‚ฌ์šฉํ•˜๋ฉด์„œ ๊ด€์‹ฌ์‚ฌ์˜ ๋ถ„๋ฆฌ, ๊ฐ์ฒด์ง€ํ–ฅ ์›์น™์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ๋†’์ผ ์ˆ˜ ์žˆ์—ˆ๋‹ค.


AOP ์ฝ”๋“œ๋Š” ์–ด๋””์—?

์ด ์žฅ์€ ๊ทธ๋ƒฅ ๋„˜๊ฒจ๋„ ๋œ๋‹ค. ์ถ”ํ›„์— ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋ฉฐ ๊ธ€์„ ์ž‘์„ฑํ•  ์˜ˆ์ •์ด๋‹ค.

์ด์ œ ์Šคํ”„๋ง์ด ์ถ”์ƒ์ ์œผ๋กœ ์–ด๋–ค ๋ฐฉ์‹์„ ํ†ตํ•ด ์บ์‹ฑ์„ ์ฒ˜๋ฆฌํ•˜๋Š”์ง€๋Š” ์•Œ์•˜๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด ์‹ค์ œ๋กœ ์–ด๋–ค ๊ฐ์ฒด๋“ค์ด ์ฑ…์ž„์„ ๋‚˜๋ˆ  ๊ฐ€์ ธ๊ฐ€์„œ ์ฒ˜๋ฆฌํ•˜๋Š” ๊ฒƒ์ผ๊นŒ?


์œ„์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด, ์บ์‹ฑ ๋กœ์ง๋„ ์Šคํ”„๋ง์€ ๋ชจ๋‘ ์ถ”์ƒํ™”์‹œ์ผœ๋‘์—ˆ๋‹ค.

ํ’€์–ด ์–˜๊ธฐํ•˜์ž๋ฉด, AOP๋ฅผ ์ ์šฉ์‹œํ‚ค๊ธฐ์œ„ํ•œ Aspect, CacheAnnocationParser, CacheProxyFactoryBean๋“ฑ๋“ฑ์„ ์ถ”์ƒํ™”์‹œ์ผฐ๋‹ค.


์Šคํ”„๋ง ์บ์‹ฑ ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•˜๊ณ , @EnableCaching ์• ๋…ธํ…Œ์ด์…˜์„ ์„ ์–ธํ•ด์ฃผ๋ฉด ์ž๋™์œผ๋กœ ๊ตฌํ˜„์ฒด๊ฐ€ ์ฃผ์ž…๋œ๋‹ค.

  • CacheAspectSupport: Base class for caching aspects, such as the CacheInterceptor or an AspectJ aspect.
    • CacheInterceptor: ๊ตฌํ˜„์ฒด
  • SpringCacheAnnotationParser: Strategy implementation for parsing Spring's {@link Caching}, {@link Cacheable},
  • CacheProxyFactoryBean: Proxy factory bean for simplified declarative caching handling.

์Šคํ”„๋ง์ด ์ถ”์ƒํ™”๋ฅผ ์ž˜ ํ•ด๋‘์—ˆ๊ธฐ ๋•Œ๋ฌธ์—, ์‚ฌ์‹ค ์‚ฌ์šฉํ•˜๋Š”๋ฐ ์žˆ์–ด์„œ ์œ„์™€ ๊ฐ™์€ ์ฝ”๋“œ๋ฅผ ๋ณผ ์ผ์€ ๋งŽ์ด ์—†๋‹ค.

๊ทธ๋ž˜์„œ ์ด๋ฒˆ ๊ธ€์—์„  ๊ฐ„๋‹จํžˆ๋งŒ ๋‹ค๋ฃจ๊ณ , ์ถ”ํ›„์— ์ง์ ‘ AOP๋ฅผ ์ด์šฉํ•˜์—ฌ ์บ์‹ฑ์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ธ€์„ ์ž‘์„ฑํ•ด์„œ ๊ณต์œ ํ•  ์˜ˆ์ •์ด๋‹ค.


Cache, CacheManager

์Šคํ”„๋ง์ด ์บ์‹ฑ ๊ธฐ๋Šฅ์„ ์ž˜ ์ถ”์ƒํ™”์‹œ์ผฐ๊ณ , ๊ทธ์ € @EnableCaching์ด๋ผ๋Š” ์• ๋…ธํ…Œ์ด์…˜์„ ์„ ์–ธ๋งŒํ•ด์ฃผ๋ฉด, ์บ์‹œ ๊ด€๋ จ๋œ ์• ๋…ธํ…Œ์ด์…˜์„ ์Šค์บ”ํ•˜์—ฌ ์บ์‹ฑ ๋กœ์ง์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.


์‚ฌ์‹ค ๊ฐ€์žฅ ์ค‘์š”ํ•œ ๊ฒƒ์€ ์บ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋””์— ์ €์žฅํ•˜๋Š๋ƒ์ด๋‹ค.

๋‹ค์‹œ ๋งํ•ด, ์Šคํ”„๋ง์€ ์บ์‹œ ๊ด€๋ จ๋œ ๋กœ์ง์„ ์ œ๊ณตํ•˜์ง€๋งŒ, ์บ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋””์— ์ €์žฅํ• ์ง€๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง€์ •ํ•ด์ค˜์•ผํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด ๋ถ€๋ถ„์„ ์Šคํ”„๋ง์€ ์•„๋ž˜ ๋‘ ๊ฐ€์ง€ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ์ด์šฉํ•ด ์ถ”์ƒํ™”ํ•ด๋‘์—ˆ๋‹ค.

  • org.springframework.cache.Cache: ์บ์‹œ ๋ฐ์ดํ„ฐ์— ๋Œ€ํ•œ ์ƒ๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๋Š” ๊ฐ์ฒด.
    • is managed by Cache Manager, which manages the life cycle of Cache. Cache exists in the context of Cache Manager and is a map-like data structure that temporarily stores key-indexed values.A Cache is owned by only one CacheManager.
  • org.springframework.cache.CacheManager: ์บ์‹œ๋ฅผ ๊ด€๋ฆฌํ•ด์ฃผ๋Š” ๋งค๋‹ˆ์ €. Cache ๊ฐ์ฒด๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค.
    • Create, configure, acquire, manage, and control multiple uniquely named Caches that exist within the context of CacheManager. A CacheManager corresponds to only one CachingProvider

๋” ์ž์„ธํ•œ ์•„ํ‚คํ…์ฒ˜ ๋ถ€๋ถ„์€ ์—ฌ๊ธฐ๋ฅผ ์ฐธ๊ณ ํ•˜์ž.


์Šคํ”„๋ง์€ ์•„๋ž˜์™€ ๊ฐ™์€ ์บ์‹œ DB์˜ ๋Œ€ํ•œ ๊ตฌํ˜„์ฒด๋ฅผ ์ œ๊ณตํ•œ๋‹ค.

  • ConcurrentMapCacheManager: Java์˜ConcurrentHashMap์„ ์‚ฌ์šฉํ•ด ๊ตฌํ˜„ํ•œ ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์บ์‹œ๋งค๋‹ˆ์ €
  • SimpleCacheManager: ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜๋Š” ์บ์‹œ๊ฐ€ ์—†์–ด ์‚ฌ์šฉํ•  ์บ์‹œ๋ฅผ ์ง์ ‘ ๋“ฑ๋กํ•˜์—ฌ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์บ์‹œ๋งค๋‹ˆ์ €
  • EhCacheCacheManager: ์ž๋ฐ”์—์„œ ์œ ๋ช…ํ•œ ์บ์‹œ ํ”„๋ ˆ์ž„์›Œํฌ ์ค‘ ํ•˜๋‚˜์ธ EhCache๋ฅผ ์ง€์›ํ•˜๋Š” ์บ์‹œ ๋งค๋‹ˆ์ €
  • CompositeCacheManager: 1๊ฐœ ์ด์ƒ์˜ ์บ์‹œ ๋งค๋‹ˆ์ €๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์ง€์›ํ•ด์ฃผ๋Š” ํ˜ผํ•ฉ ์บ์‹œ ๋งค๋‹ˆ์ €
  • CaffeineCacheManager: Java 8๋กœ Guava ์บ์‹œ๋ฅผ ์žฌ์ž‘์„ฑํ•œ Caffeine ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์บ์‹œ ๋งค๋‹ˆ์ €
  • JCacheCacheManager: JSR-107 ๊ธฐ๋ฐ˜์˜ ์บ์‹œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์บ์‹œ ๋งค๋‹ˆ์ €
  • RedisCacheManager: ์บ์‹œ ์ €์žฅ์†Œ๋กœ ์œ ๋ช…ํ•œ Redis๋ฅผ ์ง€์›ํ•˜๋Š” ์บ์‹œ ๋งค๋‹ˆ์ €.

๋˜ํ•œ, ๊ฐ ์บ์‹œ ๋งค๋‹ˆ์ €๋ณ„ Cache ๊ฐ์ฒด์˜ ๊ตฌํ˜„์ฒด๋„ ์ œ๊ณตํ•œ๋‹ค.


๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๋Š” ๊ธฐ๋ณธ์œผ๋กœ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค

์Šคํ”„๋ง์˜ ์บ์‹ฑ ์ถ”์ƒํ™”๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ๋‚˜ ๋ฉ€ํ‹ฐ ํ”„๋กœ์„ธ์Šค๋ฅผ ์œ„ํ•œ ์ฒ˜๋ฆฌ๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค.

๋งŒ์•ฝ ์—ฌ๋Ÿฌ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ์บ์‹ฑ ์ฒ˜๋ฆฌ๋ฅผ ํ•˜๋ ค๊ณ  ํ•œ๋‹ค๋ฉด ๋”ฐ๋กœ ์„ค์ •ํ•ด์ค˜์•ผ ํ•œ๋‹ค. (DB Lock๊ฐ™์€ ๊ธฐ๋Šฅ์„ ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณตํ•˜์ง€ ์•Š๋Š”๋‹ค)

๊ทธ๋Ÿฌ๋ฏ€๋กœ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ™์€ ์•„์ดํ…œ๋ฅผ ์ ‘๊ทผํ•˜๊ณ  ์ˆ˜์ •ํ•˜๋ ค๊ณ ํ•˜๋ฉด, ์˜ˆ์ƒ๊ณผ ๋‹ค๋ฅด๊ฒŒ ๋™์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฌผ๋ก  sync๋ผ๋Š” ์„ค์ •์ด ์กด์žฌํ•˜์ง€๋งŒ, ๋Œ€๋ถ€๋ถ„์˜ ์บ์‹œ ์ €์žฅ์†Œ๊ฐ€ ์ด๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค. (๋ฌผ๋ก  ์ง€์›ํ•˜๋Š” ์ €์žฅ์†Œ๊ฐ€ ์žˆ์„์ˆ˜๋„...)

๋‹ค๋งŒ, ํ•„์ž ์ƒ๊ฐ์—” ์บ์‹œ ๋ฐ์ดํ„ฐ๋Š” ์„ฑ๋Šฅ์„ ๋†’์ด๊ธฐ ์œ„ํ•œ ์ž„์‹œ ๋ฐ์ดํ„ฐ์ผ ๋ฟ ํŠธ๋žœ์žญ์…˜ ๋ฝ๊ณผ ๊ฐ™์€ ์„ฑ๋Šฅ์„ ์ €ํ•˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์€ ๋งž์ง€ ์•Š๋‹ค๊ณ  ์ƒ๊ฐํ•œ๋‹ค.

๋งŒ์•ฝ ์ด๋ ‡๊ฒŒ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค๋ฉด ์ด๋Š” ์„ค๊ณ„์—์„œ ์ž˜๋ชป๋œ ๋ถ€๋ถ„์ด ์กด์žฌํ•˜์ง€ ์•Š๋‚˜์‹ถ๋‹ค.


๊ฒฐ๊ตญ ํ•ต์‹ฌ์€ ๋‘ ๊ฐ€์ง€๋‹ค - ์ค‘์š”

์Šคํ”„๋ง์—์„œ ์บ์‹ฑ์ฒ˜๋ฆฌ๋ฅผ ์ ์šฉ์‹œํ‚ค๊ธฐ์œ„ํ•ด ์‹ ๊ฒฝ์จ์•ผํ•  ๋ถ€๋ถ„์€ ์‚ฌ์‹ค ๋”ฑ ๋‘๊ฐ€์ง€์ด๋‹ค.

  • Caching declaration: Identify the methods that need to be cached and their policy.
    • ์• ๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์–ด๋–ค ๋ฉ”์„œ๋“œ๊ฐ€ ์บ์‹ฑ์ด ํ•„์š”ํ•œ์ง€, ๋˜ํ•œ ์• ๋…ธํ…Œ์ด์…˜์„ ํ†ตํ•ด ์–ด๋–ค ์บ์‹ฑ ์ •์ฑ…์„ ์‚ฌ์šฉํ• ์ง€ ์„ค์ •ํ•ด์ฃผ๋ฉด๋œ๋‹ค.
  • Cache Configuration: The backing cache where the data is stored and from which it is read.
    • ์บ์‹œํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์–ด๋””์— ์ €์žฅํ•˜๊ณ  ์ฝ์–ด์˜ฌ์ง€ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

์• ๋…ธํ…Œ์ด์…˜

์•ž์—์„œ ์–ธ๊ธ‰ํ–ˆ๋“ฏ์ด ์Šคํ”„๋ง ์บ์‹ฑ์€ ์„ ์–ธ์  ์• ๋…ธํ…Œ์ด์…˜์„ ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

๊ทธ๋Ÿฌ๋ฏ€๋กœ ๊ฐ ์• ๋…ธํ…Œ์ด์…˜์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ํ•„์š”ํ•˜๋‹ค.

  • @Cacheable: Triggers cache population. (์บ์‹œ ๋ฐ์ดํ„ฐ ์กฐํšŒ ํŠธ๋ฆฌ๊ฑฐ)
  • @CacheEvict: Triggers cache eviction. (์บ์‹œ ๋ฐ์ดํ„ฐ ์‚ญ์ œ ํŠธ๋ฆฌ๊ฑฐ)
  • @CachePut: Updates the cache without interfering with the method execution. (๋ฉ”์„œ๋“œ ์‹คํ–‰์„ ๋ฐฉํ•ดํ•˜์ง€ ์•Š๊ณ  ์บ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์—…๋ฐ์ดํŠธ)
  • @Caching: Regroups multiple cache operations to be applied on a method. (๋ฉ”์„œ๋“œ์— ์ ์šฉํ•  ์—ฌ๋Ÿฌ ์บ์‹œ ์ž‘์—…์„ ๋‹ค์‹œ ๊ทธ๋ฃนํ™”)
  • @CacheConfig: Shares some common cache-related settings at class-level. (ํด๋ž˜์Šค ๋ ˆ๋ฒจ์—์„œ ๊ณตํ†ต ์บ์‹ฑ ์„ค์ •)

@Cacheable

์ž๋ฐ” ๋ฉ”์„œ๋“œ์— @Cacheable์„ ์„ค์ •ํ•จ์œผ๋กœ์จ ํ•ด๋‹น ๋ฉ”์„œ๋“œ์˜ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹ฑํ•  ์ˆ˜ ์žˆ๋‹ค.

ํƒ€๊ฒŸ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋˜์—ˆ์„ ๋•Œ, ์บ์‹œ์— ํ•ด๋‹น ๋ฉ”์„œ๋“œ๊ฐ€ ์ด๋ฏธ ๋™์ผํ•œ ์ธ์ž๋กœ ์กด์žฌํ•œ๋‹ค๋ฉด ์บ์‹œํ•ด๋‘” ๊ฒฐ๊ณผ๋ฅผ Proxy์—์„œ ๋ฐ˜ํ™˜ํ•œ๋‹ค.

๋งŒ์•ฝ ์บ์‹ฑ์ด ํžˆํŠธ๋˜์–ด ์บ์‹ฑ์ €์žฅ์†Œ์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜จ๋‹ค๋ฉด, ํƒ€๊ฒŸ๋ฉ”์„œ๋“œ๊ฐ€ ์‹คํ–‰์กฐ์ฐจ๋˜์ง€์•Š๋Š”๋‹ค.

์บ์‹ฑํ•ด๋‘” ๋ฐ์ดํ„ฐ๊ฐ€ ์—†๋‹ค๋ฉด, ํƒ€๊ฒŸ๋ฉ”์„œ๋“œ๋ฅผ ์‹คํ–‰์‹œ์ผœ ์‹ค์ œ DB๋กœ๋ถ€ํ„ฐ ์กฐํšŒํ•˜์—ฌ ์บ์‹ฑ ์ €์žฅ์†Œ์— ์ €์žฅํ›„ ๊ฒฐ๊ณผ๋ฅผ ๋ฐ˜ํ™˜ํ•œ๋‹ค.


value, cacheNames

@Cacheable("books")
public Book findBook(ISBN isbn) {...}
  • ์บ์‹ฑ ์ „๋žต (์กฐ๊ฑด)์—†์ด ๋ชจ๋“  ์ธ์ž๋ฅผ ์บ์‹ฑํ•˜๊ณ ์žํ•œ๋‹ค๋ฉด ์œ„์™€ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋ฉด ๋œ๋‹ค.
  • books๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ์บ์‹œ์ €์žฅ์†Œ๊ฐ€ ์‚ฌ์šฉ๋œ๋‹ค.
    • ๋ฉ”์„œ๋“œ๊ฐ€ ํ˜ธ์ถœ๋  ๋•Œ ๋งค๋ฒˆ books๋ผ๋Š” ์บ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ํ™•์ธํ•œ๋‹ค.
  • ์บ์‹œ ์ €์žฅ์†Œ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋‹ค.
    • ex. @Cacheable({"books", "isbns"}) -> books์™€ isbns`๋ผ๋Š” ๋‘ ๊ตฐ๋ฐ์— ์บ์‹œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋œ๋‹ค.


Redis๋ฅผ ์ด์šฉํ•˜์—ฌ books ์บ์‹œ ์ €์žฅ์†Œ์— ์ €์žฅ์‹œํ‚จ ์˜ˆ์‹œ

Redis๋ฅผ ์ด์šฉํ•˜์—ฌ books์™€ isbns ์บ์‹œ ์ €์žฅ์†Œ์— ์ €์žฅ์‹œํ‚จ ์˜ˆ์‹œ

redis-cli๋กœ ๋ฐ์ดํ„ฐ๋ฅผ ๋ณด๊ณ ์‹ถ๋‹ค๋ฉด get books::test-isbn ํ˜น์€ get isbns::test-isbn ๋ช…๋ น์–ด๋ฅผ ์ž…๋ ฅํ•˜๋ฉด ๋œ๋‹ค.


key

์บ์‹œ๋Š” ํ•„์ˆ˜์ ์œผ๋กœ key:value ํ˜•์‹์œผ๋กœ ์ €์žฅ๋œ๋‹ค. ๊ทธ๋Ÿฌ๋ฏ€๋กœ ๊ฐ ๋ฉ”์„œ๋“œ๋งˆ๋‹ค ์–ด๋–ค key๋ฅผ ํ†ตํ•ด ์บ์‹œ ๋ฐ์ดํ„ฐ๋ฅผ ์ €์žฅํ•˜๊ณ  ์กฐํšŒํ•  ์ง€ ์„ค์ •ํ•ด์ฃผ์–ด์•ผํ•œ๋‹ค.

๋ณ„๋„์˜ ์ปค์Šคํ…€ ํ‚ค๋ฅผ ์ •์˜ํ•˜์ง€ ์•Š์œผ๋ฉด, ๋””ํดํŠธ๋กœ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๊ธฐ๋ฐ˜์˜ KeyGenerator๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ‚ค๋ฅผ ์ƒ์„ฑํ•œ๋‹ค.

๋””ํดํŠธ๋กœ ์ •์˜๋˜์–ด์žˆ๋Š” KeyGenerator๋Š” ์•„๋ž˜์™€ ๊ฐ™์ด ๋™์ž‘ํ•œ๋‹ค. (๋””ํดํŠธ๋กœ SimpleKeyGenerator๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.)

  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ์•„๋ฌด๊ฒƒ๋„ ์—†์œผ๋ฉด SimpleKey.EMPTY์„ ๋ฐ˜ํ™˜.
  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ํ•˜๋‚˜๋ฉด, ๊ทธ ์ธ์Šคํ„ด์Šค๋ฅผ ๋ฐ˜ํ™˜.
  • ๋งค๊ฐœ๋ณ€์ˆ˜๊ฐ€ ๋‘˜ ์ด์ƒ์ด๋ฉด, SimpleKey๋ฅผ ๋ฐ˜ํ™˜. (๋ชจ๋“  ๋งค๊ฐœ๋ณ€์ˆ˜์˜ Hash ๊ฐ’์œผ๋กœ ๊ณ„์‚ฐ๋œ ํ‚ค)

๊ธฐ๋ณธํ‚ค๋Š” ๋งค๊ฐœ๋ณ€์ˆ˜์˜ ๊ธฐ๋ณธ ํƒ€์ž…ํ˜•์•„๋‹ˆ๋ฉด hashCode()์™€ equals()๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ๊ณ„์‚ฐ๋œ ํ‚ค๋ฅผ ์ €์žฅํ•œ๋‹ค.

SimpleKey์•ˆ์— Object[]ํ˜•์‹์œผ๋กœ ํ‚ค๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š”๋‹ค.

์ปค์Šคํ…€ key ์ •์ฑ…์„ ์„ค์ •ํ•˜๋ ค๋ฉด org.springframework.cache.KeyGenerator ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ , CacheResolver์— ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.


์„ ์–ธ์  Custom Key ์„ค์ •

์Šคํ”„๋ง์—์„  ๊ฐ ๋ฉ”์„œ๋“œ๋งˆ๋‹ค ์‰ฝ๊ฒŒ ์›ํ•˜๋Š” key๋ฅผ ์ปค์Šคํ…€ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ ์–ธ์  ์„ค์ •๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•œ๋‹ค.

์›ํ•˜๋Š” Key๊ฐ€ ์žˆ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด SpEL์„ ์‚ฌ์šฉํ•˜๋ฉฐ ์ •์˜ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

@Cacheable(value="books", key="#isbn")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
 
 
@Cacheable(value="books", key="#isbn.rawNumber")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)
 
 
@Cacheable(value="books", key="T(someType).hash(#isbn)")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

๋งŒ์•ฝ SpEL๋กœ key์— ๋Œ€ํ•œ ์ปค์Šคํ…€ ์„ค์ •์ด ๋ณต์žกํ•ด์ง„๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์ง์ ‘ KeyGenerator๋ฅผ ๊ตฌํ˜„ํ•˜์—ฌ ์„ค์ •ํ•ด์ฃผ๋ฉด ๋œ๋‹ค.

@Cacheable(cacheNames="books", keyGenerator="myKeyGenerator")
public Book findBook(ISBN isbn, boolean checkWarehouse, boolean includeUsed)

์ฐธ๊ณ ๋กœ key์™€ keyGenerator๋Š” ์ƒํ˜ธ๋ฐฐํƒ€์ ์ด๋‹ค. ์ฆ‰, ๋‘˜์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋ฉด ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.


cacheResolver์™€ cacheManager

์Šคํ”„๋ง์—์„œ ์ถ”์ƒํ™”ํ•œ ์บ์‹ฑ์€ ๊ธฐ๋ณธ์ ์œผ๋กœ CacheResolver์—์„œ CacheManger์˜ ์„ค์ •์„ ๋ณด๊ณ  ์บ์‹œ๋ฅผ ํƒ์ƒ‰ํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ๋””ํดํŠธ๋กœ ์‚ฌ์šฉ๋˜๋Š” CacheResolver๋Š” SimpleCacheResolver์ด๋ฉฐ, ์ด ๊ตฌํ˜„์ฒด๋Š” ์„ค์ •๋œ CacheManager์— ๋”ฐ๋ผ ์บ์‹œ๋ฅผ ํƒ์ƒ‰ํ•œ๋‹ค.

๊ทธ๋ฆฌ๊ณ  ์ด๋Š” ํ•˜๋‚˜์˜ CacheManager์— ์ ํ•ฉํ•ด์„œ, ๋ณต์žกํ•œ ์„ค์ •์„ ํ•  ์ˆ˜ ์—†๋‹ค.

๋งŒ์•ฝ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์—ฌ๋Ÿฌ ๊ฐœ์˜ CacheManager๋ฅผ ์„ค์ •ํ•ด์•ผํ•œ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•ด์„œ ์‚ฌ์šฉํ•˜๋ฉด๋œ๋‹ค.

@Cacheable(cacheNames="books", cacheManager="anotherCacheManager") 
public Book findBook(ISBN isbn) {...}

๋งŒ์•ฝ CacheResolver ์ž์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

@Cacheable(cacheResolver="runtimeCacheResolver") 
public Book findBook(ISBN isbn) {...}

์ด ๋‘ ์„ค์ •๋„ ์ƒํ˜ธ๋ฒ ํƒ€์ ์œผ๋ฏ€๋กœ ํ•˜๋‚˜๋งŒ ์„ค์ •๊ฐ€๋Šฅํ•˜๋‹ค. ๋‘˜ ๋‹ค ์„ค์ •ํ•  ๊ฒฝ์šฐ ์˜ˆ์™ธ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.


condition

...์ผ๋•Œ ์บ์‹ฑ์„ ํ•ด๋ผ

SpEL์„ ์‚ฌ์šฉํ•˜์—ฌ ์บ์‹ฑ ์กฐ๊ฑด์„ ์„ค์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

  • Condition๋กœ ์ฃผ์–ด์ง„ ๊ฐ’์ด true๋ฉด ์บ์‹ฑ O
    • ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€(ํ•ต์‹ฌ ๊ฐ์ฒด)๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š๋Š”๋‹ค.
  • Condition๋กœ ์ฃผ์–ด์ง„ ๊ฐ’์ด false๋ฉด ์บ์‹ฑ X
    • ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€(ํ•ต์‹ฌ ๊ฐ์ฒด)๊ฐ€ ์‹คํ–‰๋œ๋‹ค.
@Cacheable(value="book", condition="#name.length < 32")
public Book findBook(String name)

์ด์™ธ์—๋„ SpEL์„ ์ด์šฉํ•˜์—ฌ ๋ฉ”ํƒ€ ๋ฐ์ดํ„ฐ๋ฅผ ํ™œ์šฉํ•  ์ˆ˜๋„ ์žˆ๋‹ค.

์ด์™€ ๊ด€๋ จ๋œ ๋‚ด์šฉ์€ ๊ณต์‹ ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์ž.

SpEL์— ๋Œ€ํ•œ ๋‚ด์šฉ์€ Baeldung - SpEL์™€ ๊ณต์‹ ๋ฌธ์„œ์„ ์ฐธ๊ณ ํ•˜์ž.


unless

...๋งŒ ์•„๋‹ˆ๋ฉด ์บ์‹ฑํ•˜๋ผ

condition๊ณผ ๋™์ผํ•˜๊ฒŒ ์บ์‹ฑ ์กฐ๊ฑด์„ ์„ค์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

๋‹จ, condition๊ณผ ๋‹ค๋ฅด๊ฒŒ unless๋Š” ๋ฉ”์„œ๋“œ์˜ ๊ฒฐ๊ณผ๊ฐ’ ๋ฐ˜ํ™˜ ์‹œ์ ์— ๊ฒฐ๊ณผ๊ฐ’์„ ํ™•์ธํ•˜์—ฌ ์บ์‹ฑ์—ฌ๋ถ€๋ฅผ ๊ฒฐ์ •ํ•œ๋‹ค.

๋‹ค์‹œ ๋งํ•ด, ๋ฉ”์„œ๋“œ ๋‚ด๋ถ€ (ํ•ต์‹ฌ ๊ฐ์ฒด)๊ฐ€ ํ•ญ์ƒ ์‹คํ–‰๋œ๋‹ค.

  • unless๋กœ ์ฃผ์–ด์ง„ ๊ฐ’์ด true๋ฉด ์บ์‹ฑ X
  • unless๋กœ ์ฃผ์–ด์ง„ ๊ฐ’์ด false๋ฉด ์บ์‹ฑ O
@Cacheable(value="book", condition="#name.length < 32", unless="#result.hardback")
public Book findBook(String name)
  • ๋ฉ”์„œ๋“œ ๋งค๊ฐœ๋ณ€์ˆ˜์˜ name์˜ ๊ธธ์ด๊ฐ€ 32์ด ์ดํ•˜๋ฉฐ, ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒฐ๊ณผ์˜ Optional์˜ ๊ฐ’์ด null์ด๋ฉด ์บ์‹ฑ๋˜์ง€ ์•Š๋Š”๋‹ค.
  • #result๋ฅผ ํ†ตํ•ด ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ ๊ฒฐ๊ณผ๋ฅผ ๊ฐ€์ ธ์˜ฌ ์ˆ˜ ์žˆ๋‹ค. (unless์™€ cache evict ํ‘œํ˜„์—์„œ๋งŒ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค.)
@Cacheable(value="book", condition="#name.length < 32", unless="#result == null")
public Book findBook(String name)
  • ๋ฐ˜ํ™˜๋˜๋Š” ๊ฒฐ๊ณผ๊ฐ€ null์ด๋ฉด ์บ์‹ฑํ•˜์ง€ ๋ง๋ผ๋Š” ์˜๋ฏธ.

sync

๋””ํดํŠธ๋Š” false๋‹ค.

sync = true๋กœ ์„ค์ •ํ•˜๋ฉด, ํ•ด๋‹น ๋ฉ”์„œ๋“œ๋Š” ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ์—์„œ๋งŒ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋‹ค. (๋™๊ธฐ)

@Cacheable(cacheNames="foos", sync=true) 
public Foo executeExpensiveOperation(String id) {...}

๋Œ€๋ถ€๋ถ„์˜ ์บ์‹œ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์ด๋ฅผ ์ง€์›ํ•˜์ง€ ์•Š๋Š”๋‹ค๊ณ  ํ•œ๋‹ค. (์‚ฌ์‹ค์ƒ ์บ์‹œ ์ €์žฅ์†Œ๋กœ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๊ตณ์ด ์‚ฌ์šฉํ•  ํ•„์š” ์—†์–ด๋ณด์ธ๋‹ค.)


@CachePut

@CachePut์ด ๋ถ™์€ ๋ฉ”์„œ๋“œ๋Š” ํ•ญ์ƒ ์‹คํ–‰ ๋˜๋ฉฐ, ๊ฒฐ๊ณผ๋Š” @CachePut ์˜ต์…˜์— ๋”ฐ๋ผ ์บ์‹œ์— ์ €์žฅ๋œ๋‹ค.

์ฆ‰, ์บ์‹œ๋˜์–ด์žˆ๋Š” ๋ฐ์ดํ„ฐ๊ฐ€ ์žˆ์–ด๋„, @CachePut์ด ๋ถ™์€ ๋ฉ”์„œ๋“œ๋Š” ํ•ญ์ƒ ํ˜ธ์ถœ๋˜๊ณ , ๊ทธ ๊ฒฐ๊ณผ๊ฐ€ ์บ์‹œ์— ์ €์žฅ๋œ๋‹ค.

๋ณดํ†ต ์บ์‹œ์— ์ €์žฅํ•˜๊ฑฐ๋‚˜ ์—…๋ฐ์ดํŠธ๋ฅผ ํ•ด์•ผํ•˜๋Š” ๊ฒฝ์šฐ ์‚ฌ์šฉ๋œ๋‹ค.

@CachePut(cacheNames="book", key="#isbn")
public Book updateBook(ISBN isbn, BookDescriptor descriptor)

@CachePut์€ @Cacheable๊ณผ ๋™์ผํ•œ ์˜ต์…˜์„ ์ œ๊ณตํ•œ๋‹ค. ๋‹ค๋งŒ, ์บ์‹œ์— ์ €์žฅํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค๋Š” ๋ฉ”์„œ๋“œ ํ๋ฆ„์„ ์ตœ์ ํ™”ํ•˜๋Š”๋ฐ ์‚ฌ์šฉ๋˜์–ด์•ผํ•œ๋‹ค.

ํ•œ ๋ฉ”์„œ๋“œ์— @Cacheable์™€ @CachePut์„ ํ•จ๊ป˜ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•˜์ง€ ์•Š๋Š”๋‹ค.


@CacheEvict

Evict: ์ถ•์ถœ, ์ซ—์•„๋ƒ„

@CacheEvict๋Š” @Cacheable๊ณผ ๋ฐ˜๋Œ€๋กœ, ์บ์‹œ ์ €์žฅ์†Œ์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๋ฅผ ์ง€์šธ ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค.

@CacheEvict๋„ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ์บ์‹œ๋ฅผ ๋ช…์‹œํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, key์™€ condition์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.

๋˜ํ•œ, allEntries ์†์„ฑ์„ ํ†ตํ•ด ํ‚ค๊ฐ’์œผ๋กœ Cache Entrieํ•˜๋‚˜๋งŒ ๋น„์šฐ๋Š” ๊ฒƒ์ด ์•„๋‹Œ, ์บ์‹œ ์˜์—ญ์˜ ๋ชจ๋“  Entrie๋ฅผ ๋น„์šด๋‹ค.

์ด ๊ฒฝ์šฐ์—๋Š” ํ‚ค๋ฅผ ๋ช…์‹œํ•˜๋”๋ผ๋„ ์ด๋ฅผ ๋ฌด์‹œํ•˜๊ณ  ๋ชจ๋“  Entrie๋ฅผ ๋น„์šฐ๊ฒŒ ๋œ๋‹ค.


@Caching

๋‹ค์ˆ˜์˜ ์บ์‹œ ์• ๋…ธํ…Œ์ด์…˜์„ ์“ฐ๊ณ ์ž ํ•  ๋•Œ @Caching์„ ์“ด๋‹ค. @Cacheable, @CacheEvic, @CachePut์„ ์ง€์›ํ•œ๋‹ค.

@Caching(evict = { @CacheEvict("primary"), @CacheEvict(value = "secondary", key = "#p0") })
public Book importBooks(String deposit, Date date)

์˜ˆ๋ฅผ ๋“ค์–ด ๊ฐ™์€ ๋ฉ”์„œ๋“œ์ด์ง€๋งŒ ์บ์‹œ ์ €์žฅ์†Œ์— ๋”ฐ๋ผ ๋‹ค๋ฅด๊ฒŒ ์บ์‹œ ์„ค์ •์„ ํ•ด์ค˜์•ผํ•  ๋•Œ ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ๋‹ค.


@CacheConfig

์ง€๊ธˆ๊นŒ์ง€์˜ ์„ค์ •์€ ๋Œ€๋ถ€๋ถ„ ๋ฉ”์„œ๋“œ์— ์„ค์ •ํ•ด์ฃผ๋Š” ๊ฒƒ์ด์—ˆ๋‹ค.

๋งŒ์•ฝ ํŠน์ • ํด๋ž˜์Šค์•ˆ์— ์žˆ๋Š” ๋ฉ”์„œ๋“œ ๋ชจ๋‘์— ์บ์‹œ ๊ด€๋ จ๋œ ์„ค์ •์„ ํ•œ๋ฒˆ์— ํ•˜๊ณ ์‹ถ๋‹ค๋ฉด, @CacheConfig๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด๋œ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, ํŠน์ • ํด๋ž˜์Šค์— ์žˆ๋Š” ์บ์‹œ name์„ ๋ชจ๋‘ books๋กœ ํ•˜๊ณ ์‹ถ๋‹ค๋ฉด ์•„๋ž˜์™€ ๊ฐ™์ด ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋‹ค.

@CacheConfig("books") 
public class BookRepositoryImpl implements BookRepository {

    @Cacheable
    public Book findBook(ISBN isbn) {...}
}

@CacheConfig๋ฅผ ํ†ตํ•ด ํŠน์ • ํด๋ž˜์Šค์•ˆ์— ๋ชจ๋“  ๋ฉ”์„œ๋“œ์— cacheName, CacheManager, KeyGenerator, CacheResolver๋“ฑ์„ ์„ค์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.


@CacheConfig๋Š” ํด๋ž˜์Šค ๋ ˆ๋ฒจ ์• ๋…ธํ…Œ์ด์…˜์ด๋‹ค.

๋ฌผ๋ก  ๋ฉ”์„œ๋“œ ๋ ˆ๋ฒจ๋กœ ์žฌ์ •์˜ํ•œ๋‹ค๋ฉด ํ•ด๋‹น ๋ฉ”์„œ๋“œ ๋ ˆ๋ฒจ ์• ๋…ธํ…Œ์ด์…˜์˜ ์šฐ์„  ์ˆœ์œ„๊ฐ€ ๋” ๋†’๋‹ค.


์บ์‹œ ์„ค์ • ๋ ˆ๋ฒจ

์บ์‹œ ์„ค์ •์€ ์„ธ ๊ฐ€์ง€ ๋ ˆ๋ฒจ๋กœ ๋‚˜๋‰˜๋ฉฐ, ๋‚ฎ์•„์งˆ ์ˆ˜๋ก ์˜ค๋ฒ„๋ผ์ด๋”ฉ๋œ๋‹ค. (๋‚ฎ์•„์งˆ ์ˆ˜๋ก ์šฐ์„ ์ˆœ์œ„๊ฐ€ ๋†’๋‹ค.)

  • Global ์„ค์ •.
    • @EnableCaching์ด ๋ถ™์€ Configuration์—์„œCacheManger, KeyGenerator์— ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋‹ค.
  • ํด๋ž˜์Šค ๋ ˆ๋ฒจ ์„ค์ •.
    • @CacheConfig๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.
  • ๋ฉ”์„œ๋“œ ๋ ˆ๋ฒจ ์„ค์ •.

@EnableCaching

๋งˆ์ง€๋ง‰ ์• ๋…ธํ…Œ์ด์…˜์€ ์บ์‹œ ์„ค์ • ์• ๋…ธํ…Œ์ด์…˜์ด๋‹ค.

์•„๋ฌด๋ฆฌ ์บ์‹œ ๊ด€๋ จ ์• ๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•ด์„œ ์บ์‹œ ํŠธ๋ฆฌ๊ฑฐ๋ฅผ ์„ค์ •ํ•ด๋‘์–ด๋„, ํ™œ์„ฑํ™”๋ฅผ ์‹œํ‚ค์ง€ ์•Š์œผ๋ฉด ๋™์ž‘ํ•˜์ง€ ์•Š๋Š”๋‹ค.

๋ชจ๋“  ์บ์‹ฑ ์• ๋…ธํ…Œ์ด์…˜๋ฅผ ํ™œ์„ฑํ™”์‹œํ‚ค๋ ค๋ฉด @EnableCaching์„ ์•„๋ฌด @Configuration ํด๋ž˜์Šค์— ์ถ”๊ฐ€ํ•ด์ค˜์•ผํ•œ๋‹ค.

@Configuration
@EnableCaching
public class AppConfig {
}

์ด๋Š” Global ์„ค์ •์— ์†ํ•˜๋ฉฐ, ์• ๋…ธํ…Œ์ด์…˜์˜ ์„ค์ •์„ ํ†ตํ•ด ErrorHandler, CacheManager, KeyGenerator, CacheResolver๋“ฑ์„ ์„ค์ •ํ•ด์ค„ ์ˆ˜ ์žˆ๋‹ค.

@SpringBootApplication์ด @Configuration์„ ์ƒ์†๋ฐ›์œผ๋ฏ€๋กœ, Application ์‹œ์ž‘๋ถ€๋ถ„์— ๋„ฃ๋Š” ์˜ˆ์‹œ๋„ ๋งŽ์ด ๋ดค๋‹ค.


๋งˆ์น˜๋ฉฐ

์‹œ์ž‘ํ•  ๋• ๊ณต์‹ ๋ฌธ์„œ์— ์‚ด์„ ๋” ๋ถ™์ผ ์˜ˆ์ •์ด์—ˆ์ง€๋งŒ, ๊ฑฐ์˜ ๊ณต์‹ ๋ฌธ์„œ ๋ฒˆ์—ญ์ด ๋˜์—ˆ๋‹ค...

๊ทธ๋ž˜๋„ ์ฝ๊ณ  ๋ฒˆ์—ญํ•˜๊ณ  ์ •๋ฆฌํ•˜๋ฉฐ, ์Šคํ”„๋ง ์บ์‹ฑ์— ๋Œ€ํ•ด์„œ ๋” ๊นŠ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

๋ถ€๋”” ์ด ์ž๋ฃŒ๊ฐ€ ๋ˆ„๊ตฐ๊ฐ€์—๊ฒ ๋„์›€์ด ๋˜๊ธฐ๋ฅผ..ใ…Ž