SpringBoot + Redis

배지원·2024년 5월 2일

Redis

목록 보기
5/5

1. Jedis와 Lettuce중 어떤것을 사용해야할까?

Lettuce는 비동기 및 병렬 입력/출력 작업을 지원하고, 네이티브한 코어와 효율적인 명령 전송의 장점을 제공하여 성능을 극대화합니다. Lettuce는 Reactive 환경 및 백프레셔(flow)와 같은 비동기 시스템과의 통합을 용이하게 합니다. 또한 Lettuce는 Redis 클러스터 및 Sentinel과의 통신을 지원하며, 연결 풀링, SSL 지원과 같은 고급 기능들을 제공합니다.

Jedis는 Redis의 명령들을 호출하기 위한 Java 클라이언트 라이브러리로, 네이티브 코어와 달리 전적으로 동기화된 방식으로 동작합니다. 이는 멀티 스레드 환경에서의 안정성과 관련된 몇 가지 주의 사항을 요구할 수 있습니다. Jedis는 단순한 API와 쉽고 빠른 구현을 제공하며, 기존에 많은 프로젝트에서 사용되어 왔습니다.

Lettuce는 비동기 및 병렬 작업을 지원하고, Reactive 환경과의 통합에 유용하기 때문에 많은 경우에서 성능 측면에서 뛰어난 선택지로 여겨집니다. 또한 Redis의 클러스터 및 Sentinel과의 통신을 지원하며, 고급 기능들을 제공함으로써 전반적으로 다양한 요구사항을 충족시키는 데 도움이 됩니다.
따라서, 성능 및 확장성 측면에서 더 나은 선택을 위해 많은 경우 Lettuce를 더 선호하는 경향이 있습니다.


2. Lettuce 실습1 - Key - Value 저장

Lettuce 공식 사이트
해당 공식 사이트에서 Lettuce 공식 문서를 확인할 수 있습니다.

(1) Gradle 추가

// redis , Lettuce
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
implementation 'io.lettuce:lettuce-core:6.3.2.RELEASE'
  • Redis와 lettuce를 사용하기 위해 해당 의존성을 추가해줍니다.

(2) application.yaml 추가

  data:
    redis:
      host: ${REDIS_HOST}
      port: ${REDIS_PORT}
  • Redis host와 port넘버를 지정해 줍니다.

(3) RedisConfig 추가

@Configuration
public class RedisConfig {

    @Value("${spring.data.redis.host}")
    private String host;

    @Value("${spring.data.redis.port}")
    private int port;


    /*
        LettuceConnectionFactory는 Redis와의 연결을 설정하고 관리하는 데 사용됩니다. 
        RedisStandaloneConfiguration을 이용하여 host와 port 정보를 전달하여 Redis에 연결하는 단일 구성을 생성합니다.
     */
    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        return new LettuceConnectionFactory(new RedisStandaloneConfiguration(host, port));
    }

    /*
    RedisTemplate은 Redis와 상호작용하기 위한 핵심적인 클래스입니다. 
    이 메서드는 기존에 생성한 LettuceConnectionFactory를 사용하여 연결을 설정하고, 
    StringRedisSerializer를 key와 value에 대한 Serializer로 설정합니다.
     */
    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        return redisTemplate;
    }

}
  • Redis에 대한 기본 설정을 구현한 Config파일을 추가해 줍니다.

(4) RestController 추가

@RestController
@RequiredArgsConstructor
public class UserController {

    private final UserRepository userRepository;

    private final StringRedisTemplate redisTemplate;

    @GetMapping("/users/{id}/email")
    public String getUserEmail(@PathVariable Long id) {
        /*
        ValueOperations는 Redis에 저장된 값(value)을 다루기 위한 메서드들을 제공합니다. 주로 문자열이나 기본 데이터 타입의 값을 다루는 데 사용됩니다.
        따라서 stringStringValueOperations는 Redis의 문자열 값을 다루기 위한 메서드들을 포함하는 ValueOperations의 구현체로,
        문자열에 대한 다양한 작업(저장, 조회, 수정, 삭제 등)을 수행할 수 있게 해줍니다.
         */
        final ValueOperations<String, String> stringStringValueOperations = redisTemplate.opsForValue();

        User user = userRepository.findById(id).orElse(User.builder().build());

        stringStringValueOperations.set(user.getName(),user.getEmail()); // redis set 명령어

        return String.valueOf(user.getName() + "," + user.getEmail());
    }
}
  • 마지막으로 간단하게 RestController를 통해 user의 이름과 이메일을 key,value형태로 Redis에 저장시켜 줍니다.

(5) 결과


3. Lettuce 실습1 - Hash 저장

  • 2번의 방식처럼 Redis에 Key - Value형태로 저장이 가능하지만 테이블 자체를 JPA와 비슷한 형태를 통해 저장도 가능합니다. 저장할때는 Hash 자료구조를 사용하여 객체를 Redis에 저장시킬 수 있습니다.

(1) RedisEntity 생성

@RedisHash("user")
@Data
public class RedisUser {
    @Id
    private Long id;

    @Column(length = 100)
    private String name;

    @Column(length = 100)
    private String email;

    
    public RedisUser(String name, String email) {
        this.email = email;
        this.name = name;
    }
}
  • 테이블 형식으로 저장하기 위해 RedisUser 생성합니다
  • RedisHash : 클래스의 객체가 Redis에 저장될때 Hash의 이름을 user로 저장합니다.

(2) RedisService 생성

@Service
@RequiredArgsConstructor
public class RedisService{
    private final RedisRepository redisRepository;

    public void setRedisData(RedisUser user) {
        redisRepository.save(user);
    }
}
  • JPA처럼 Repository.save를 통해 데이터를 저장할 수 있습니다.

(3) RedisRepository 생성

public interface RedisRepository extends CrudRepository<RedisUser,Long> {
}
  • CrudRepository를 상속을 받아 JPA처럼 save, update...를 사용가능하게 합니다.

(4) RestController 수정

@RestController
@RequiredArgsConstructor
public class UserController {

    private final UserRepository userRepository;
    private final RedisService redisService;

    private final StringRedisTemplate redisTemplate;

    @GetMapping("/users/{id}/email")
    public String getUserEmail(@PathVariable Long id) {
        /*
        ValueOperations는 Redis에 저장된 값(value)을 다루기 위한 메서드들을 제공합니다. 주로 문자열이나 기본 데이터 타입의 값을 다루는 데 사용됩니다.
        따라서 stringStringValueOperations는 Redis의 문자열 값을 다루기 위한 메서드들을 포함하는 ValueOperations의 구현체로,
        문자열에 대한 다양한 작업(저장, 조회, 수정, 삭제 등)을 수행할 수 있게 해줍니다.
         */
        final ValueOperations<String, String> stringStringValueOperations = redisTemplate.opsForValue();

        User user = userRepository.findById(id).orElse(User.builder().build());

        // Key-Value 저장
        stringStringValueOperations.set(user.getName(),user.getEmail()); // redis set 명령어

        // Hash 저장
        RedisUser redisUser = new RedisUser(user.getName(),user.getEmail());
        redisService.setRedisData(redisUser);

        return String.valueOf(user.getName() + "," + user.getEmail());
    }
}
  • RedisUser 객체를 생성하고 해당 객체를 Redis에 Hash형식으로 저장시켜 줍니다.

(5) 결과

업로드중..

profile
Web Developer

0개의 댓글