๋ณธ๋ฌธ ๋ฐ”๋กœ๊ฐ€๊ธฐ

Spring & Spring Boot

[Redis] Redis Cache๋ฅผ ํ™œ์šฉํ•ด ๋ฐ์ดํ„ฐ ์กฐํšŒ ์†๋„ ๊ฐœ์„ ํ•˜๊ธฐ - (2)

๐Ÿ“– ๋ชฉ์ฐจ

 

 

 


์ง€๋‚œ๋ฒˆ ํฌ์ŠคํŒ…์—์„œ Redis์˜ ์–ด๋–ค ํŠน์ง• ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ด ๊ฐœ์„ ๋˜๋Š”์ง€ ์•Œ์•„๋ณด์•˜๋‹ค.

 

[Redis] Redis Cache๋ฅผ ํ™œ์šฉํ•ด ๋ฐ์ดํ„ฐ ์กฐํšŒ ์†๋„ ๊ฐœ์„ ํ•˜๊ธฐ - (1)

 

[Redis] Redis Cache๋ฅผ ํ™œ์šฉํ•ด ๋ฐ์ดํ„ฐ ์กฐํšŒ ์†๋„ ๊ฐœ์„ ํ•˜๊ธฐ - (1)

๐Ÿ“– ๋ชฉ์ฐจ    SpringBoot๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด์ปค๋จธ์Šค ์„œ๋น„์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋˜ ์ค‘,์ด์ปค๋จธ์Šค์˜ ํŠน์„ฑ์ƒ ์กฐํšŒํ•˜๋Š” ์ผ์ด ๋งŽ์€๋ฐ ์„ฑ๋Šฅ์ด ์ž˜ ๋‚˜์˜ค์ง€ ์•Š๋Š”๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ๋‹ค.๋จผ์ €, Redis์˜ ์–ด๋–ค ํŠน์ง• ๋•Œ๋ฌธ์— ์„ฑ๋Šฅ์ด

zzudev.tistory.com

 

 

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” Redis ๋ช…๋ น์–ด๋ฅผ ์ง์ ‘์ ์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ ,

Spring Cache ์–ด๋…ธํ…Œ์ด์…˜์„ ์ ์šฉํ•˜์—ฌ ์กฐํšŒ ์„ฑ๋Šฅ์„ ๊ฐœ์„ ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด์ž.

 

 

 

 

 

 

 

๐Ÿ“Œ   Spring Cache ์–ด๋…ธํ…Œ์ด์…˜ ์ด์šฉํ•˜๊ธฐ 

  Spring์˜ ์บ์‹ฑ ์–ด๋…ธํ…Œ์ด์…˜์„ ์‚ฌ์šฉํ•˜๋ฉด, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ฝ”๋“œ์—์„œ ์ง์ ‘์ ์œผ๋กœ Redis ๋ช…๋ น์–ด๋ฅผ ํ˜ธ์ถœํ•˜์ง€ ์•Š์•„๋„ Redis๊ฐ€ ์ž๋™์œผ๋กœ ์‚ฌ์šฉ๋œ๋‹ค. ์บ์‹ฑ ์–ด๋…ธํ…Œ์ด์…˜์˜ ์ข…๋ฅ˜๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

 

 

 

1. @Cacheable : ๋ฉ”์†Œ๋“œ์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค.

@Service
public class UserService {

    ...

    @Cacheable(cacheNames = "cacheName", key = "#key")
    public ReturnType methodName(ParamType key) {
        // ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ๋กœ์ง
    }

    @Cacheable(cacheNames = "userCache", key = "#userId")
    public User getUserById(String userId) {
        // ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ๋กœ์ง
    }
}

 

 

  • ๋™์ผํ•œ ํ‚ค๋กœ ๋ฉ”์†Œ๋“œ๋ฅผ ๋‹ค์‹œ ํ˜ธ์ถœํ•˜๋ฉด ์บ์‹œ ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ์บ์‹œ์— ๊ฐ’์ด ์žˆ์œผ๋ฉด ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜์ง€ ์•Š๊ณ  ์บ์‹œ ๋œ ๊ฐ’์„ ๋ฐ˜ํ™˜ํ•œ๋‹ค.
  • ์บ์‹œ์— ๊ฐ’์ด ์—†์œผ๋ฉด ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค.
  • ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์กฐํšŒ์™€ ๊ฐ™์€ ์‹œ๊ฐ„์ด ๋งŽ์ด ๊ฑธ๋ฆฌ๋Š” ์ž‘์—…์˜ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹ฑํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

 

 

 

 

2. @CachePut : ๋ฉ”์†Œ๋“œ์˜ ์‹คํ–‰ ๊ฒฐ๊ณผ๋ฅผ ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค.

@Service
public class UserService {

    ...

    @CachePut(cacheNames = "cacheName", key = "#key")
    public ReturnType methodName(ParamType key) {
        // ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ๋กœ์ง
    }

    @CachePut(cacheNames = "userCache", key = "#user.id")
    public User updateUser(User user) {
        // ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ๋กœ์ง
    }
}

 

 

  • ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•œ ํ›„ ํ•ญ์ƒ ์บ์‹œ๋ฅผ ๊ฐฑ์‹ ํ•œ๋‹ค.
  • ์บ์‹œ๋ฅผ ๊ฐฑ์‹ ํ•˜์ง€๋งŒ @Cacheable๊ณผ ๋‹ฌ๋ฆฌ ๋ฉ”์†Œ๋“œ ์‹คํ–‰์„ ์ƒ๋žตํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ๋งค๋ฒˆ ๋ฉ”์†Œ๋“œ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ์ตœ์‹  ๊ฐ’์„ ์บ์‹œ์— ์ €์žฅํ•œ๋‹ค.
  • ํŠน์ • ์กฐ๊ฑด์— ๋”ฐ๋ผ ์บ์‹œ๋ฅผ ๊ฐฑ์‹ ํ•ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ์— ์‚ฌ์šฉํ•œ๋‹ค.

 

 

 

 

3. @CacheEvict : ์บ์‹œ์—์„œ ํ•˜๋‚˜ ์ด์ƒ์˜ ํ•ญ๋ชฉ์„ ์ œ๊ฑฐํ•œ๋‹ค.

@Service
public class UserService {

    ...    
    @CacheEvict(cacheNames = "cacheName", key = "#key", beforeInvocation = false)
    public void methodName(ParamType key) {
    // ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ๋กœ์ง
    }

    @CacheEvict(cacheNames = "userCache", key = "#userId", beforeInvocation = true)
    public void deleteUserById(String userId) {
        // ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ๋กœ์ง
    }
}

 

 

  • ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ํ›„ ์บ์‹œ๋ฅผ ๋น„์šด๋‹ค.
  • beforeInvocation ์†์„ฑ์„ true๋กœ ์„ค์ •ํ•˜๋ฉด ๋ฉ”์†Œ๋“œ ์‹คํ–‰ ์ „์— ์บ์‹œ๋ฅผ ๋น„์šด๋‹ค.
  • ๋ฐ์ดํ„ฐ ๋ณ€๊ฒฝ ํ›„ ์บ์‹œ๋ฅผ ๋ฌดํšจํ™”ํ•˜์—ฌ ์ผ๊ด€์„ฑ์„ ์œ ์ง€ํ•  ๋•Œ ์‚ฌ์šฉํ•œ๋‹ค.

 

 

 

 


 

 

 

 

    ์บ์‹ฑ ์–ด๋…ธํ…Œ์ด์…˜์„ ์ ์šฉํ•ด Redis์˜ ์บ์‹ฑ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•ด ๋ณด์ž. Spring์˜ ์–ด๋…ธํ…Œ์ด์…˜ ๊ธฐ๋ฐ˜์˜ ์บ์‹œ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์˜์กด์„ฑ์„ ์ถ”๊ฐ€ํ•ด์ฃผ์–ด์•ผํ•œ๋‹ค.

dependencies {
    // Spring Boot Starter for Cache
    implementation 'org.springframework.boot:spring-boot-starter-cache'

    // JSON ์ง๋ ฌํ™” ๋ฐ ์—ญ์ง๋ ฌํ™” ๊ด€๋ จ Jackson ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
    implementation 'com.fasterxml.jackson.core:jackson-databind'
    implementation 'com.fasterxml.jackson.datatype:jackson-datatype-jsr310'
}
/*
   ์ง๋ ฌํ™”: Java ๊ฐ์ฒด๋ฅผ JSON ๋ฌธ์ž์—ด๋กœ ๋ณ€ํ™˜
   ์—ญ์ง๋ ฌํ™”: JSON ๋ฌธ์ž์—ด์„ Java ๊ฐ์ฒด๋กœ ๋ณ€ํ™˜
*/

 

 

 

 

 

  ์ง€๋‚œ๋ฒˆ ๋™์‹œ์„ฑ ์ œ์–ด ํฌ์ŠคํŒ…์—์„œ Redis๊ธฐ๋ณธ ์„ธํŒ…์„ ๋งˆ์ณค๋‹ค๋Š” ๊ฐ€์ •ํ•˜์—, RedisConfig ํด๋ž˜์Šค์— ๋‹ค์Œ ๋กœ์ง์„ ์ถ”๊ฐ€ํ•ด ์ค€๋‹ค.

[Redis] Redisson์„ ์ด์šฉํ•œ ๋ถ„์‚ฐ ๋ฝ ๊ตฌํ˜„์œผ๋กœ ๋™์‹œ์„ฑ ์ด์Šˆ ํ•ด๊ฒฐ

 

[Redis] Redisson์„ ์ด์šฉํ•œ ๋ถ„์‚ฐ ๋ฝ ๊ตฌํ˜„์œผ๋กœ ๋™์‹œ์„ฑ ์ด์Šˆ ํ•ด๊ฒฐ

๐Ÿ“– ๋ชฉ์ฐจ   SpringBoot๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ์ด์ปค๋จธ์Šค ์„œ๋น„์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋ฉด์„œ ๋™์‹œ์„ฑ ์ด์Šˆ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋‹ค.Redis์˜ Redisson๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์ด์šฉํ•ด ๋™์‹œ์„ฑ ์ด์Šˆ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐฉ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์ž.                 

zzudev.tistory.com

@Configuration
public class RedisConfig {
    ...
    
    @Bean
    public RedisTemplate<String, Object> objectRedisTemplate(
        RedisConnectionFactory connectionFactory) {

        // ObjectMapper ์„ค์ • ๋กœ์ง        
        
        RedisTemplate<String, Object> template = new RedisTemplate<>();

        template.setConnectionFactory(connectionFactory);
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer(objectMapper));
        
        return template;
    }
}

 

 

 

 

 

  Cache์„ค์ •์— ๊ด€๋ จ๋œ ๋‚ด์šฉ์€ CacheConfig ํด๋ž˜์Šค์— ๋”ฐ๋กœ ๋ถ„๋ฆฌํ•ด ์ค€๋‹ค. ์บ์‹œ ์„ค์ •์„ ํ™œ์„ฑํ™”ํ•ด์ฃผ๊ธฐ ์œ„ํ•ด @EnableCaching ์–ด๋…ธํ…Œ์ด์…˜๋„ ์ถ”๊ฐ€ํ•ด ์ฃผ๋„๋ก ํ•˜์ž. ์ด๋•Œ, TTL์„ ์„ค์ •ํ•  ์ˆ˜ ์žˆ๋Š”๋ฐ, TTL(Time-To-Live)์€ ์บ์‹œ์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์œ ์ง€๋˜๋Š” ์‹œ๊ฐ„์„ ๋‚˜ํƒ€๋‚ธ๋‹ค. ์„ค์ •ํ•œ ๊ธฐ๊ฐ„์ด ์ง€๋‚˜๋ฉด ์ž๋™์œผ๋กœ ์‚ญ์ œ๋œ๋‹ค. TTL์€ ์บ์‹œ ์„ค์ •์—์„œ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ด๋ฉฐ, ๋ฐ์ดํ„ฐ์˜ ์œ ํšจ ๊ธฐ๊ฐ„์„ ๊ด€๋ฆฌํ•˜๊ณ  ๋ฉ”๋ชจ๋ฆฌ ๋˜๋Š” ๋””์Šคํฌ ๊ณต๊ฐ„์„ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐ ๋„์›€์„ ์ค€๋‹ค.

@Configuration
@EnableCaching
public class CacheConfig {

    public static final String CACHE_180_SECOND = "cache180"; // ์บ์‹œ ๋งŒ๋ฃŒ ์‹œ๊ฐ„ 3๋ถ„์œผ๋กœ ์„ค์ •

    @Bean
    public RedisCacheManager redisCacheManager(RedisConnectionFactory cf, ResourceLoader rl) {
        RedisCacheManager.RedisCacheManagerBuilder builder = RedisCacheManager.RedisCacheManagerBuilder.fromConnectionFactory(
            cf);

        // ObjectMapper ์„ค์ • ๋กœ์ง

        RedisCacheConfiguration configuration = RedisCacheConfiguration
            .defaultCacheConfig(rl.getClassLoader())
            .disableCachingNullValues()
            .serializeKeysWith(fromSerializer(new StringRedisSerializer()))
            .serializeValuesWith(
                fromSerializer(new GenericJackson2JsonRedisSerializer(objectMapper)))
            .entryTtl(Duration.ofDays(1));

        Map<String, RedisCacheConfiguration> cacheConfigurationMap = new HashMap<>();
        cacheConfigurationMap.put(CACHE_180_SECOND,
            configuration.entryTtl(Duration.ofSeconds(180L)));

        return builder.cacheDefaults(configuration)
            .withInitialCacheConfigurations(cacheConfigurationMap).build();
    }
}

 

 

 

  ๋ฐ์ดํ„ฐ์˜ ์ˆ˜์ •์ด ์ž์ฃผ ์ผ์–ด๋‚˜์ง€ ์•Š๊ณ , ๋‹จ์ˆœ ์กฐํšŒ๋ฅผ ๋นˆ๋ฒˆํ•˜๊ฒŒ ํ•˜๋Š” ์žฅ๋ฐ”๊ตฌ๋‹ˆ ๋„๋ฉ”์ธ์— @Cacheable, @CacheEvict ์–ด๋…ธํ…Œ์ด์…˜์„ ์ ์šฉํ•ด ๋ณด์ž.

@Service
@RequiredArgsConstructor
@Transactional
public class CartService {

    ...
    
    @CacheEvict(cacheNames = CACHE_180_SECOND, key = "'cart:' + #p0", beforeInvocation = false)
    public CartInfo addCart(String email, Long productId, Integer quantity) {
        // ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ƒ์„ฑ ๋กœ์ง
    }

    @CacheEvict(cacheNames = CACHE_180_SECOND, key = "'cart:' + #p0", beforeInvocation = false)
    public CartInfo updateCart(String email, Long cartId, Integer quantity) {
        // ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ƒํ’ˆ ์ˆ˜์ • ๋กœ์ง
    }

    @CacheEvict(cacheNames = CACHE_180_SECOND, key = "'cart:' + #p0", beforeInvocation = false)
    public void deleteCart(String email, Long cartId) {
        // ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ƒํ’ˆ ์‚ญ์ œ ๋กœ์ง
    }

    @Transactional(readOnly = true)
    @Cacheable(cacheNames = CACHE_180_SECOND, key = "'cart:' + #p0")
    public List<CartInfo> getCarts(String email) {
       // ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์กฐํšŒ ๋กœ์ง 
    }
}

 

โœ”๏ธ ์‚ฌ์šฉ๋œ ์บ์‹œ ์ „๋žต

  ์ฝ๊ธฐ ์ „๋žต: ์บ์‹œ๋ฅผ ๋จผ์ € ํ™•์ธํ•˜๊ณ , ์บ์‹œ์— ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์„ ๊ฒฝ์šฐ DB์—์„œ ๋ฐ์ดํ„ฐ๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” Look Aside(Lazy Loading) ์ „๋žต ์‚ฌ์šฉ.
  ์“ฐ๊ธฐ ์ „๋žต: ๋ณ€๊ฒฝ๋œ ๋‚ด์šฉ๋งŒ DB์— ๋ฐ˜์˜ํ•˜๊ณ  ํ•ด๋‹น ์บ์‹œ๋Š” ์ œ๊ฑฐ ๋˜๋Š” ๋ฌดํšจํ™”ํ•˜๋Š” Write-around์ „๋žต ์‚ฌ์šฉ.

 

 

 

 

 

  ์บ์‹œ ์–ด๋…ธํ…Œ์ด์…˜์„ ์ ์šฉํ•˜๊ณ , ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์กฐํšŒ API๋ฅผ ์‹คํ–‰ํ•ด ๋ณด๋ฉด Redis์— ๋ฐ์ดํ„ฐ๊ฐ€ ์—†์œผ๋ฏ€๋กœ ์กฐํšŒ ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์ด๋•Œ, @Cacheable์— ์˜ํ•ด Redis์— ๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋œ๋‹ค.

<์žฅ๋ฐ”๊ตฌ๋‹ˆ ์กฐํšŒ API๋ฅผ ์‹คํ–‰ํ•˜๋ฉด ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.>

 

 

 

  ๊ทธ ํ›„, ๋‹ค์‹œ ํ•œ๋ฒˆ ์กฐํšŒํ•ด ๋ณด๋ฉด ์ฟผ๋ฆฌ๋Š” ์‹คํ–‰๋˜์ง€ ์•Š๊ณ  ์บ์‹œ์—์„œ ์กฐํšŒ๊ฐ€ ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. @Cacheable์— ์˜ํ•ด Redis์—์„œ ์กฐํšŒ๊ฐ€ ์ด๋ฃจ์–ด์ง„๋‹ค. ๋˜ํ•œ, ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ˆ˜์ • ๋ฐ ์‚ญ์ œ๊ฐ€ ์ผ์–ด๋‚ฌ์„ ๊ฒฝ์šฐ์— @CacheEvict์— ์˜ํ•ด ๋ฐ์ดํ„ฐ๊ฐ€ ์‚ญ์ œ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

<redis-cli์—์„œ cache๊ฐ€ ์ €์žฅ๋˜์–ด ์กฐํšŒ๋˜๋Š” ๊ฒƒ๊ณผ ์‚ญ์ œ๋˜์–ด ์กฐํšŒ๋˜์ง€ ์•Š๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.>

 

  

 

  ์œ„์—์„œ ์„ค๋ช…ํ•œ ๋Œ€๋กœ Look Aside + Write Around  ์กฐํ•ฉ์ด ์‚ฌ์šฉ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— DB์— ์ €์žฅ๋œ ๋ฐ์ดํ„ฐ๊ฐ€ ์ˆ˜์ •, ์ถ”๊ฐ€, ์‚ญ์ œ๋  ๋•Œ๋งˆ๋‹ค ์บ์‹œ ๋˜ํ•œ ์‚ญ์ œํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค. ๋งŒ์•ฝ, ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์บ์‹œ๋ฅผ ๋น„์›Œ์ฃผ์ง€ ์•Š์œผ๋ฉด ์บ์‹œ์™€ DB์˜ ๋ฐ์ดํ„ฐ ์‚ฌ์ด์— ์ •ํ•ฉ์„ฑ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ๊ทธ๋ ‡๊ธฐ ๋•Œ๋ฌธ์— ๋ฐ์ดํ„ฐ๊ฐ€ ๋ณ€๊ฒฝ๋  ๋•Œ๋งˆ๋‹ค ์บ์‹œ๋ฅผ ์ œ๊ฑฐํ•ด ์ฃผ๋Š” ์ž‘์—…์ด ์ค‘์š”ํ•˜๋‹ค.

 

 

 


 

 

 

 

๐Ÿ“Œ   Redis Cache๋ฅผ ํ™œ์šฉํ•ด ๋ฐ์ดํ„ฐ ์กฐํšŒ ์„ฑ๋Šฅ ๊ฐœ์„ ํ•˜๊ธฐ

  ์บ์‹œ๊ฐ€ ์ €์žฅ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ–ˆ์œผ๋‹ˆ ์„ฑ๋Šฅ ๊ฐœ์„ ์ด ๋˜๋Š”์ง€ ์ง์ ‘ ํ™•์ธ์„ ํ•ด๋ณด์ž.

<10,000๊ฑด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ๊ณ  ์กฐํšŒ๋ฅผ ํ–ˆ์„ ๋•Œ์˜ ์‘๋‹ต ์†๋„ - ์บ์‹œ์—์„œ ๊ฐ€์ ธ์˜ค๊ธฐ ์ „>

 

 

 

  ์ด๋ ‡๊ฒŒ ๋Œ€๋Ÿ‰์˜ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•  ๊ฒฝ์šฐ, ์‘๋‹ต ์†๋„๊ฐ€ ์ง€์—ฐ๋˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•˜์˜€๋‹ค. ์‚ฌ์šฉ์ž๊ฐ€ ๋Š˜์–ด๋‚จ์— ๋”ฐ๋ผ ์„œ๋ฒ„์— ๊ฐ™์€ ์š”์ฒญ์ด ๋ฐ˜๋ณต์ ์œผ๋กœ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ, DB์— ๋ฌด๋ฆฌ๊ฐ€ ๊ฐ€๊ณ  ์„ฑ๋Šฅ์ด ๋–จ์–ด์งˆ ์ˆ˜ ์žˆ๋‹ค. ์บ์‹ฑ ์ฒ˜๋ฆฌ ์ „, DB์—์„œ ์กฐํšŒ ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜๊ณ  10,000๊ฑด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๊ธฐ์ค€์œผ๋กœ 4460ms์˜ ์‘๋‹ต ์†๋„๊ฐ€ ๊ฑธ๋ฆฌ๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์บ์‹ฑ์ด ์ ์šฉ๋˜์—ˆ์„ ๋•Œ ์–ผ๋งŒํผ์˜ ์ฐจ์ด๊ฐ€ ์žˆ๋Š”์ง€ ํ™•์ธํ•ด๋ณด์ž.

<10,000๊ฑด์˜ ๋ฐ์ดํ„ฐ๋ฅผ ๋„ฃ๊ณ  ์กฐํšŒ๋ฅผ ํ–ˆ์„ ๋•Œ์˜ ์‘๋‹ต ์†๋„ - ์บ์‹œ์—์„œ ๊ฐ€์ ธ์˜จ ๋ฐ์ดํ„ฐ>

 

 

 

  ์กฐํšŒ ์ฟผ๋ฆฌ๊ฐ€ ์‹คํ–‰๋˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐ์ดํ„ฐ๋ฅผ ์บ์‹œ์—์„œ ๊ฐ€์ ธ์˜ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์‘๋‹ต ์†๋„ ๋˜ํ•œ 199ms๋กœ 95.5%๊ฐ€ ๊ฐ์†Œํ•œ ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์บ์‹ฑ ์ „ํ›„์˜ ์„ฑ๋Šฅ ์ฐจ์ด๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์กฐ๊ธˆ ๋” ๋งŽ์€ ๋ฐ์ดํ„ฐ๋ฅผ ์กฐํšŒํ•˜๋Š” ์ƒํ™ฉ์—์„œ ๋น„๊ต๋ฅผ ํ•ด๋ณด์ž. 

 

<์บ์‹œ ์ ์šฉ ์ „๊ณผ ํ›„์˜ ์กฐํšŒ ์‘๋‹ต ์†๋„>

 

 

 

  ์กฐํšŒ ์‘๋‹ต ์†๋„ ์„ฑ๋Šฅ์ธก์ • ๊ฒฐ๊ณผ, ์กฐํšŒํ•˜๋Š” ๋ฐ์ดํ„ฐ์˜ ์ˆ˜๊ฐ€ ๋งŽ์•„์งˆ์ˆ˜๋ก ์‘๋‹ต์‹œ๊ฐ„์ด 5๋ฐฐ๊ฐ€๋Ÿ‰ ์ฐจ์ด๋‚˜๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ์—ˆ๋‹ค.

* ์œ„์˜ ์„ฑ๋Šฅ ๋น„๊ต๋Š” ์ „๋ถ€ ๊ฐ™์€ ํ™˜๊ฒฝ์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ ์ง„ํ–‰ํ•œ ๊ฒƒ์ด์ง€๋งŒ, ๋ณด๋‹ค ์ •ํ™•ํ•œ ์„ฑ๋Šฅ ๋น„๊ต๋ฅผ ์œ„ํ•ด์„œ๋Š” ์ƒ์„ธํ•œ ํ…Œ์ŠคํŠธ๊ฐ€ ํ•„์š”ํ•  ๊ฒƒ์ด๋‹ค.

 

 

 

 

 

 

 

  ์—ฌ๊ธฐ๊นŒ์ง€ Spring Cache ์–ด๋…ธํ…Œ์ด์…˜ ๋ฐ Redis Cache๋ฅผ ํ™œ์šฉํ•ด ๋ฐ์ดํ„ฐ ์กฐํšŒ ์†๋„๋ฅผ ๊ฐœ์„ ํ•˜๋Š” ๋ฒ•์— ๋Œ€ํ•ด ์•Œ์•„๋ณด์•˜๋‹ค.

 

 

 

 

 

๐Ÿ“Œ  ์ฐธ๊ณ 

 

Spring Cache, ์ œ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๊ธฐ

Spring Cache ์‚ฌ์šฉ๋ฒ•, Annotation ๋“ฑ์„ ์•Œ์•„๋ณด๊ณ  ์„ค์ • ๋ฐฉ์‹์„ ์•Œ์•„๋ณด๋Š” ๊ฒƒ์ด ํ•ด๋‹น ํฌ์ŠคํŒ…์˜ ๋ชฉํ‘œ์ž…๋‹ˆ๋‹ค. ๐Ÿ“Œ Spring Cache Series โœ” Spring Cache, ์ œ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๊ธฐ โœ” Caffeine Cache, ์ œ๋Œ€๋กœ ์‚ฌ์šฉํ•˜๊ธฐ 1 โœ” Caffeine Cac

gngsn.tistory.com

 

 

 

Redis ์— @Cacheable, @CachePut, @CacheEvict ์ ์šฉํ•ด๋ณด๊ธฐ

Redis ์—๋Š” ์—ฌ๋Ÿฌ๊ฐ€์ง€ ์บ์‹ฑ ๋ฐฉ๋ฒ•๋“ค์ด ์žˆ์ง€๋งŒ ์œ„ ๋ฐฉ์‹์œผ๋กœ ์ ์šฉํ•ด๋ณผ ๊ฒƒ์ด๋‹ค ์–ด๋…ธํ…Œ์ด์…˜ (์ด ์–ด๋…ธํ…Œ์ด์…˜๋“ค์€ ...

blog.naver.com

 

 

[Spring + Redis] Redis cache๋ฅผ ์ ์šฉํ•ด ์กฐํšŒ ์„ฑ๋Šฅ ๊ฐœ์„  ๋ฐฉ๋ฒ•

๋‚ด ํ”„๋กœ์ ํŠธ์—์„œ๋Š” ์‚ฌ์šฉ์ž๋ณ„๋กœ ์‚ฌ์ด๋“œ๋ฐ”์— ์ฐœ ์ˆ˜, ์žฅ๋ฐ”๊ตฌ๋‹ˆ ์ˆ˜๋“ค์„ ์นด์šดํŠธ ์ฟผ๋ฆฌ๋กœ ๋ฐ˜ํ™˜๋œ ๋ฐ์ดํ„ฐ ์ˆ˜๋ฅผ view์— ๋ฟŒ๋ ค์ฃผ๋Š”๋ฐ, ์ด ์‚ฌ์ด๋“œ๋ฐ”๋Š” ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€์—์„œ ๋…ธ์ถœ๋˜์–ด ํŽ˜์ด์ง€ ์ด๋™๋งˆ๋‹ค ์นด์šดํŠธ ์ฟผ

hstory0208.tistory.com

 

 

 

Spring Boot์™€ Redis๋กœ ์บ์‹ฑ ๊ตฌํ˜„ํ•˜๊ธฐ | ์š”์ฆ˜IT

์บ์‹ฑ์€ ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋น„์šฉ์„ ์ค„์ด๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉ๋˜๋Š” ๊ธฐ๋ฒ•์œผ๋กœ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ๋ฐ์ดํ„ฐ ์กฐํšŒ ์ž‘์—…์—์„œ ์ž์ฃผ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฒˆ ๊ธ€์—์„œ๋Š” ์บ์‹œ๋ฅผ ๊ตฌํ˜„ํ•˜๊ธฐ์— ์•ž์„œ ์‚ฌ์ „์— ์•Œ์•„๋‘๋ฉด ์ข‹์„ ๋งŒํ•œ ์บ์‹œ

yozm.wishket.com