๐ ๋ค์ด๊ฐ๋ฉฐ
๋ฐฑ์๋ ๊ฐ๋ฐ์ ํ ๋ ๊ฐ์ฅ ์ ๊ฒฝ์ฐ๊ฒ ๋๋ ๊ฒ์ ์๋ฌด๋๋ API์ ์ฑ๋ฅ์ผ ๊ฒ์ ๋๋ค. ๋ง์ ํธ๋ํฝ์ ๋ฐ์๋ ์์ ์ ์ธ ์๋๋ก ๋์ผํ ๊ฒฐ๊ณผ๋ฅผ ์ฌ์ฉ์์๊ฒ ์ ๊ณตํด ์ฃผ์ด์ผ ํ๊ธฐ ๋๋ฌธ์ ๋๋ค. ์ด๋ฒ ํฌ์คํ ์์๋ ์ด๋ฌํ API์ ์ฑ๋ฅ์ ๋์ผ ๋ ์ฌ์ฉ๋๋ ๋ฐฉ๋ฒ์ค ํ๋์ธ ์บ์๋ฅผ ์ ์ฉํ๋ ๋ฐฉ๋ฒ์ ์์๋ณด๊ณ ์ ํฉ๋๋ค. ์บ์๋ฅผ ์ ์ฉํ๊ธฐ ์ํด Redis๋ฅผ ์ฌ์ฉํ๊ธฐ๋ ํ๋๋ฐ์ ํด๋น ํฌ์คํ ์์๋ ์คํ๋ง๋ถํธ์ ์์ฒด ์บ์(๋ก์ปฌ ์บ์)๋ฅผ ์ฌ์ฉํด ๋ณด๋๋ก ํ๊ฒ ์ต๋๋ค.
๐ ์บ์๋?
์บ์๋ ์์ฃผ ์ฌ์ฉํ๋ ๋ฐ์ดํฐ๋ฅผ ์ ์ฅํด๋๊ณ ์ฌํ์ฉํ๋ ๊ธฐ์ ์ ๋ปํฉ๋๋ค.
์ผ๋ฐ์ ์ผ๋ก ์บ์๋ ์ผ์์ ์ธ ํน์ง์ด ์๋ ๋ฐ์ดํฐ ์งํฉ์ ๊ณ ์ ๋ฐ์ดํฐ ์คํ ๋ฆฌ์ง ์ ์ฅํฉ๋๋ค.
๋ฐ๋ผ์ ์ดํ์ ํด๋น ๋ฐ์ดํฐ์ ๋ํ ๋์ผํ ์์ฒญ์ด ์์ ๊ฒฝ์ฐ,
๋ฐ์ดํฐ์ ์๋ณธ ์คํ ๋ฆฌ์ง ์์น๋ก ์ก์ธ์คํ ๋๋ณด๋ค ๋ ๋น ๋ฅด๊ฒ ์์ฒญ์ ์ฒ๋ฆฌํ ์ ์์ต๋๋ค.
์ด๋ ๊ฒ ์บ์ฑ์ ์ฌ์ฉํ๋ฉด ์ด์ ์ ๊ฒ์ํ๊ฑฐ๋ ๊ณ์ฐํ ๋ฐ์ดํฐ๋ฅผ ํจ์จ์ ์ผ๋ก ์ฌ์ฌ์ฉํ ์ ์์ต๋๋ค.
๋ถ๋ถ์ ์ผ๋ก ์ค๋ช ํ์๋ฉด,
์ผ๋ฐ์ ์ผ๋ก ๋์ผํ ๋ฆฌ์์ค ๋ํด ๋น๋ฒํ SELECT๋ก ๋ฐ์๋๋ DBMS ๊ณผ๋ถํ๋ฅผ ์ค์ด๊ณ ์ ์ฌ์ฉํฉ๋๋ค.
์ด๋ฐ ์์ผ๋ก ๊ณผ๋ถํ๋ฅผ ์ค์ด๋ฉด ๋์ ํธ๋ํฝ์ด ๊ฐ์๊ธฐ ๋ชฐ๋ฆฌ๋๋ผ๋ Web Application์ด ์ฃฝ์ง ์๊ณ ๋ฒํธ ์ ์์ต๋๋ค.
๐ Cache Manager
์บ์ ์ถ์ํ์์๋ ์บ์ ๊ธฐ์ ์ ์ง์ํ๋ ์บ์ ๋งค๋์ ๋ฅผ ๋น์ผ๋ก ๋ฑ๋กํด์ผ ํฉ๋๋ค.
์๋ ๋ CacheManager ๋ฅผ ๊ฐ์ฅ ๋ง์ด ์ฌ์ฉํ๋ฉฐ ์ด ์ค์์ CaffeineCacheManager ์ฌ์ฉ๋ฒ์ ๋ํด ์์๋ณด๊ฒ ์ต๋๋ค.
โ๏ธ EhCacheCacheManager
์๋ฐ์์ ์ ๋ช ํ ์บ์ ํ๋ ์์ํฌ ์ค ํ๋์ธ EhCache๋ฅผ ์ง์ํ๋ ์บ์ ๋งค๋์ ์ ๋๋ค.
โ๏ธ CaffeineCacheManager
Java 8๋ก Guava ์บ์๋ฅผ ์ฌ์์ฑํ Caffeine ์บ์๋ฅผ ์ฌ์ฉํ๋ ์บ์ ๋งค๋์ ์ ๋๋ค.
EhCache์ ํจ๊ป ์ธ๊ธฐ ์๋ ์บ์ ๋งค๋์ ์ธ๋ฐ, EhCache๋ณด๋ค ์ข์ ์ฑ๋ฅ์ ๊ฐ๋๋ค๊ณ ํด์ ์ต๊ทผ ๋ง์ด ์ฌ์ฉํฉ๋๋ค.
๐ CaffeineCacheManager
๋จผ์ Ehcache๋ multi-level ์บ์, distributed ์บ์, ์บ์ ๋ฆฌ์ค๋ ๋ฑ๊ณผ ๊ฐ์ ๋ง์ ๊ธฐ๋ฅ์ ์ง์ํฉ๋๋ค.
Caffeine์ Ehcache๋ณด๋ค ์บ์์ ์ฑ๋ฅ์ด ๋์ผ๋ฉฐ, ์ค์ ๋ก ๋ ์ฐ์ํ ์บ์ ์ ๊ฑฐ ์ ๋ต์ ์ฌ์ฉํฉ๋๋ค.
์ค์ ๋ก Window TinyLfu ํด์ถ ์ ์ฑ ์ ์ฌ์ฉํ๋๋ฐ, ๊ฑฐ์ ์ต์ ์ ์ ์ค๋ฅ ์ ์ ๊ณตํฉ๋๋ค.
Caffeine์ ๋ํ ๋๋ถ๋ถ์ ๊ธฐ๋ฅ์ Caffeine Wiki๋ฅผ ์ฐธ์กฐ๋ถํ๋๋ฆฝ๋๋ค.
๊ทธ๋ผ ๋ณธ๊ฒฉ์ ์ผ๋ก ์บ์๋ฅผ ์ ์ฉํด๋ณด๊ฒ ์ต๋๋ค.
์์กด์ฑ ์ถ๊ฐ build.gradle
//spring cache with caffeine
implementation 'org.springframework.boot:spring-boot-starter-cache'
implementation 'com.github.ben-manes.caffeine:caffeine'// caffeine
CacheConfig ์ถ๊ฐ
package kr.co.starbucks.config;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import kr.co.starbucks.constants.CacheType;
import org.springframework.cache.CacheManager;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.cache.caffeine.CaffeineCache;
import org.springframework.cache.support.SimpleCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@EnableCaching
@Configuration
public class CacheConfig {
@Bean
public CacheManager cacheManager() {
SimpleCacheManager cacheManager = new SimpleCacheManager();
List<CaffeineCache> caches = Arrays.stream(CacheType.values())
.map(cache -> new CaffeineCache(
cache.getName(),
Caffeine.newBuilder()
// .expireAfterWrite(cache.getExpireAfterWrite(), TimeUnit.SECONDS)
.expireAfterAccess(cache.getExpireAfterWrite(), TimeUnit.SECONDS)
.maximumSize(cache.getMaximumSize())
.recordStats()
.build()
))
.collect(Collectors.toList());
cacheManager.setCaches(caches);
return cacheManager;
}
}
๐ Creating Parameters
- initialCapacity: ๋ด๋ถ ํด์ ํ ์ด๋ธ์ ์ต์ํ์ ํฌ๊ธฐ๋ฅผ ์ค์ ํฉ๋๋ค.
- maximumSize: ์บ์์ ํฌํจํ ์ ์๋ ์ต๋ ์ํธ๋ฆฌ ์๋ฅผ ์ง์ ํฉ๋๋ค.
- maximumWeight: ์บ์์ ํฌํจํ ์ ์๋ ์ํธ๋ฆฌ์ ์ต๋ ๋ฌด๊ฒ๋ฅผ ์ง์ ํฉ๋๋ค.
- expireAfterAccess: ์บ์๊ฐ ์์ฑ๋ ํ, ํด๋น ๊ฐ์ด ๊ฐ์ฅ ์ต๊ทผ์ ๋์ฒด๋๊ฑฐ๋ ๋ง์ง๋ง์ผ๋ก ์ฝ์ ํ ํน์ ๊ธฐ๊ฐ์ด ๊ฒฝ๊ณผํ๋ฉด ์บ์์์ ์๋์ผ๋ก ์ ๊ฑฐ๋๋๋ก ์ง์ ํฉ๋๋ค.
- expireAfterWrite: ํญ๋ชฉ์ด ์์ฑ๋ ํ ๋๋ ํด๋น ๊ฐ์ ๊ฐ์ฅ ์ต๊ทผ์ ๋ฐ๋ ํ ํน์ ๊ธฐ๊ฐ์ด ์ง๋๋ฉด ๊ฐ ํญ๋ชฉ์ด ์บ์์์ ์๋์ผ๋ก ์ ๊ฑฐ๋๋๋ก ์ง์ ํฉ๋๋ค.
- refreshAfterWrite: ์บ์๊ฐ ์์ฑ๋๊ฑฐ๋ ๋ง์ง๋ง์ผ๋ก ์ ๋ฐ์ดํธ๋ ํ ์ง์ ๋ ์๊ฐ ๊ฐ๊ฒฉ์ผ๋ก ์บ์๋ฅผ ์๋ก ๊ณ ์นฉ๋๋ค.
- weakKeys: ํค๋ฅผ weak reference๋ก ์ง์ ํฉ๋๋ค. (GC์์ ํ์๋จ)
- weakValues: Value๋ฅผ weak reference๋ก ์ง์ ํฉ๋๋ค. (GC์์ ํ์๋จ)
- softValues: Value๋ฅผ soft reference๋ก ์ง์ ํฉ๋๋ค. (๋ฉ๋ชจ๋ฆฌ๊ฐ ๊ฐ๋ ์ฐผ์ ๋ GC์์ ํ์๋จ)
- recordStats: ์บ์์ ๋ํ Statics๋ฅผ ์ ์ฉํฉ๋๋ค.
โ ๏ธ expireAfterWrite ์ expireAfterAccess ๊ฐ ํจ๊ป ์ง์ ๋ ๊ฒฝ์ฐ, expireAfterWrite๊ฐ ์ฐ์ ์์๋ก ์ ์ฉ๋ฉ๋๋ค.
โ ๏ธ maximumSize์ maximumWeight๋ ํจ๊ป ์ง์ ๋ ์ ์์ต๋๋ค.
CacheType ์ ๋ํ ๊ด๋ฆฌ
package kr.co.starbucks.constants;
import com.google.common.collect.ImmutableMap;
import java.util.function.Function;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import lombok.Getter;
@Getter
public enum CacheType {
TEST("test"),
BASIC_POLICY("basic-policy"),
GIFT_TERMS("gift-terms"),
GOODS_INFO("goods-info"),
PAYMENT_POLICY("payment-policy");
private final String name;
private final int expireAfterWrite;
private final int maximumSize;
CacheType(String name) {
this.name = name;
this.expireAfterWrite = ConstConfig.DEFAULT_TTL_SEC;
this.maximumSize = ConstConfig.DEFAULT_MAX_SIZE;
}
private static final ImmutableMap<String, CacheType> codes = ImmutableMap.copyOf(
Stream.of(values()).collect(Collectors.toMap(CacheType::getName, Function.identity())));
static class ConstConfig {
static final int DEFAULT_TTL_SEC = 60;
static final int DEFAULT_MAX_SIZE = 10000;
}
}
์ค์ cache๋ฅผ ์ ์ฉํ๊ณ ์ถ์ ๋ฉ์๋์ @Cacheable ์ด๋ ธํ ์ด์ ์ ์ถ๊ฐํ์ฌ ์ ์ฉ
@Cacheable(value = "payment-policy", cacheManager = "cacheManager")
public List<PaymentPolicy> getPaymentPolicyList() {
return paymentPolicyRepository.findByUseYnAndAvailableGiftBuyYn("Y", "Y");
}
์ด๋ ๊ฒ ์ ์ฉํ๊ณ ์ค์ ํด๋น ๋ฉ์๋๋ฅผ ํธ์ถ ํด ๋ณด๋ฉด
ํ๋ฒ๋ง JPA ๊ด๋ จ ๋ก๊น (select ๋ฌธ)์ด ์ฐํ๊ณ ๊ทธ ์ดํ์๋ ์ฌ๋ฌ๋ฒ ํธ์ถํด๋
์บ์๊ฐ ์ฌ๋ผ์ง ๋๊น์ง๋select ๋ฌธ์ด ์คํ๋์ง ์๋ ๊ฒ์
ํ์ธํ ์ ์์ต๋๋ค.
์ฐธ๊ณ :
'BackEnd > SpringBoot' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
Spring Transaction ์ ๋ํ ์ดํด (0) | 2023.09.20 |
---|---|
[Spring] ์ด๋ ธํ ์ด์ ์ ์ ์์ ๋์์๋ฆฌ (0) | 2023.09.18 |
Feign Client ๋ฅผ ํ์ฉํ์ฌ ์ธ๋ถํต์ ์ฐ๋ํ๊ธฐ (0) | 2023.04.22 |
String ํํ๊ฐ ์๋ LocalDateTime๊ทธ๋๋ก ๋ฐ์๋ณด์! (1) | 2023.01.01 |
SpringBoot @Converter @Convert ๋ฐ์ดํฐ ์ฒ๋ฆฌ ์ ํ์ฉ (1) | 2022.12.11 |