ballqs 님의 블로그
[Spring] Redis 적용 (Window 환경) 본문
Redis 공부해야지 공부해야지 생각만 했었는데 이제서야 들여다보면서 알아보고 적용해보았다.
작성하는데 도움이 된 참조글 : https://akku-dev.tistory.com/102
Redis란?
Remote Dictionary Server의 약자로, 오픈 소스 기반의 인메모리 데이터 구조 저장소이다.
데이터베이스, 캐시, 메시지 브로커 등의 용도로 사용할 수 있고 Redis는 매우 빠른 속도로 데이터를 처리할 수 있어 성능이 중요한 애플리케이션에 많이 사용된다.
Redis 특징
- 인메모리 저장소: Redis는 데이터를 메모리(RAM)에 저장하여 빠른 읽기 및 쓰기 성능을 제공한다. 이 덕분에 캐싱 서버나 세션 저장소로 많이 활용된다.
- 다양한 자료 구조 지원: 일반적인 키-값(Key-Value) 구조뿐만 아니라, 다음과 같은 다양한 자료 구조를 지원한다.
- 문자열(String)
- 리스트(List)
- 셋(Set)
- 정렬된 셋(Sorted Set)
- 해시(Hash)
- 비트맵(Bitmap), 하이퍼로그로그(HyperLogLog), 스트림(Stream) 등
- 데이터 영속성: Redis는 주로 인메모리 방식으로 동작하지만, 데이터를 영구 저장하기 위한 옵션도 제공한다. 이를 위해 두 가지 방식의 영속성을 지원한다.
- RDB (Redis Database): 주기적으로 데이터를 디스크에 덤프하는 방식.
- AOF (Append Only File): 모든 쓰기 작업을 로그 파일에 기록하는 방식.
- 빠른 성능: Redis는 메모리 기반이고, 싱글 스레드로 동작하지만 비동기 I/O를 사용하여 매우 높은 처리 속도를 제공한다. 10만 이상의 요청을 초당 처리할 수 있는 성능이 특징을 가지고 있다.
- 복제 및 클러스터링: Redis는 마스터-슬레이브 구조의 복제(replication)를 지원하여 데이터의 고가용성을 보장한다. 또한, Redis 클러스터링 기능을 통해 여러 Redis 인스턴스에 데이터를 분산 저장할 수 있다.
- 원자성: Redis는 모든 명령어가 원자적으로 실행된다. 즉, 하나의 명령어가 실행되면 다른 명령어가 그 중간에 끼어들 수 없다는 의미! 또한, Redis는 트랜잭션 기능도 지원하며, 여러 명령어를 하나의 단위로 묶어 실행할 수 있는 MULTI/EXEC 명령어를 제공한다.
Window 환경에서의 Redis를 사용할 수 있도록 하는 방법
WSL install
wsl --install
redis라는 글을 쓰기 전에 테스트해볼때 스크린샷을 찍지 못해서 설치를 하게 된다면 아래와 같이 나올 것이다.
안내문구에 따라 컴퓨터를 재시작해주면 ubuntu가 설치되며 자동으로 실행 된다.
ubuntu가 실행되면 해당 os의 명을 어떻게 할지 비밀번호도 설정하라는 안내가 뜨는데 설정하면 이와 같이 나온다.
Docker install
curl -fsSL https://get.docker.com/ | sudo sh
sudo usermod -aG docker `whoami`
Docker 에 redis 받아오기
docker run --name redis -p 6379:6379 -d redis:6-alpine
이렇게 하면 Docker가 설치가 완료된다.
redis-cli 접속
// redis로 해서 접근이 되는 이유 : -name redis로 해놓았기에 해당 docker의 이름이다.
docker exec -it redis sh
접속이 안되는 경우!
docker 리스트 확인하는 명령어 : docker ps -a
docker의 상태를 확인하여 실행하자!
docker 실행하기 : docker container start [CONTAINER ID]
docker 재실행하기 : docker container restart [CONTAINER ID]
docker 중지하기 : docker container stop [CONTAINER ID]
docker 삭제하기 : docker container rm [CONTAINER ID]
[CONTAINER ID] 를 다 작성하지 않은 이유!!
docker list 내에서 내가 작성한 값이 일치하는게 1개이면 알아서 그 docker라고 인식이 되기에 실행하는데 지장없다.
redis-cli 명령어
redis-cli
redis의 간단한 명령어
명령어 | 설명 |
FLUSHDB | 데이터 모두 삭제 |
KEYS * | 모든 키 검색 |
SET [key] [data] | [key] 값에 [data]에 삽입 |
GET [key] | [key] 조회 |
DEL [key] | [key] 삭제 |
TYPE [key] | [key]의 TYPE 조회 리스트 : LRANGE , LINDEX 해시 : HGET , HGETALL 셋 : SMEMBERS |
HGETALL [key] | 해시일때 [key] 를 통해 데이터 가져오는 방법 |
Spring boot 적용
gradle 추가
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
application.properties 추가
# redis
spring.data.redis.host=localhost
spring.data.redis.port=6379
Configuration 작성
@Configuration
public class RedisConfig {
@Value("${spring.data.redis.host}")
private String host;
@Value("${spring.data.redis.port}")
private int port;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisStandaloneConfiguration redisConfiguration = new RedisStandaloneConfiguration();
redisConfiguration.setHostName(host);
redisConfiguration.setPort(port);
return new LettuceConnectionFactory(redisConfiguration);
}
@Primary
@Bean
public RedisTemplate<String, String> redisTemplate() {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
return redisTemplate;
}
}
추가 설명!
RedisConnectionFactory redisConnectionFactory()
- 이 메서드는 Redis와의 연결을 관리하는 공장 클래스인 RedisConnectionFactory를 반환합니다.
- RedisStandaloneConfiguration을 사용해 단일 인스턴스의 Redis 서버에 대한 구성을 설정합니다. 여기에서 호스트와 포트 정보를 설정합니다.
- LettuceConnectionFactory는 Lettuce 클라이언트를 이용해 Redis와의 연결을 관리합니다. Lettuce는 널리 사용되는 Redis 클라이언트 중 하나입니다.
- 이 부분은 Redis와의 물리적 연결을 생성하고 관리하는 역할을 합니다.
RedisTemplate<String, String> redisTemplate()
- RedisTemplate은 Redis에 데이터를 저장하고 가져올 때 사용하는 주요 도구입니다. 이 템플릿은 Redis와의 상호작용을 위한 다양한 메서드(예: set, get, delete 등)를 제공합니다.
- 이 메서드는 RedisTemplate 객체를 생성하고, 이 객체를 사용하여 Redis에 키-값(String, String)의 형태로 데이터를 저장하고 조회할 수 있습니다.
설정된 사항:
- ConnectionFactory: Redis와의 실제 연결을 관리하는 redisConnectionFactory()를 설정합니다.
- KeySerializer: Redis에서 사용하는 키를 문자열로 직렬화하기 위한 StringRedisSerializer로 설정합니다.
- ValueSerializer: Redis에서 사용하는 값을 문자열로 직렬화하기 위한 StringRedisSerializer로 설정합니다.
- 이는 기본적으로 모든 데이터가 문자열로 처리된다는 것을 의미합니다.
Controller 작성
@RestController
@RequiredArgsConstructor
@RequestMapping("/redis")
public class RedisController {
private final RedisService redisService;
@PostMapping
public void createRedis() {
redisService.createRedis();
}
@DeleteMapping
public void deleteRedis() {
redisService.deleteRedis();
}
}
Service 작성
@Service
@RequiredArgsConstructor
public class RedisService {
private final RedisRepository redisRepository;
public void createRedis() {
redisRepository.save(new UserVo("id", "Daniel", "New York")); // 저장
// 값 제대로 저장되었는지 확인
Optional<UserVo> result = redisRepository.findById("id"); // 불러오기
if(result.isPresent()) {
UserVo userVo = result.get();
System.out.println(userVo.getName());
}
}
public void deleteRedis() {
Optional<UserVo> result = redisRepository.findById("id"); // 불러오기
if(result.isPresent()) {
redisRepository.deleteById("id"); // 삭제
UserVo userVo = result.get();
System.out.println(userVo.getId());
System.out.println(userVo.getName());
System.out.println(userVo.getAddress());
}
}
}
Repository 작성
public interface RedisRepository extends CrudRepository<UserVo , String> {
}
※JpaRepository가 아닌 CrudRepository를 사용한 이유
CrudRepository vs JpaRepository
- CrudRepository: 기본적인 CRUD(Create, Read, Update, Delete) 작업을 처리하는 메서드를 제공합니다. findAll(), save(), delete() 같은 기본적인 데이터 접근 작업에 적합합니다.
- JpaRepository: CrudRepository를 확장하며, 추가적으로 JPA에 특화된 기능을 제공합니다. 예를 들어, 페이징 및 정렬 기능을 제공하는 findAll(Pageable pageable) 등의 메서드를 포함합니다. 또한 더 많은 JPA 관련 기능을 사용할 수 있습니다.
Redis에서는 CrudRepository?
Redis는 일반적으로 비관계형(NoSQL) 데이터베이스로, JPA가 제공하는 관계형 데이터베이스에 맞춘 기능들은 불필요할 수 있습니다. Redis에서는 단순한 CRUD 작업이 주로 사용되므로, CrudRepository를 사용하는 것이 더 적합할 수 있습니다. 물론 Redis를 더 복잡하게 활용하고 싶다면 상황에 맞게 다른 인터페이스나 커스텀 기능을 추가할 수도 있습니다.
따라서 Redis에서는 CrudRepository만으로도 충분한 경우가 많고, JPA 관련 기능은 필요하지 않습니다.
Entity 작성
/**
* redis에 저장할 객체
* RedisHash 설정은 Redis에 Hash 형태로 저장하고, timeToLive가 남아있는 시간을 의미
* 600 => 60초 * 10 => 10분
* */
@RedisHash(value = "user", timeToLive = 600)
@Data
@NoArgsConstructor
@AllArgsConstructor
public class UserVo {
@Id
private String id;
private String name;
private String address;
}
테스트
insert
insert 했더니 set형태로도 hash형태로도 둘다 들어가 있는 것을 확인했다.
이부분은 다음에 상세하게 보도록 하자
delete
delete 후 확인해보니 데이터가 없는 것을 확인했다.
마무리
Redis가 어렵다는 생각밖에 없었는데 글을 잘 작성해주신 분에게 감사드리며 오늘도 이렇게 하나를 배워 갑니다.
'코딩 공부 > Spring' 카테고리의 다른 글
[Spring] 테스트 코드 심화(Controller , Service) (0) | 2024.09.11 |
---|---|
[Spring] AOP 동작 흐름 및 패턴 이해 (0) | 2024.09.10 |
[Spring] CustomException , ErrorCode 작성 및 적용 (0) | 2024.09.05 |
[Spring] @Query를 사용하다 생긴 문제 , Enum 활용 , Java 설정 파일 (0) | 2024.09.04 |
[Spring] Spring Security 기초 사용법 (0) | 2024.08.30 |