Spring Boot Redis replication

jonghyukLee·2022년 10월 8일
0

오늘은 redis 서버를 쓰기/읽기 전용으로 분리 구성해보았습니다.

기존에는 redis 서버를 한대만 두었는데, 아직까지 이유는 파악하지 못했지만 갑자기 테스트용 redis 서버가 읽기 전용으로 인식되어, set이 불가능한 상태가 되었습니다.
우선 이 에러와 관련 없이, redis 서버에 장애가 발생했을 때 대처할 방법이 필요했었기 때문에 구조를 분리하게 되었습니다.

구성할 redis 노드는 아래와 같습니다.

(노드 : 포트)
main : 6379
replica1 : 6000
replica2 : 6001

이렇게 총 3개의 서버를 구성하겠습니다.

1. redis.conf 수정

먼저, 설정 파일에 아래 코드를 추가합니다.
replicaof <main IP> <main Port>

저는 docker-compose를 사용하여 컨테이너로 띄울 것이기 때문에, host IP 부분에 컨테이너 이름을 넣어주었습니다.

2. docker-compose 작성

다음은 도커 컴포즈를 작성합니다.

version: '3.8'
services:
  redis-main:
    container_name: main
    image: redis:latest
    ports:
      - 6379:6379
  redis-replica1:
    container_name: rep1
    image: redis:latest
    volumes:
      - /home/ec2-user/conf/:/data
    ports:
      - 6000:6379
    command: redis-server /data/redis.conf
  redis-replica2:
    container_name: rep2
    image: redis:latest
    volumes:
      - /home/ec2-user/conf/:/data
    ports:
      - 6001:6379
    command: redis-server /data/redis.conf

Spring Boot

1. yml(properties)

#redis
redis:
  main:
    host: 127.0.0.1
    port: 6379
  replicas:
    - host: 127.0.0.1
      port: 6000
    - host: 127.0.0.1
      port: 6001

redis의 호스트, 포트 정보를 설정하기 위해 yml 또는 properties 파일에 위와 같이 추가해줍니다.

2. ConfigurationProperties

@Data
@ConfigurationProperties(prefix = "redis")
@Configuration
public class RedisProperties {
    private String host;
    private int port;
    private RedisProperties main;
    private List<RedisProperties> replicas;
}

값을 세팅하기 위해 ConfigurationProperties를 구성합니다.

3. RedisConfiguration

@RequiredArgsConstructor
@Configuration
public class RedisConfig {

    final RedisProperties properties;

    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
                .readFrom(ReadFrom.REPLICA_PREFERRED)
                .build();
        RedisStaticMasterReplicaConfiguration staticMasterReplicaConfiguration =
                new RedisStaticMasterReplicaConfiguration(properties.getMain().getHost(), properties.getMain().getPort());

        properties.getReplicas().forEach(replica -> staticMasterReplicaConfiguration.addNode(replica.getHost(), replica.getPort()));
        return new LettuceConnectionFactory(staticMasterReplicaConfiguration, clientConfig);
    }
}

마지막으로 세팅한 properties 값들로 redis 커넥션을 완성합니다.

4. Test

@Test
@DisplayName("redis main set/get test")
void redis_main_set_get_test() {
    //given
    String key = "key";
    String value = "value";

    redisService.setValues(key, value);
    //when
    String getValue = redisService.getValues(key);
    //then
		assertThat(value).isEqualTo(getValue);
    redisService.deleteValues(key);
}

redis 서버에 set, get을 해본 결과 정상적으로 테스트가 성공하는 것을 확인할 수 있습니다.

좀 더 확실하게 확인하고 싶으시면, 실행한 도커 컨테이너로 접근하여
main에 값을 set 했을 때 replica 서버에도 값이 set 되는가,
replica 에서 set 했을때 error가 발생하는가

등을 확인해보시면 될 것 같습니다! 저는 모두 정상임을 확인했고, 테스트 완료 후 운영 서버에도 반영하였습니다.

참고 : https://faun.pub/redis-master-slave-configuration-and-tested-in-spring-boot-3a68e7314b90

profile
머무르지 않기!

0개의 댓글