현재 진행중인 프로젝트에서 redis 도입이 필요했고 내가 세팅을 담당했다.
기존 AWS 아키텍처 구성에서 어떤 방식으로 redis를 추가 구성하는게 가장 좋은 선택일지 고민해본 결과, Private subnet의 API 서버 EC2에 Redis를 함께 설치하기로 했다.
(우리 프로젝트의 클라우드 인프라 아키텍처는 글의 하단부에 다이어그램을 첨부해두었다)
그 이유는:
- 프리티어는 EC2 인스턴스 사용 시간을 기준으로 과금이 되는데, 지금 이미 2개 이상의 인스턴스가 실행되고 있으므로(private, public subnet 각각), 현재 실행중인 EC2에 설치하는게 맞다고 판단했다.
- 또한, 구조적으로도 안정적이다!
- 이미 Private subnet에 위치하고 있으므로 보안성이 확보된다.
- Bastion 호스트(Public EC2)를 통해 관리가 가능하다.
- RDS와 같은 서브넷에 위치하므로 안정적인 통신이 가능해진다.
이제 세팅을 시작해보자!
1. EC2 접속
일단 private EC2에 접속하기 위한 public EC2에 접속한다.
나는 powerShell로 진행중이다.
public EC2 ssh 접속
- ssh -i saudi.pem ec2-user@ec2-43-201-31-8.ap-northeast-2.compute.amazonaws.com
private EC2 ssh 접속
- ssh -i saudi-2.pem root@10.0.137.251
- public ec2에서 접속된 상태로 해당 명령어를 입력하여 Redis를 설치하기 위한 private ec2에 접속한다.
2. Redis 설치
# dnf 패키지 업데이트
sudo dnf update -y
# 레디스 패키지 검색
sudo dnf search redis
# 레디스 설치
sudo dnf install redis6
# 레디스 재시작
sudo systemctl restart redis6
# 부팅할 때 레디스 실행 설정
sudo systemctl enable redis6
# 레디스 접속
redis6-cli
- 설치 가능한 레디스 버전 검색 결과, 현재 나의 EC2에서는 redis6 버전을 사용할 수 있었다.
- 다운로드한 레디스의 버전에 맞게 cli에 접속하여, ‘ping’ 명령어를 입력해보자! pong 이라는 응답이 오면 제대로 설치가 완료된 것이다.
3. Redis 설정
- 레디스는 redis.conf 라는 설정파일을 바탕으로 실행된다.
- 다음으로, 추가적인 설정을 해주자.
- 변경할 설정 값들은 다음과 같다.
- requirepass
- bind
- maxmemory
- maxmemory-policy
- sudo vi /etc/redis6/redis6.conf
- 위 명령어를 통해 redis 설정파일에 접근하여 원하는 설정값들을 변경할 수 있다.
requirepass: redis 접속 비밀번호 설정
- redis6.conf 파일에서 /requirepass 를 입력하고 enter 키를 눌러서 requirepass 옵션 설정 부분을 찾는다. n 키를 누르면 계속해서 다음 단어를 찾는다
- vi 에디터에서 i 키를 누르면 수정 모드가 된다.
- requirepass 설청 부분에서 주석을 해제하고, requirepass password 이런 식으로 입력한 후에 esc 키를 눌러서 초기 모드로 되돌린다.
bind: 접속 가능한 ip 주소 설정
- 위와 같은 방법으로 bind 옵션 설정 부분을 찾는다.
- 기본 설정값 대신 bind 0.0.0.0 으로 변경해준다. 이를 통해 모든 ip로부터의 접근을 허용할 수 있다.
Maxmemory 설정
- Redis는 사용할 수 있는 최대 메모리 용량을 설정해주지 않으면 시스템 전체 용량을 사용한다.
- 따라서 이를 설정해주기 전에, free -h 명령어를 통해 현재 EC2의 상태를 확인해봤다.
- Redis uses a relatively large number of buffers, which enable replica communication, client communication, pub/sub commands, and more. As a result, you should ensure that 30% of the RAM is available on each node at any given time.
- 출처: https://redis.io/docs/latest/operate/rs/installing-upgrading/install/plan-deployment/hardware-requirements/
- 위 내용을 참고하여, 현재 avaliable 메모리 양이 432mb이므로 이 값의 약 70%인 300mb로 설정해야겠다.
- 위와 같은 방법으로 maxmemory 300mb 를 설정해준다.
maxmemory-policy 변경
- 이 설정값은 레디스의 메모리가 가득 찼을 때, 새로운 데이터 쓰기 요청이 들어오면 어떻게 할지에 대한 방법을 결정한다. 이를 Eviction policy라고 부른다.
- Redis의 디폴트 Eviction policy는 noeviction이다. 이는 메모리가 가득 찼을 때 새로운 쓰기 명령에 대해 에러를 반환하는 정책이다.
- 사용 가능한 정책들은 공식 문서 참고: https://redis.io/docs/latest/operate/rs/databases/memory-performance/eviction-policy/
- 현재 우리의 EC2는 개발 환경이므로 allkeys-lru 를 쓰려고 한다. 그 이유는:
- 메모리 한계에 도달했을 때 에러를 발생시키는 것보다 자동으로 오래된 데이터를 지우는 게 개발할 때 편한데, noeviction(기본값)을 사용하면 메모리 꽉 찼을 때마다 직접 개입해야 하기 때문이다.
- 또한, 개발 중에는 데이터의 정확한 만료 시간(TTL) 관리가 덜 중요하고, 테스트용 데이터는 자주 변경되고 재사용될 것이기 때문이다.
- 같은 방법으로 변경해준다.
- 이제 설정파일 변경을 완료했으니까 레디스를 재시작 해주자.
- sudo systemctl restart redis6
4. EC2 보안그룹 설정
- redis는 설정해둔 port로 들어오는 연결만 허용하기 때문에, 6379번 포트(Redis의 디폴트 포트번호)로 EC2 인스턴스에 접속할 수 있도록 설정해준다.
- 우리의 클라우드 인프라 구조에서는 다음과 같이 인바운드 규칙에 Public subnet EC2의 Private IP에 대해 6379번 포트 접속을 허용하는 규칙을 추가해주면 된다.
- 다음은 참고용도로 현재 우리의 클라우드 인프라 구조 중에서 일부만 도식화한 이미지이다.
- 내가 Redis를 설치한 EC2는, private subnet에 위치한 아이이다.
- 현재 우리의 클라우드 인프라는 public subnet에 EC2를 하나 더 만들어서 private subnet의 EC2에 접근하는 형태인 것이다.
5. 접속 확인하기
- Bastion 호스트에서 정상적으로 redis 접속이 되는지 확인해보자
- redis6-cli -h 10.0.137.251 -p 6379 -a saudi
- 새로운 key-value 값을 저장하고 불러와봤다.
- 성공!!
6. Spring Boot와 Redis 연결 예시
- 우리 프로젝트의 API는 Spring Boot를 활용해서 개발한다.
- 다음과 같이 설정을 추가해주고 필요한 코드를 작성하면 된다.
1. 의존성 추가
# build.gradle
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
}
2. application.yml 설정
spring:
redis:
host: localhost # 같은 서버에서 실행될 예정이므로 localhost
port: 6379
password: ${REDIS_PASSWORD}
# 필요시 추가 설정 옵션들 추가
참고