Spring Data Redis

뾰족머리삼돌이·2024년 10월 8일
0

Spring Data Redis

목록 보기
1/12

Redis

Redis키-값 쌍으로 데이터를 저장하는 인 메모리 데이터베이스로 유명하다.
기본적으로 메모리에 데이터를 저장하므로 휘발성이지만, RDB와 AOF 기능을 이용하여 데이터를 디스크에 영구적으로 저장할 수 있다.

Redis에 저장될 수 있는 데이터 유형에는 문자열, 리스트, 집합, 정렬된 집합 등이 존재한다.
데이터 유형에 대한 자세한 내용은 문서에서 확인할 수 있다.

Spring Data Redis

Spring Data Redis는 Spring 애플리케이션에서 Redis를 사용하기 위한 손쉬운 설정과 접근방법을 제공하는 모듈이다.

우선 환경테스트를 진행하기 위해서는 Redis 서버가 구동중인 상태여야 한다.

작성자는 윈도우 환경에서 WSL2를 이용하여 Redis 서버를 설치하고 구동했다

기본적인 Redis 구동 포트는 6379

Redis 통신을 위한 핵심적인 인터페이스는 RedisConnection과 이를 생성하는 RedisConnectionFactory 다.

RedisConnectionRedis와의 상호작용을 수행한다.

RedisConnectionFactory는 이러한 RedisConnection을 생성하는 팩토리 클래스이며, PersistenceExceptionTranslator 인터페이스를 구현하기 때문에 데이터 접근 중에 발생하는 예외를 Spring 예외 계층으로 변환해주는 역할도 수행한다.

RedisConnection은 기본적으로 스레드 안전하지 않다.
따라서, 멀티 스레드 환경에서 이를 공유하려 한다면 native connection을 획득하고, redis 클라이언트 API를 직접 사용해야한다.

RedisConnectionFactory를 사용하기 위해서는 Spring의 IoC 컨테이너를 이용하여 적절한 접근 Connector를 주입받아야 한다.

대표적으로 사용되는 Redis ConnectorLettuceJedis가 있다.

Lettuce

LettuceNetty 기반의 오픈소스 커넥터다.

LettuceConnectionFactory을 통해 LettuceConnection을 생성해내며,
기본적으로 non-blocking, non-transactional 작업에 대해 스레드 안전한 native 연결을 공유한다.

즉, LettuceConnection 객체는 동일한 Redis 연결을 공유하며 스레드 안전하게 관리된다.

@Configuration
class AppConfig {

  @Bean
  public LettuceConnectionFactory redisConnectionFactory() {

    return new LettuceConnectionFactory(new RedisStandaloneConfiguration("server", 6379));
  }
}

Jedis

Jedis커뮤니티 기반의 커넥터다.

JedisConnectionFactory을 통해 JedisConnection을 생성해내며,
기본적으로 비동기방식을 사용하지 않기때문에, 비동기 작업을 위해서는 별도의 클러스터나 비동기 API를 사용해야한다.

@Configuration
class RedisConfiguration {

  @Bean
  public JedisConnectionFactory redisConnectionFactory() {

    RedisStandaloneConfiguration config = new RedisStandaloneConfiguration("server", 6379);
    return new JedisConnectionFactory(config);
  }
}

Connection Mode

Redis가 동작할 수 있는 여러가지의 실행 모드들을 의미하며, 각 모드에서는 섹션별로 소개되는 특정한 구성이 필요하다.

Redis Standalone

가장 쉽게 시작할 수 있는 방법으로, 단일 Redis 서버와 함께 사용된다.
아래와 같이 LettuceConnectionFactoryJedisConnectionFactory를 구성한다

@Configuration
class RedisStandaloneConfiguration {

  /**
   * Lettuce
   */
  @Bean
  public RedisConnectionFactory lettuceConnectionFactory() {
    return new LettuceConnectionFactory(new RedisStandaloneConfiguration("server", 6379));
  }

  /**
   * Jedis
   */
  @Bean
  public RedisConnectionFactory jedisConnectionFactory() {
    return new JedisConnectionFactory(new RedisStandaloneConfiguration("server", 6379));
  }
}

Redis Master/Replica

데이터를 여러 노드에 복제하여 읽기 성능을 향상시킬 수 있는 방법이다.
자동 failover는 지원하지 않지만, 데이터를 더 많은 노드에 안전하게 복사하므로 읽기성능을 분산시킬 수 있다.
또한, Lettuce를 사용하면 Master에 쓰기를 푸시하는 동안 Replica에서 데이터를 읽을 수 있다.

아래 코드처럼 LettuceConnectionFactory를 사용하여 읽기/쓰기 전략을 선택할 수 있다.

@Configuration
class WriteToMasterReadFromReplicaConfiguration {

  @Bean
  public LettuceConnectionFactory redisConnectionFactory() {

    LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
      .readFrom(REPLICA_PREFERRED)
      .build();

    RedisStandaloneConfiguration serverConfig = new RedisStandaloneConfiguration("server", 6379);

    return new LettuceConnectionFactory(serverConfig, clientConfig);
  }
}

Redis Sentinel

고가용성 Redis를 처리하기 위한 방법으로, RedisSentinelConfiguration를 사용한 Redis Sentinel을 지원한다.

이 모드는 Master/Replica와 다르게 자동 failover를 지원하므로, Master 노드에 문제가 생기면 새로운 Master 노드가 선택된다.

Sentinel 노드의 과반수 이상이 Master 노드의 이상을 감지하면 Master 노드가 변경된다

/**
 * Lettuce
 */
@Bean
public RedisConnectionFactory lettuceConnectionFactory() {
  RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
  .master("mymaster")
  .sentinel("127.0.0.1", 26379)
  .sentinel("127.0.0.1", 26380);
  return new LettuceConnectionFactory(sentinelConfig);
}

/**
 * Jedis
 */
@Bean
public RedisConnectionFactory jedisConnectionFactory() {
  RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration()
  .master("mymaster")
  .sentinel("127.0.0.1", 26379)
  .sentinel("127.0.0.1", 26380);
  return new JedisConnectionFactory(sentinelConfig);
}

프로퍼티 파일에 관련 정보를 작성한 경우,
RedisSentinelConfiguration.of(PropertySource)를 통해 객체를 생성하는 것도 가능하다. 관련 정보

센티넬 중 하나와 직접 상호작용 해야하는 경우,
RedisConnectionFactory.getSentinelConnection()RedisConnection.getSentinelCommands()를 사용하여 첫 번째 활성 센티넬에 접근할 수 있다.

Redis Cluster

데이터 분산과 자동 failover를 지원하는 설정으로, 여러 노드를 통한 수평적 확장과 해시 슬롯이 주요 특징이다.
여러개의 Master 노드를 보유할 수 있으며, 16384개의 해시 슬롯으로 key 공간을 나누어 관리한다.

조금 더 자세한 설명은 여기를 참고하자

Spring Data Redis에서의 구성방식은 아래와 같다.

@Component
@ConfigurationProperties(prefix = "spring.redis.cluster")
public class ClusterConfigurationProperties {

    /*
     * spring.redis.cluster.nodes[0] = 127.0.0.1:7379
     * spring.redis.cluster.nodes[1] = 127.0.0.1:7380
     * ...
     */
    List<String> nodes;

    /**
     * Get initial collection of known cluster nodes in format {@code host:port}.
     *
     * @return
     */
    public List<String> getNodes() {
        return nodes;
    }

    public void setNodes(List<String> nodes) {
        this.nodes = nodes;
    }
}

@Configuration
public class AppConfig {

    /**
     * Type safe representation of application.properties
     */
    @Autowired ClusterConfigurationProperties clusterProperties;

    public @Bean RedisConnectionFactory connectionFactory() {

        return new LettuceConnectionFactory(
            new RedisClusterConfiguration(clusterProperties.getNodes()));
    }
}

0개의 댓글

관련 채용 정보