[레디스] 여러 커넥션 설정 방법

홍건의·2025년 3월 8일
0

레디스

목록 보기
2/3

드라이버 및 커넥션 초기 설정

단일 Redis 서버에서의 연결

LettuceConnectionFactory Bean등록
RedisStandaloneConfiguration를 등록


@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));
  }
}

+ LettuceClientConfigurationBuilder 이용해서 SSL / timeout 쓰기

@Bean
public LettuceConnectionFactory lettuceConnectionFactory() {

  LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
    .useSsl().and()
    .commandTimeout(Duration.ofSeconds(2))
    .shutdownTimeout(Duration.ZERO)
    .build();

  return new LettuceConnectionFactory(new RedisStandaloneConfiguration("localhost", 6379), clientConfig);
}

Master에 Write & Replica에 Read

LettuceConnectionFactory에 아래 2개 객체를 넣어서 등록한다.

  • LettuceClientConfiguration
    : Replica Read 하는 곳
  • RedisStandaloneConfiguration
    : Master Write 하는 곳
@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 이용

결국 LettuceConnectionFactory

  • RedisSentinelConfiguration을 넘긴다

master랑 sentienl 정보(IP주소, Port 번호)를 넘겨서 사용한다.

/**
 * 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);
}

spring.redis.sentinel.master: 마스터 노드의 이름.
spring.redis.sentinel.nodes: 호스트:포트 쌍의 쉼표로 구분된 목록.
spring.redis.sentinel.username: Redis Sentinel으로 인증할 때 적용할 사용자 이름 (Redis 6 필요)
spring.redis.sentinel.password: Redis Sentinel으로 인증할 때 적용할 비밀번호
spring.redis.sentinel.dataNode.username: Redis Data Node로 인증할 때 적용할 사용자 이름
spring.redis.sentinel.dataNode.password: Redis Data Node로 인증할 때 적용할 비밀번호
spring.redis.sentinel.dataNode.database: Redis Data Node로 인증할 때 적용할 데이터베이스 인덱스

+ Redis Sentinel
레디스가 다중 서버로 구성되어있을 때, 마스터 노드에서 장애가 발생하면 자동으로 failover(복구)를 수행하는 프로그램.
Redis와 별개임.

서버 자체에 Redis 프로세스 따로, Sentinel 프로세스 각각 별개로 작동하게 된다. 그래서 각 서버에는 2개 프로그램이 돌아가게 된다. 그래서 Redis 없이 Sentinel만 구성할 수도 있다.

추가로 마스터 노드가 장애를 탐지하는 기준은 쿼럼(quorum)으로 판단한다. 예를 들어 센티널 인스턴스가 3개 일 때, 쿼럼이 2라면 2개 이상의 인스턴스가 master를 비정상이라고 판단해야 FailOver 프로세스를 진행하게 된다.

센티널 수행 전 레디스 자체에서 마스터와 복제본 간에 연결이 선행되어야 한다.

Redis 클러스터 구축

LettuceConnectionFactory

  • RedisClusterConfiguration 를 등록한다.

클러스터 지원은 비클러스터 커뮤니케이션과 동일한 구성 요소를 기반으로 합니다. RedisConnection의 확장인 RedisClusterConnection은 Redis 클러스터와의 통신을 처리하고 오류를 Spring DAO 예외 계층으로 변환합니다. RedisClusterConnection 인스턴스는 다음 예제와 같이 연결된 RedisClusterConfiguration으로 설정해야 하는 RedisConnectionFactory로 생성됩니다.

@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()));
    }
}

Redis Cluster 개념

Sentinel은 마스터가 1개인 반면, Cluster 개념으로 오면 마스터가 여러 대가 된다.

데이터가 분산되어 저장(샤딩)되는 것도 차이가 있다.

마스터를 최대 1000개까지 확장할 수도 있다. 하나의 키는 항상 하나의 마스터에 매핑된다. 얘도 클러스터 안에 노드끼리 자동으로 FailOver를 수행한다.

HeartBeat 패킷

Node 끼리 Ping,Pong 패킷을 서로 주고 받는다. 두 쌍의 패킷을 HearBeat 패킷이라고 부른다.

클러스터 버스 포트

TCP용 Port는 2개 씩 열어놓는다.(클러스터 버스 포트) 일반 적으로 10000을 더한 값을 열어놓는다.

해시슬롯

각 마스터 노드 마다 정해진 범위의 해시슬롯 넘버가 있고, 데이터가 저장되거나 조회해올 때 해당 해시슬롯 넘버를 기준으로 저장되고 한다.

그래서 실제 Redis Client (DB 쿼리 날릴 수 있는 편집기)에서 저장해보면 지정된 해시슬롯 아니면 에러 뜬다. -c 옵션으로 해결은 가능. 다른 DB 붙는거 도와주는거 (Lettuce, Jedis)에서는 클러스터 모드가 따로 있다.

센티널과의 차이

센티널에서는 레디스 자체가 아닌 별개의 센티널 인스턴스를 띄워서 서로 감시하도록 하였으나,
클러스터 구조에서는 일반 레디스 노드가 서로를 감시하게 된다.
모든 노드는 클러스터 버스를 통해 통신한다.

profile
Backend Developer

0개의 댓글

관련 채용 정보