들어가며
안녕하세요. 최근에 플러피라는 시험 제작 및 관리, 응시 서비스를 만들고 있습니다. 서버의 가용성을 높이기 위해서 서버를 이중화하려고 합니다. 가용성에 대해서 알고 싶으신 분들은 이 글을 참고하시면 좋을 것 같습니다. 기존에는 EC2 1대에 Docker를 통해 Spring과 Redis를 운영하고 있었습니다. 키값 저장소인 레디스는 여러 서비스에서 접근하기 때문에 분리하려고 합니다.
이번 글에서는 프리티어(Free Tier)에서 ElastiCache를 사용하는 방법에 대해서 알아보고, EC2에서 동작하는 Spring과 연결할 때 주의할 점에 대해서 알아보겠습니다.
AWS ElastiCache 사용법
AWS ElastiCache 생성하기
ElastiCache 페이지로 이동하고, Valkey 생성을 시작해줍니다. Valkey의 경우 Linux Foundation에서 만들어진 오픈 소스로 Redis v7.2와 완벽하게 호환된다고 합니다. 또한 서버리스와 노드에서 각각 33%, 20%의 비용을 줄일 수 있다고 합니다.
클러스터 설정
프리티어 조건 내에서 사용하기 위해서 자체 캐시 설계, 클러스터 캐시로 선택하겠습니다.
이름과 설명을 적절하게 작성해줍니다.
AWS 프리티어의 일부로 cache.t2.micro 또는 cache.t3.micro를 월간 750시간 사용할 수 있습니다. 자세한 설명은 요금 세부 정보를 확인해주세요. 복제본의 개수도 0개로 지정하겠습니다. 금전적인 여유가 있으신 분들은 늘리셔도 됩니다.
클러스터를 위한 서브넷을 지정해야 합니다. 새 서브넷 그룹을 생성하겠습니다. 이름과 설명을 적절히 작성해주세요. VPC는 운영하고 있는 EC2와 같은 것을 선택합니다. 서로 다른 VPC일 경우 통신할 수 없습니다. 또는 Peering 통해서 통신할 수 있습니다.
하단의 가용 영역 배치의 경우 필요에 따라 선택합니다.
고급 설정
전송 중 암호화를 사용할 경우 TLS/SSL 프로토콜을 사용하여 데이터를 암호화합니다. redis-cli를 통해 접속할 경우 --tls 옵션을 추가해야합니다. 아래를 참고해주세요.
redis-cli -h <호스트명> -p <포트번호> --tls
모든 AWS 리전에 대해 월별 GiB당 0.085 USD의 요금으로 백업을 설정할 수 있습니다. 필요에 따라 선택해줍니다.
보안 그룹은 생성 이후에 추가해주도록 하고, 나머지 부분은 기호에 맞게 선택해주시면 됩니다.
보안 그룹 생성 및 지정
방금 생성했던 ElastiCache에는 현재 접근할 수 없는 상태입니다. 일반적으로 EC2에서 6379 포트로 Redis와 같은 키값 저장소에 접근합니다. 이에 맞게 보안 그룹을 생성하겠습니다.
포트 범위는 6379로 지정하고, 소스는 "사용자 지정"으로 하고, "EC2가 사용하는 보안 그룹"을 선택합니다. 이것은 해당 보안 그룹을 사용하는 것들에 대해서 6379번 포트로 들어오는 트래픽을 허용한다는 의미입니다.
이렇게 생성한 보안 그룹을 ElastiCache의 보안 그룹에 추가해줍니다. "보안 그룹"의 "수정"으로 들어가서 "보안 그룹 선택됨"의 "관리" 버튼을 통해서 보안 그룹을 선택할 수 있습니다.
Spring Redis 사용 시 참고
Lettuce 설정
전송 중 암호화를 선택했을 경우 LettuceClientConfig를 통해 useSsl을 사용해야 한다.
@Configuration
@RequiredArgsConstructor
public class RedisConfig {
private final RedisProperties properties; // host, port, ssl 설정 정보를 가지고 있음
@Bean
public RedisConnectionFactory redisConnectionFactory() {
RedisConfiguration config = new RedisStandaloneConfiguration(properties.host(), properties.port());
LettuceClientConfigurationBuilder clientConfigBuilder = LettuceClientConfiguration.builder();
if (Boolean.TRUE.equals(properties.ssl().enabled())) {
clientConfigBuilder.useSsl();
}
return new LettuceConnectionFactory(config, clientConfigBuilder.build());
}
@Bean
public RedisTemplate<String, String> redisTemplate() {
RedisTemplate<String, String> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory());
return redisTemplate;
}
}
Redisson 설정
이것도 마찬가지로 전송 중 암호화를 선택했을 경우 setSslEnableEndpointIdentification을 통해 SSL을 설정해야 한다. 주의할 점으로 SSL일 경우 "rediss://"로 시작하는 경로를 가지고, SSL이 아닐 경우 "redis://"로 시작하는 경로를 가진다.
@Configuration
@RequiredArgsConstructor
public class RedisConfig {
private final RedisProperties properties; // host, port, ssl 설정 정보를 가지고 있음
@Bean
public RedissonClient redissonClient() {
Config config = new Config();
config.useSingleServer()
.setAddress(String.format(createUrl(), properties.host(), properties.port()))
.setSslEnableEndpointIdentification(properties.ssl().enabled());
return Redisson.create(config);
}
private String createUrl() {
if (Boolean.TRUE.equals(properties.ssl().enabled())) {
return "rediss://%s:%d";
}
return "redis://%s:%d";
}
}
마치며
이번 글에서는 ElastiCache의 Valkey를 사용해서 키값 저장소를 운영하는 방법에 대해서 알아보았습니다. 프리티어 조건 내에서 사용하려고 해서 빈약한 부분이 많습니다. 금전적인 여유가 있으신 분들은 여러 기능들을 활용해보시길 바랍니다.
읽어주셔서 감사합니다 :D
'서버' 카테고리의 다른 글
분산락을 이용한 중복 생성 문제 해결 (2) | 2025.02.23 |
---|---|
로컬에서 AWS Private Subnet에 있는 인스턴스에 접속하는 방법 (0) | 2025.02.13 |
스프링에서 AWS S3를 이용한 이미지 업로드 방법 (0) | 2025.02.03 |
고가용성을 위한 단일 장애 지점(SPOF) 해결 방법 (2) | 2025.01.25 |
확장 가능한 좋아요 기능 설계 및 구현하기 (2) | 2025.01.21 |