

Future Engineering
기술의 최전선을 기록합니다.
Spring Boot와 Redis 기본 설정과 사용법
Spring Boot에서 Redia를 쉽게 연동하고 활용할 수 있도록 돕는 spring-boot-starter-data-redis의존성에 대해 사용 방법을 작성해봤습니다.
spring-boot-starter-data-redis란?
Spring Boot 환경에서 Redis를 사용하기 위한 의존성입니다. 복잡한 설정 없이 쉽게 연결할 수 있게 도와줍니다.
-
자동 구성 지원: Redis 서버와의 연결을 관리하는
RedisConnectionFactory
, 데이터 조작을 담당하는RedisTemplate
등 핵심 객체들을 자동으로 스프링 빈(Bean)으로 등록해줍니다. -
Lettuce 클라이언트 기본 내장: 현재 업계 표준으로 자리 잡은 고성용 비동기 Redis 클라이언트인 Lettuce가 기본으로 포함되어 있어, 별도의 클라이언트 라이브러리 설정이 필요 없습니다.
-
고수준 추상화 제공:
RedisTemplate
같은 템플릿 클래스를 제공하여, Redis의 다양한 데이터 타입(String, List, Hash 등)을 Java에서 객체지향적으로 편리하게 다룰 수 있도록 돕습니다.
결론적으로, 개발자는 Redis와의 연결이나 세부적인 설정에 대한 부담 없이 비즈니스 로직에 더 집중할 수 있습니다.
프로젝트 설정
의존성 추가 (Maven pom.xml)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
Redis 연결 설정
application.yml 파일에 Redis 서버 접속 정보를 설정
spring:
data:
redis:
host: localhost # Redis 서버 호스트 (기본값: localhost)
port: 6379 # Redis 서버 포트 (기본값: 6379)
password: # Redis 서버 비밀번호 (설정한 경우)
database: 0 # 사용할 데이터베이스 인덱스 (0~15, 기본값: 0)
이 설정만으로 Spring Boot 애플리케이션은 시작 시 Redis 서버와의 자동 연결됩니다.
RedisTemplate Bean 커스터마이징
Redis 연결만으로 Redis를 사용할 수 있는 건 아닙니다. RedisTemplate을 반드시 설정해야합니다.
일반적으로 config 폴더에 RedisConfig.java를 작성하면 됩니다. 이외 다양한 기능이 존재하지만 기본적으로 제공 받은 Template만 작성해놨습니다.
// src/main/java/com/example/config/RedisConfig.java
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
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 RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
RedisTemplate<String, Object> template = new RedisTemplate<>();
template.setConnectionFactory(connectionFactory);
// Key 직렬화 방식: String
template.setKeySerializer(new StringRedisSerializer());
// Value 직렬화 방식: JSON
// 객체를 JSON 형태로 저장하여 가독성을 높이고 다른 시스템과의 연동을 용이하게 함
template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
// Hash 자료구조의 Key, Value 직렬화 방식 설정
template.setHashKeySerializer(new StringRedisSerializer());
template.setHashValueSerializer(new GenericJackson2JsonRedisSerializer());
return template;
}
}
위와 같이 설정 후 간단한 캐싱 예시를 확인해보겠습니다. 게시글 조회입니다.
// src/main/java/com/example/service/PostService.java
import com.example.dto.PostDto;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import java.time.Duration;
@Slf4j
@Service
@RequiredArgsConstructor
public class PostService {
private final RedisTemplate<String, Object> redisTemplate;
private final ObjectMapper objectMapper; // Redis에서 가져온 Object를 DTO로 변환하기 위해 사용
/**
* 특정 ID의 게시글 조회 (Cache-Aside 패턴 적용)
*/
public PostDto getPostById(Long postId) {
final String key = "post::" + postId; // Redis 키 정의: "객체타입::ID"
// 1. 캐시에서 데이터 조회 시도
Object cachedPost = redisTemplate.opsForValue().get(key);
if (cachedPost != null) {
log.info("Cache Hit: post id {}", postId);
// 캐시에 데이터가 있으면 DTO로 변환하여 반환
return objectMapper.convertValue(cachedPost, PostDto.class);
}
// 2. 캐시에 데이터가 없으면 DB에서 조회 (Cache Miss)
log.info("Cache Miss: Fetching from DB for post id {}", postId);
PostDto postFromDb = findPostInDatabase(postId); // DB 조회 로직
// 3. DB에서 조회한 데이터를 캐시에 저장 (만료 시간 10분 설정)
redisTemplate.opsForValue().set(key, postFromDb, Duration.ofMinutes(10));
return postFromDb;
}
/**
* 게시글 수정 시 캐시 데이터 무효화
*/
public void updatePost(PostDto postDto) {
// 1. DB 데이터 업데이트
log.info("Updating post in DB for id {}", postDto.getId());
// ... 실제 DB 업데이트 로직 ...
// 2. 캐시 데이터 삭제 (Cache Invalidation)
// 수정된 데이터를 캐시에 바로 반영(put)할 수도 있지만,
// 정합성을 위해 삭제(evict)하는 것이 더 간단하고 안전한 전략입니다.
final String key = "post::" + postDto.getId();
redisTemplate.delete(key); // 해당 게시글 캐시 삭제
log.info("Cache evicted for post id {}", postDto.getId());
}
// --- 아래는 데이터베이스 연동을 시뮬레이션하는 더미(dummy) 메서드입니다. ---
private PostDto findPostInDatabase(Long postId) {
// 실제로는 DB에서 `SELECT * FROM posts WHERE id = ?` 쿼리를 실행합니다.
log.info("DB Query for post id {}", postId);
return new PostDto(postId, "DB에서 가져온 제목 " + postId, "DB에서 가져온 내용입니다.");
}
}
Redis Operations 살펴보기
RedisTemplate이 제공하는 다양한 자료구조입니다.
-
opsForValue()
: Strings. 가장 기본적인 Key-Value 형태. 위의 캐싱 예제에서 사용되었습니다. -
opsForList()
: Lists. 순서가 있는 데이터 목록. 메시지 큐, 타임라인 등에 활용됩니다. -
opsForSet()
: Sets. 순서가 없고 중복을 허용하지 않는 데이터 집합. 태그, 친구 목록 등에 사용됩니다. -
opsForZSet()
: Sorted Sets. Set에 Score가 추가되어 정렬된 상태를 유지. 랭킹보드, 자동완성 등에 매우 유용합니다. -
opsForHash()
: Hashes. 하나의 Key 아래에 여러 필드와 값을 저장하는 구조. 객체 정보를 저장하기에 적합합니다.