[Spring Boot] Redis (Jedis)를 이용한 간단한 API 제작

2020. 10. 17. 01:12Spring/Spring Boot

1. Redis

Redis 서버가 설치되어 있다는 전제하에 진행된다.


[참고] Database - Practice - AWS EC2 인스턴스 Redis 설치

 

 

 

2. Redis 설정

1) build.gradle

compile group: 'redis.clients', name: 'jedis'
compile group: 'org.apache.commons', name: 'commons-pool2', version: '2.6.2'
compile ('org.springframework.boot:spring-boot-starter-data-redis') {
	exclude group: 'io.lettuce', module: 'lettuce-core'
}

※ Spring Boot 2.0 이상에서는 Lettuce가 기본 클라이언트가 되었기 때문에 Jedis를 사용하기 위해서는 Lettuce를 exclude 해주어야 한다.

2) application.yml

spring:
  redis:
    host: [Redis 서버 IP]
    port: 6379

3) RedisRepositoryConfig.java

기본적인 Jedis 설정만으로도 API를 간단하게 제작할 수 있다. 

package com.example.jedistest.config;

import lombok.RequiredArgsConstructor;
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.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;

import java.time.Duration;

@RequiredArgsConstructor
@Configuration
@EnableRedisRepositories
public class RedisRepositoryConfig {

    private final RedisProperties redisProperties;

    // Jedis
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        return new JedisConnectionFactory(new RedisStandaloneConfiguration(redisProperties.getHost(), redisProperties.getPort()));
    }

    @Bean
    public RedisTemplate<?, ?> redisTemplate() {
        RedisTemplate<byte[], byte[]> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        return redisTemplate;
    }
}

기본적인 설정으로도 API를 제작할 수 있지만 Connection Pool을 사용한다면 성능을 더 높일 수 있다.

package com.example.jedistest.config;

import lombok.RequiredArgsConstructor;
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.RedisStandaloneConfiguration;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.repository.configuration.EnableRedisRepositories;
import redis.clients.jedis.JedisPoolConfig;

import java.time.Duration;

@RequiredArgsConstructor
@Configuration
@EnableRedisRepositories
public class RedisRepositoryConfig {

    private final RedisProperties redisProperties;

    @Bean
    public RedisTemplate<?, ?> redisTemplate() {
        RedisTemplate<byte[], byte[]> redisTemplate = new RedisTemplate<>();
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        return redisTemplate;
    }

    // Connection Pool
    @Bean
    public RedisConnectionFactory redisConnectionFactory() {
        RedisStandaloneConfiguration config = new RedisStandaloneConfiguration(redisProperties.getHost(), redisProperties.getPort());
        JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(config);
        jedisConnectionFactory.setPoolConfig(jedisPoolConfig());
        return jedisConnectionFactory;
    }

    private JedisPoolConfig jedisPoolConfig() {
        final JedisPoolConfig poolConfig = new JedisPoolConfig();
        poolConfig.setMaxTotal(128);
        poolConfig.setMaxIdle(128);
        poolConfig.setMinIdle(36);
        poolConfig.setTestOnBorrow(true);
        poolConfig.setTestOnReturn(true);
        poolConfig.setTestWhileIdle(true);
        poolConfig.setMinEvictableIdleTimeMillis(Duration.ofSeconds(60).toMillis());
        poolConfig.setTimeBetweenEvictionRunsMillis(Duration.ofSeconds(30).toMillis());
        poolConfig.setNumTestsPerEvictionRun(3);
        poolConfig.setBlockWhenExhausted(true);
        return poolConfig;
    }
}

4) 그 외

그 외의 코드는 이전 글과 동일하다. Connection Pool 사용 전과 후에 대한 차이는 블로그에(jojoldu.tistory.com/418) 잘 기술되어있다.


블로그에서 다룬 Connection Pool 사용 전과 후의 차이를 요약하자면, Connection Pool을 사용했을 때, Jedis의 기본 설정을 했을 때에 비해 TPS 성능이 50% 향상이 되었지만, CPU에 부하가 커질 수 있기 때문에 적절한 Pool Size를 찾아야 한다고 한다.

 

전체적인 테스트 결과에서는 Lettuce가 Jedis에 비해 전 분야에서 우위에 있음을 확인을 하였다. (Lettuce 권장)

항목 TPS Redis CPU Redis Connection 속도 응답 속도
Jedis
(No Connection Pool)
31,000 20% 35 100ms
Jedis
(Use Connection Pool)
55,000 69.5% 515 50ms
Lettuce 100,000 7% 6 7.5ms

[참고] jojoldu.tistory.com/418

[참고] github.com/ozofweird/SpringBoot_Redis_Jedis

728x90