- NoSQL 데이터베이스 중 하나이며 오픈소스 소프트웨어입니다. 주요한 특징은 ‘키-값(Key-Value)’ 형태로 데이터를 저장하고 이 데이터를 ‘인-메모리 데이터 저장소’에 저장합니다.
- ‘키-값(Key-Value)’ 형태로 데이터를 저장을 하며 ‘다양한 종류의 값’을 지정 가능합니다. 값으로는 문자열, 리스트, 셋, 정렬된 셋, 해시 등을 지원합니다. - ‘인 메모리 데이터 저장소’를 사용하기에 서버의 메인 메모리에 모든 데이터를 저장하므로, 디스크 I/O를 거치는 다른 데이터베이스 시스템보다 훨씬 빠른 성능을 보여줍니다. - 메모리에 저장되는 데이터 베이스는 디스크에 저장하여 휘발성으로 사용되는 데이터를 영구적으로 저장하는 기능을 제공하여 서버가 다운되더라도 데이터를 복구할 수 있습니다. - 주로 데이터베이스, 캐시, 메시지 브로커 등 다양한 용도로 사용될 수 있습니다.
- ‘Not Only SQL’ 또는 ‘Non-Relational SQL’이라는 의미를 가지며 관계형 데이터베이스 관리 시스템(RDBMS)이 아닌 다른 형태의 데이터 저장소를 의미하며 스키마가 없거나 유연한 스키마를 가지고 있어 데이터 구조가 고정되어 있지 않습니다. 이로 인해 다양한 형태의 데이터를 저장하고 관리할 수 있습니다. - NoSQL은 대용량 분산 데이터 처리를 위해 개발되었으며 데이터의 구조적 유연성과 확장성을 제공합니다.
💡 Redis 서버를 내리고 다시 서버를 올리면 데이터가 모두 사라질까?
- Redis는 기본적으로 인-메모리 데이터 구조 저장소이기 때문에, 서버가 종료되면 메모리에 저장된 데이터는 사라집니다. - 그러나 Redis는 디스크에 데이터를 저장하는 영구 저장 기능을 제공합니다. 이 기능을 사용하면, 서버가 종료되어도 데이터를 복구할 수 있습니다. - 이 영구 저장 방식은 RDB (Redis DataBase)와 AOF (Append Only File) 두 가지 방법이 있습니다.
- Spring Data Redis를 쉽게 사용할 수 있도록 도와주는 라이브러리이며, 내장 Lettuce Client를 사용하여서 Redis의 데이터를 키-값 형태의 저장소로 이용이 가능합니다. - 이를 통해 Redis 데이터베이스에 접근하고 데이터를 저장, 조회하는 등의 작업을 수행할 수 있습니다.
- spring-boot-starter-data-redis 라이브러리 내에 내장되어 있으며 Java 환경에서 Redis를 이용하기 위한 Redis 클라이언트입니다. - 이를 사용하면 여러 Redis 명령을 비동기적으로 실행할 수 있습니다. 또한, Netty 네트워크 프레임워크를 사용하여 구현되어서 고가용성 및 확장성을 제공하며 다중 스레드 환경을 지원합니다.
특징
설명
비동기 지원
Lettuce는 비동기적으로 Redis 명령을 실행할 수 있습니다.
고가용성 및 확장성
Lettuce는 Netty 네트워크 프레임워크를 사용하여 구현되어 있어 고가용성과 확장성을 제공합니다.
- Spring Data Redis에서 제공하는 템플릿 클래스로 데이터 조작을 추상화하고 자동화해 주는 역할을 수행하여 코드의 중복을 줄여주는 클래스입니다. - 기본적으로 데이터를 읽고 쓰는데 필요한 모든 작업을 처리해 줍니다. 이 클래스를 활용하여 String, List, Set, Sorted Set, Hash 등 다양한 Redis 데이터 구조를 쉽게 다룰 수 있습니다. - 연결 관리, 직렬화/역직렬화, 예외 처리 등을 처리해 주며, 기본적인 Redis 데이터 액세스 코드를 간결하게 만들어줍니다
💡 RedisConfig - 주요 Redis를 구성하기 위한 환경설정을 위한 Configuration 클래스입니다. - 해당 클래스에서는 application.properties로부터 받아온 host, port 정보를 기반으로 Redis 클라이언트를 구성합니다. 이를 통해서 추후 Redis와의 통신에 사용됩니다.
1. RedisConnectionFactory
- Redis와의 연결을 위한 'Connection'을 생성하고 관리하는 메서드입니다. - 해당 여기서는 LettuceConnectionFactory를 사용하여 host와 port 정보를 기반으로 연결을 생성합니다.
2. RedisTemplate<String, Object>
- Redis 데이터 처리를 위한 템플릿을 구성하는 메서드입니다. 이 메서드에서는 Redis와의 데이터 통신을 처리하기 위한 직렬화를 수행합니다.
항목
설명
RedisConnectionFactory
- Spring Data Redis에서 제공하는 인터페이스. Redis 커넥션을 생성하고 관리함.
LettuceConnectionFactory
- 해당 클래스는 RedisConnectionFactory 인터페이스를 구현한 클래스입니다. - 내장 되어 있는 Lettuce 라이브러리를 사용하여 Redis 커넥션을 생성하고 관리하는데 사용됩니다. 이를 통해 Redis 서버와 비동기식 통신을 수행할 수 있습니다.
RedisTemplate
- Spring Data Redis에서 제공하는 클래스. Redis 데이터베이스에 접근하고 데이터를 처리하는 데 사용됩니다. 타입 안전성을 제공하고, 직렬화 및 역직렬화를 처리하며, Redis의 기본적인 데이터 구조를 지원합니다.
package com.adjh.springbootredis.config;
import org.springframework.beans.factory.annotation.Value;
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.lettuce.LettuceConnectionFactory;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/**
* Redis 환경 설정
*
* @author : jonghoon
* @fileName : RedisConfig
* @since : 11/2/24
*/@ConfigurationpublicclassRedisConfig {
@Value("${spring.data.redis.host}")private String host;
@Value("${spring.data.redis.port}")privateint port;
/**
* Redis 연결을 위한 'Connection' 생성합니다.
*
* @return RedisConnectionFactory
*/@Beanpublic RedisConnectionFactory redisConnectionFactory() {
returnnewLettuceConnectionFactory(host, port);
}
/**
* Redis 데이터 처리를 위한 템플릿을 구성합니다.
* 해당 구성된 RedisTemplate을 통해서 데이터 통신으로 처리되는 대한 직렬화를 수행합니다.
*
* @return RedisTemplate<String, Object>
*/@Beanpublic RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = newRedisTemplate<>();
// Redis를 연결합니다.
redisTemplate.setConnectionFactory(redisConnectionFactory());
// Key-Value 형태로 직렬화를 수행합니다.
redisTemplate.setKeySerializer(newStringRedisSerializer());
redisTemplate.setValueSerializer(newStringRedisSerializer());
// Hash Key-Value 형태로 직렬화를 수행합니다.
redisTemplate.setHashKeySerializer(newStringRedisSerializer());
redisTemplate.setHashValueSerializer(newStringRedisSerializer());
// 기본적으로 직렬화를 수행합니다.
redisTemplate.setDefaultSerializer(newStringRedisSerializer());
return redisTemplate;
}
/**
* 리스트에 접근하여 다양한 연산을 수행합니다.
*
* @return ListOperations<String, Object>
*/public ListOperations<String, Object> getListOperations() {
returnthis.redisTemplate().opsForList();
}
/**
* 단일 데이터에 접근하여 다양한 연산을 수행합니다.
*
* @return ValueOperations<String, Object>
*/public ValueOperations<String, Object> getValueOperations() {
returnthis.redisTemplate().opsForValue();
}
/**
* Redis 작업중 등록, 수정, 삭제에 대해서 처리 및 예외처리를 수행합니다.
*
* @param operation
* @return
*/publicintexecuteOperation(Runnable operation) {
try {
operation.run();
return1;
} catch (Exception e) {
System.out.println("Redis 작업 오류 발생 :: " + e.getMessage());
return0;
}
}
}
Redis 단일 데이터 값을 등록/수정합니다. duration 값이 존재하면 메모리 상 유효시간을 지정합니다.
getSingleData(String key)
String
Redis 키를 기반으로 단일 데이터의 값을 조회합니다.
deleteSingleData(String key)
int
Redis 키를 기반으로 단일 데이터의 값을 삭제합니다.
package com.adjh.springbootredis.service;
import org.springframework.stereotype.Service;
import java.time.Duration;
/**
* Redis 단일 데이터를 처리하는 비즈니스 로직 인터페이스입니다.
*/@ServicepublicinterfaceRedisSingleDataService {
intsetSingleData(String key, Object value); // Redis 단일 데이터 값을 등록/수정합니다.intsetSingleData(String key, Object value, Duration duration); // Redis 단일 데이터 값을 등록/수정합니다.(duration 값이 존재하면 메모리 상 유효시간을 지정합니다.)
String getSingleData(String key); // Redis 키를 기반으로 단일 데이터의 값을 조회합니다.intdeleteSingleData(String key); // Redis 키를 기반으로 단일 데이터의 값을 삭제합니다.
}
Redis 단일 데이터 값을 등록/수정하고, 메모리 상 유효시간을 지정합니다. 성공 시 1, 실패 시 0을 반환합니다.
getSingleData
String key
String
Redis 키를 기반으로 단일 데이터의 값을 조회합니다. 값이 없으면 빈 문자열을 반환합니다.
deleteSingleData
String key
int
Redis 키를 기반으로 단일 데이터의 값을 삭제합니다. 성공 시 1, 실패 시 0을 반환합니다.
package com.adjh.springbootredis.service.impl;
import com.adjh.springbootredis.config.RedisConfig;
import com.adjh.springbootredis.handler.RedisHandler;
import com.adjh.springbootredis.service.RedisSingleDataService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import java.time.Duration;
/**
* Redis 단일 데이터를 처리하는 비즈니스 로직 구현체입니다.
*/@Service@RequiredArgsConstructorpublicclassRedisSingleDataServiceImplimplementsRedisSingleDataService {
privatefinal RedisHandler redisHandler;
privatefinal RedisConfig redisConfig;
/**
* Redis 단일 데이터 값을 등록/수정합니다.
*
* @param key : redis key
* @param value : redis value
* @return {int} 성공(1), 실패(0)
*/@OverridepublicintsetSingleData(String key, Object value) {
return redisHandler.executeOperation(() -> redisHandler.getValueOperations().set(key, value));
}
/**
* Redis 단일 데이터 값을 등록/수정합니다.(duration 값이 존재하면 메모리 상 유효시간을 지정합니다.)
*
* @param key : redis key
* @param value: : redis value
* @param duration : redis 값 메모리 상의 유효시간.
* @return {int} 성공(1), 실패(0)
*/@OverridepublicintsetSingleData(String key, Object value, Duration duration) {
return redisHandler.executeOperation(() -> redisHandler.getValueOperations().set(key, value, duration));
}
/**
* Redis 키를 기반으로 단일 데이터의 값을 조회합니다.
*
* @param key : redis key
* @return {String} redis value 값 반환 or 미 존재시 null 반환
*/@Overridepublic String getSingleData(String key) {
if (redisHandler.getValueOperations().get(key) == null) return"";
return String.valueOf(redisHandler.getValueOperations().get(key));
}
/**
* Redis 키를 기반으로 단일 데이터의 값을 삭제합니다.
*
* @param key : redis key
* @return {int} 성공(1), 실패(0)
*/@OverridepublicintdeleteSingleData(String key) {
return redisHandler.executeOperation(() -> redisConfig.redisTemplate().delete(key));
}
}
[ 더 알아보기 ] 💡Redis에서 등록/수정/삭제를 수행하는 경우 @Transactional 어노테이션이 필요할까?
- 일반적으로 RDBMS에서 사용되는 @Transactional 어노테이션입니다. Redis의 경우 각 명령은 원자적으로 실행하기에 @Transaction 어노테이션이 필요로 하지 않습니다. 그러나 만약 여러 개의 Redis 연산을 한 트랜잭션으로 묶어야 하는 경우 @Transactional을 사용할 수 있습니다.