Spring Framework
[Redis] SpringBoot + Redis
헤르메스의날개
2022. 11. 23. 00:18
728x90
Redis 환경을 공부해보려고 합니다. 공부하다보니 참조할 내용이 많네요.
소스를 오픈해주신 분들께 감사드립니다.
Java 의 Redis Client 는 크게 두 가지가 있습니다.
Jedis 와 Lettuce 인데요.
원래 Jedis 를 많이 사용했으나 여러 가지 단점 (멀티 쓰레드 불안정, Pool 한계 등등..) 과 Lettuce 의 장점 (Netty 기반이라 비동기 지원 가능) 때문에 Lettuce 로 추세가 넘어가고 있었습니다.
그러다 결국 Spring Boot 2.0 부터 Jedis 가 기본 클라이언트에서 deprecated 되고 Lettuce 가 탑재되었습니다.
출처
https://bcp0109.tistory.com/328
개발환경
SpringBoot 2.7.5
Redis
https://hermeslog.tistory.com/635
목표
SpringBoot 환경하에서의 간단한 Redis 입출력
pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.5</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.study.redis</groupId>
<artifactId>SpringBootNRedis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>SpringBootNRedis</name>
<description>Redis project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<org.slf4j-version>1.7.26</org.slf4j-version>
<ch.qos.logback-version>1.2.9</ch.qos.logback-version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- slf4j -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${org.slf4j-version}</version>
</dependency>
<!-- Logback -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>${ch.qos.logback-version}</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>${ch.qos.logback-version}</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>1.7.32</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.14.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>
application.properties
logging.config=classpath:logback-spring.xml
# Redis 옵션들
# https://zetawiki.com/wiki/%EC%8A%A4%ED%94%84%EB%A7%81_REDIS_%ED%94%84%EB%A1%9C%ED%8D%BC%ED%8B%B0
# 커넥션 팩토리에 사용되는 데이터베이스 인덱스
#spring.redis.database
# 레디스 서버 호스트
spring.redis.host=localhost
# server password
spring.redis.password=
# 레디스 서버 포트
spring.redis.port=6379
# 풀에서 관리하는 idle 커넥션의 쵀소수 대상 (양수일 때만 유효)
spring.redis.pool.max-idle=8
# 풀에서 관리하는 idle 커넥션의 쵀소수 대상 (양수일 때만 유효)
spring.redis.pool.min-idle=0
# pool에 할당될 수 있는 커넥션 최대수 (음수로 하면 무제한)
spring.redis.pool.max-active=8
# pool이 바닥났을 때 예외 발생 전, 커넥션 할당 차단 최대 시간(단위 밀리세컨드, 음수는 무제한 차단)
spring.redis.pool.max-wait=-1
# 레디스 서버 이름
#spring.redis.sentinel.master
# 호스트: 포트 쌍 목록 (콤마로 구분)
#spring.redis.sentinel.nodes=
# 커넥션 타임아웃 (단위 밀리세컨드)
spring.redis.timeout=0
RedisConfig.java
package com.study.redis.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.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
@Configuration
public class RedisConfig {
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.port}")
private int port;
@Bean
public RedisConnectionFactory redisConnectionFactory() {
return new LettuceConnectionFactory(host, port);
}
@Bean
public RedisTemplate<String, Object> redisTemplate() {
RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
// 일반적인 key:value의 경우 시리얼라이저
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setValueSerializer(new StringRedisSerializer());
redisTemplate.setHashKeySerializer(new StringRedisSerializer());
redisTemplate.setHashValueSerializer(new StringRedisSerializer());
return redisTemplate;
}
@Bean
public StringRedisTemplate stringRedisTemplate() {
final StringRedisTemplate stringRedisTemplate = new StringRedisTemplate();
stringRedisTemplate.setKeySerializer(new StringRedisSerializer());
stringRedisTemplate.setValueSerializer(new StringRedisSerializer());
stringRedisTemplate.setConnectionFactory(redisConnectionFactory());
return stringRedisTemplate;
}
}
PersonRedisRepository.java
package com.study.redis.sample.repository;
import org.springframework.data.repository.CrudRepository;
import com.study.redis.sample.vo.Person;
public interface PersonRedisRepository extends CrudRepository<Person, String> {
}
Person.java
package com.study.redis.sample.vo;
import java.time.LocalDateTime;
import org.springframework.data.annotation.Id;
import org.springframework.data.redis.core.RedisHash;
import lombok.Getter;
@Getter
@RedisHash(value = "people", timeToLive = 30)
public class Person {
@Id
private String id;
private String name;
private Integer age;
private LocalDateTime createdAt;
public Person(String name, Integer age) {
this.name = name;
this.age = age;
this.createdAt = LocalDateTime.now();
}
}
RedisRepositoryTest.java
package com.study.redis.sample.repository;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import com.study.redis.sample.vo.Person;
@SpringBootTest
public class RedisRepositoryTest {
@Autowired
private PersonRedisRepository repo;
@Test
void test() {
Person person = new Person("Park", 20);
// 저장
repo.save(person);
// `keyspace:id` 값을 가져옴
repo.findById(person.getId());
// Person Entity 의 @RedisHash 에 정의되어 있는 keyspace (people) 에 속한 키의 갯수를 구함
repo.count();
// 삭제
repo.delete(person);
}
}
TEST 결과
$>docker run -it --network redis-net --rm redis bash
root@745c63899a02:/data# redis-cli -h redis_boot
redis_boot:6379> keys *
1) "people"
2) "people:399cf776-26ae-4065-b98a-82e55e5a3a04"
3) "setKey"
4) "hashKey"
5) "stringKey"
redis_boot:6379> type people:399cf776-26ae-4065-b98a-82e55e5a3a04
hash
redis_boot:6379> ttl people:399cf776-26ae-4065-b98a-82e55e5a3a04
(integer) 9
redis_boot:6379> hgetall people:399cf776-26ae-4065-b98a-82e55e5a3a04
1) "_class"
2) "com.study.redis.sample.vo.Person"
3) "age"
4) "20"
5) "createdAt"
6) "2022-11-26T00:55:15.177"
7) "id"
8) "399cf776-26ae-4065-b98a-82e55e5a3a04"
9) "name"
10) "Park"
redis_boot:6379>
https://mongsil-jeong.tistory.com/25
https://westmino.tistory.com/157
https://steady-coding.tistory.com/586
728x90