Redis Master/Slave 구조를 직접 JavaSpring 을 통해 처리해보자

Terror·2024년 11월 5일

최종 프로젝트

목록 보기
20/28

Overivew

  • 단일 Redis구조에서 Master/Slave 구조로 변경시킬 수 있고, 이를 JavaSpirng으로 구현하고 실제 데이터를 저장하는 등의 행위를 실현 할 수 있다

시나리오

  1. Master/Slave구조의 redis를 만들 수 있다
  2. JavaSpring에서 Master/Slave의 설정 관리
  3. JavaSpring에서의 요청 전송시, 실제 Redis에 저장되는지 확인
  4. Slave redis에서 장애가 발생했을 경우, Master reids로 대응 할 수 있다

1. Master/Slave 구조의 redis 만들기

  • 루트 디렉토리밑에 conf/redis.conf 파일을 만들어준다
  • redis.conf, 파일의 내용은 아래와 같다
    replicaof master 6379
  • 루트 디렉토리에 docker-compose.yml 파일 만들어주기, 파일의 내용은 아래와 같다
    services:
    master:
     container_name: master
     image: redis
     ports:
       - 7001:6379
    slave-a:
     container_name: slave-a
     image: redis
     ports:
       - 7002:6379
     volumes:
       - ./conf:/usr/local/etc/redis/
     command: redis-server /usr/local/etc/redis/redis.conf
    slave-b:
     container_name: slave-b
     image: redis
     ports:
       - 7003:6379
     volumes:
       - ./conf:/usr/local/etc/redis/
     command: redis-server /usr/local/etc/redis/redis.conf
  • 잘 설정이 된 모습이다
  • 조금더 자세한 방법은 이쪽에서 확인 가능하다 !

2. JavaSpring에서 Master/Slave의 설정 관리

Master

@Getter
@Setter
@NoArgsConstructor
public class Master {
    private String host;
    private int port;
}

Slave

@Getter
@Setter
@NoArgsConstructor
public class Slave {
    private String host;
    private int port;
}

RedisInfo

@Getter
@Setter
@NoArgsConstructor
@ConfigurationProperties("spring.redis")
@Configuration
@Component
public class RedisInfo {
    private Master master;
    private List<Slave> slaves;
}

RedisConfig

@RequiredArgsConstructor
@Configuration
@EnableRedisRepositories
public class RedisConfig {

    private final RedisInfo redisInfo;

    @Bean
    public LettuceConnectionFactory redisConnectionFactory() {
        LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
                .readFrom(ReadFrom.REPLICA_PREFERRED)    // replica에서 우선적으로 읽지만 replica에서 읽어오지 못할 경우 Master에서 읽어옴
                .build();
        // replica 설정
        RedisStaticMasterReplicaConfiguration slaveConfig = new RedisStaticMasterReplicaConfiguration(
                redisInfo.getMaster().getHost(), redisInfo.getMaster().getPort());
        // 설정에 slave 설정 값 추가
        redisInfo.getSlaves().forEach(slave -> slaveConfig.addNode(slave.getHost(), slave.getPort()));
        return new LettuceConnectionFactory(slaveConfig, clientConfig);
    }

    @Bean
    public RedisTemplate<String, Object> redisTemplate() {
        RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
        redisTemplate.setKeySerializer(new StringRedisSerializer());
        redisTemplate.setValueSerializer(new StringRedisSerializer());
        redisTemplate.setConnectionFactory(redisConnectionFactory());
        return redisTemplate;
    }
}

3. JavaSpring에서의 요청 전송시, 실제 Redis에 저장되는지 확인

  • 테스트컨트롤러로 진행해보자
@RestController
@RequiredArgsConstructor
public class RedisController {
    private final RedisTemplate<String, String> redisTemplate;

    @GetMapping
    public void redisTest() {
        redisTemplate.opsForValue().set("hello", "world");
    }
}

  • 현재 아무것도 없는 상태에서, 상단 URL로 요청을 날리고 실행되고나면..
  • 3개의 Redis에 정상적으로 반영됨을 확인 할 수 있다

4. Slave redis에서 장애가 발생했을 경우, Master redis로 대응 할 수 있다

Slave redis Read -> Master Redis Read

  • 우리의 설정
LettuceClientConfiguration clientConfig = LettuceClientConfiguration.builder()
                .readFrom(ReadFrom.REPLICA_PREFERRED)    // replica에서 우선적으로 읽지만 replica에서 읽어오지 못할 경우 Master에서 읽어옴
                .build();
  • 에서는, replica에서 우선적으로 읽어오게 설정하되 읽어오지 못한다면 Master에서 읽어오게 설정하였는데 정상적으로 동작되는지 확인해보자
  • Slave redis를 두개다 종료한후
  • key에 저장되있는 value값을 가져오는 컨트롤러 설정후, 실제 요청을 날려보면
  • 잘 가져오는 모습을 볼 수 있다

오늘 나는 무엇을 알았는가?

  • Master Redis에는 Write,Read 가능
  • Slave Redis에는 Read 가능
  • Master Redis의 역할을 Slave Redis가 대신할 수 없기 떄문에, 고가용성을 확보했다고 보기 어려움
  • Master Redis가 죽어도, Slave Redis에서 대신 읽기 작업은 가능함

참조 블로그

https://velog.io/@junsu1222/Spring-boot%EC%99%80-Redis-Master-Slave-%EA%B5%AC%EC%A1%B0%EC%9D%98-%EB%A7%8C%EB%82%A8

profile
테러대응전문가

0개의 댓글