Redis는 고성능의 인메모리 데이터 구조 저장소 , 주로 캐싱 , 세션관리 , 메시지 브로커 등의 용도

인메모리 구조?
데이터가 주로 메모리에 저장되고 관리되는 데이터 베이스 시스템 , Redis는 이러한 인메모리 데이터 구조 저장소

인메모리 데이터베이스 
 - 모든 데이터를 메모리에 저장하고 읽기 때문에 매우 빠름 
 - 디스크 기반의 데이터베이스보다 훨씬 빠른 응답 제공
 - Redis는 데이터를 메모리에 저장하지만 , RDB나 AOF 방식을 통해서 디스크에 영속적으로 저장도 가능
 
ex) 
DB를 통해서 상품 정보를 사용자에게 보여주고 , 이 상품정보가 자주 변경되는 데이터가 아님
문제점 : 계속 같은 상품 조회하려고 같은 쿼리(시간 자원 소모) , 사용자가 많아지면 부하 증가 응답 속도 더 느려짐

Redis 캐싱을 이용
조회한 상품 정보를 Redis 캐시에 저장
Redis 캐시에 해당 상품 저장되어 있으므로 , db에 접근 불필요 


Redis 설정

1. 의존성 추가 코드
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-redis</artifactId>
    <version>2.6.0</version>
</dependency>
<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>3.7.1</version>
</dependency>
2. Redis 설정 파일 작성

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new JedisConnectionFactory();
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory());
        template.setKeySerializer(new StringRedisSerializer());
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        return template;
    }
}
3. 사용자 정보를 캐싱하기 위한 서비스 클래스 작성

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
public class UserService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private UserRepository userRepository; // eGov에서 DB 접근을 담당하는 DAO/Repository

    public User getUserById(Long userId) {
        String cacheKey = "user::" + userId;

        // Redis 캐시에서 조회
        User user = (User) redisTemplate.opsForValue().get(cacheKey);
        if (user != null) {
            return user;
        }

        // 캐시에 없으면 DB에서 조회
        user = userRepository.findById(userId);
        if (user != null) {
            // Redis 캐시에 저장 (예: 1시간 TTL)
            redisTemplate.opsForValue().set(cacheKey, user, 1, TimeUnit.HOURS);
        }

        return user;
    }
}

 

캐시를 먼저 조회하고 , 캐시에 없으면 데이터 베이스에서 조회하여 캐시에 저장. 

 

-> 먼저 조회를 하는 경우 속도차이가 많이 나는가? 캐시에 있는지 없는지 체크하는게 크게 차이는 없는지 궁금
-> 캐시 조회 시간 : 캐시는 메모리 내에서 데이터가 저장되기 때문에 접근 속도가 매우 빠릅니다. 일반적으로 캐시 조회 시간은 [ 마이크로초(µs) ] 단위입니다.


Redis 캐싱 장단점

- 장점
1. 성능개선 : 빠른 응답 속도 , 부하 분산
2. 비용 절감 : 쿼리 수 줄어들어 CPU와 메모리 자원 절약가능
3. 확장성 : 스케일링 Redis 캐시는 빠르게 확장 가능 DB가 처리해야 하는 트래픽을 줄여 시스템의 확장성을 높임
4. 데이터 일관성 유지 : 자주 조회되는 데이터 Redis에 캐싱하여 일관성 있는 상태를 유지

- 단점
1. 캐시 무효화 문제 : DB의 데이터가 변경되었지만 Redis의 캐시 데이터가 업데이트 되지 않는 경우가 있을 수 있음(이를 해결하기 위해 TTL 설정 필요)
2. 추가적인 복잡성 : 시스템 구성과 관리가 복잡해질 수 있고 Redis 서버의 설정 , 모니터링 , 유지보수 등등 할게 추가 됨.
3. 메모리 사용 : 메모리 사용량이 증가하여 메모리 부족이 날 수 있음(장점2하고 상충되는 것 처럼 보이는데 목적과 상황에 따라 달라질 수 있음)
4. 데이터 유실 위험 : 메모리 기반이여서 서버 장애 시 데이터 유실의 위험 그래서 RDB 스냅샷 OR AOF와 같은 영속성 옵션 설정

 

자주 사용되는 데이터만 캐시에 저장하는게 좋고 , 오래 사용하지 않는 데이터는 캐시에서 제거하는 전략이 좋음
Redis가 쿼리 수를 줄여주긴하지만 , 메모리 데이터를 저장하기 때문에 메모리가 많아지면 안되니 자주 사용하는 쿼리만 캐시에 사용되는게 좋다


디스크 기반 데이터베이스와 인메모리 데이터베이스의 차이

1. 디스크 기반 데이터베이스
일반적으로 MyBatis를 사용하여 xml을 통해 DB에 접근하는 경우, 디스크 기반 데이터베이스를 사용하는 것.
데이터가 하드 드라이브나 SSD와 같은 디스크 저장 장치에 저장 됨.


2. 인메모리 데이터베이스
데이터가 RAM(메모리)에 저장됨.
인메모리 데이터베이스는 빠른 데이터 접근 속도를 제공하지만,메모리 용량에 저장할 수 있는 데이터 양이 제한 됨.(DB 재가동 시 사라질 수 있음)

 

 - 같이 사용 가능

MyBatis와 Redis를 통합한 캐싱
Redis 서버를 설치하고 실행
MyBatis에서 캐시를 설정하여 Redis를 캐시 저장소로 사용함 , 이를 위해 설정 필요

<!-- MyBatis 캐시 설정 (mybatis-config.xml) -->
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

<!-- Mapper XML 파일 -->
<cache type="org.mybatis.caches.redis.RedisCache"/>

 

후에 자바 Config 설정으로 연동 RedisCache를 MyBatis의 캐시로 사용하도록 설정

+ Recent posts