헤르메스 LIFE

[Redis] SpringBoot + Redis 본문

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

 

Spring Boot 에서 Redis 사용하기

1. Overview Spring Boot 에서 spring-data-redis 라이브러리를 활용해서 Redis 를 사용하는 방법을 알아봅니다. Redis 에 대한 개념과 로컬 설치 방법은 Redis 설치 및 명령어 글을 확인해주세요. 2. Java 의 Redis Cl

bcp0109.tistory.com

 


개발환경

SpringBoot 2.7.5

Redis 

https://hermeslog.tistory.com/635

 

[Redis] Docker에 Redis 설치하기

Redis는 In Memory Key, Value 데이터 구조의 데이터를 저장할 수 있는 비정형 데이터 베이스입니다. 메모리 DB 이기때문에 속도가 빠르고, 영속성 및 다양한 데이터 구조와 같은 부가적인 기능을 지원

hermeslog.tistory.com


목표

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

 

RedisTemplate 을 이용해서 Multi Pojo get/set 할 때 이슈사항

Spring Boot에서 제공하는 RedisTemplate 을 이용하면 쉽게 Redis 데이터를 Get/Set 할 수 있다. 이 때, Data를 Serialize 하는 방법을 설정할 수 있는데 org.springframework.data.redis.serializer 패키지에서 확인할 수 있

mongsil-jeong.tistory.com

https://cnpnote.tistory.com/entry/SPRING-Spring-RedisTemplate-%EC%97%AC%EB%9F%AC-%EB%AA%A8%EB%8D%B8-%ED%81%B4%EB%9E%98%EC%8A%A4%EB%A5%BC-JSON%EC%9C%BC%EB%A1%9C-serialize%ED%95%A9%EB%8B%88%EB%8B%A4-%EC%97%AC%EB%9F%AC-RedisTemplates%EB%A5%BC-%EC%82%AC%EC%9A%A9%ED%95%B4%EC%95%BC%ED%95%A9%EB%8B%88%EA%B9%8C

 

[SPRING] Spring RedisTemplate : 여러 모델 클래스를 JSON으로 serialize합니다. 여러 RedisTemplates를 사용해야

Spring RedisTemplate : 여러 모델 클래스를 JSON으로 serialize합니다. 여러 RedisTemplates를 사용해야합니까? Redis에서 내 개체를 저장하기 위해 Spring Redis 지원을 사용하고 있습니다. 다른 모델 클래스를 처

cnpnote.tistory.com

https://westmino.tistory.com/157

 

Spring boot Redis 사용하기

Redis는 In-memory 데이터베이스로 key-value 구조로 자료를 저장하는 비정형 데이터베이스이다. In-memory 데이터베이스로 굉장히 속도가 빠르다 기본적인 개념자료 https://zangzangs.tistory.com/72 인메모리

westmino.tistory.com

https://steady-coding.tistory.com/586

 

[데이터베이스] Redis란?

cs-study에서 스터디를 진행하고 있습니다. Cache Cache의 개념 Cache란 나중에 요청할 결과를 미리 저장해둔 후 빠르게 서비스해 주는 것을 의미한다. 즉, 미리 결과를 저장하고 나중에 요청이 오면 그

steady-coding.tistory.com

 

728x90