Redis의 영속성 RDB와 AOF

신승호·2024년 11월 12일

문제점

최종 프로젝트에서 해결못했던 문제

중간중간 코드 수정이나 사용요금 쌀먹을 위해 배포가 진행중인 인스턴스를 중지하여 서버를 내리자 refresh토큰에서 문제가 있었다.

인메모리 db인 레디스를 활용해 refresh토큰을 저장하는 로직 때문에 서버를 내리게 된다면 db안에 저장된 refresh토큰정보가 사라져 사용자의 쿠키에 남아있던 refresh토큰과 유효성 검사를 할 수 없어 인증 쪽에 문제가 있었다.

당시에는 혹여나 로그인이 안되던 유저에게 시크릿모드를 사용하기를 권고하는 방향으로 임시방편을 했지만 최종 프로젝트가 끝나고 나서야 redis에서는 인메모리 db의 단점을 보완하고자 설정을 통해 영속성을 보장한다는 것을 확인하였다.

비록 환경변수는 다르지만 간단한 프로젝트로 영속성 설정을 실습하고자 한다.

실습(인메모리db단점 확인)

우선 간단하게 스프링 부트 프로젝트와 레디스 연결

@Configuration
public class Redisconfig {
    @Value("${spring.data.redis.host}")
    private String host;

    @Value("${spring.data.redis.port}")
    private int port;

    @Bean
    public RedisConnectionFactory redisConnectionFactory(){
        return new LettuceConnectionFactory(host,port);
    }
}

그냥 유저이름을 저장하고자 한다.(패스워드 저장에 대해서는 레디스에 대해 좀 더 공부가 필요할 듯하다. 최종프로젝트에서도 그냥 refreshtoken만 넣었고 나중에 캐싱을 다뤄보면서 제대로 된 저장법을 익혀야 할듯, 일단 해당 포스팅과 관련은 없기에 넘어가자.)

@Getter
@RedisHash(value = "user1", timeToLive = 86400)
public class User {
    @Id
    private String username;

    private String password;

    public User(String username, String password) {
        this.username = username;
        this.password = password;
    }
}
public interface UserRepository extends CrudRepository<User,String> {

}

컨트롤러 서비스 dto는 생략 , 일반적인 회원가입 로직이다.

포스트맨을 통해 유저 정보를 보내주었고

redis-cli를 통해 들어온 redis에 잘 저장된 것을 확인하였다.

그런데 컴퓨터를 재부팅하면...

인메모리 db답게 데이터가 휘발된다.

refresh토큰을 저장한게 인스턴스 중지마다 날아갔던건 이 때문

RDB와 AOF

이제 영속성 설정을 해보자.

redis는 RDB와 AOF 라는 두 가지 방식으로 메모리가 아닌 디스크에 데이터를 저장하여 영속성을 보장할 수 있다.

RDB

사실 redis는 우리가 설정하지 않아도 영속성을 보장하는 설정이 세팅 되어있다.

이미 .rdb 라는 확장자의 파일에 데이터를 저장하고 있었다. 다만 주기가 길게 설정되어있을 뿐

RDB(snapthot)는 순간적으로 메모리에 있는 내용을 스냅샷을 떠서 디스크에 옮겨 담는 방식이다.

RDB 방식은 메모리의 snapshot을 그대로 저장하기 때문에 서버를 재구동시할 때 snapshot을 다시 읽으면 되므로 속도가 빠른 장점이 있다. 

그러나, snapshot을 추출하는데 시간이 오래걸리고 도중에 서버가 꺼지면 이후의 데이터를 모두 사라진다는 단점이 있다. (저장주기에 따라 유실되는 데이터 존재)

AOF

AOF(Append On File) 방식은 redis의 모든 write/update 연산 자체를 모두 log 파일에 기록하는 형태이다.

default로 appendonly.aof 파일에 기록되며, 조회를 제외한 입력/수정/삭제 명령이 실행될 때 마다 기록된다

그리고 서버가 재시작될 때, log에 기록된 write/update 연산을 재 실행하는 형태로 데이터를 복구하는 방식이다.

log 파일에 대해서만 append하기 때문에 log write 속도가 빠르고 어떤 시점에 서버가 다운되더라도 데이터가 사라지지 않는 장점이 있다. 

그러나, 모든 write/update 연산을 log파일에 남기기 때문에 log 데이터 양이 굉장히 크고, 복구 시 저장된 모든 write/update연산을 다시 실행하기 때문에 재시작 속도가 느린 단점이 있다. 

실습(redis.conf파일)

위의 두 설정은 redis.conf파일의 설정값을 변경하여 조작 가능하다.

mac환경에서 진행했기에 터미널에서

vim /opt/homebrew/etc/redis.conf

명령어를 통해 vim으로 해당 파일을 열어주었다.

먼저 RDB부터 설정하자.

파일을 쭈욱 내리다보면 RDB의 저장방식인 스냅샷설정란이 있다.

13번 줄에 save 3600 1 300 100 60 10000이라고 기본설정이 되어있었다.

  • 3600초 (1시간) 동안 1회 이상의 변경이 있으면 데이터 저장
  • 300초 (5분) 동안 100회 이상의 변경이 있으면 데이터 저장
  • 60초 동안 10,000회 이상의 변경이 있으면 데이터 저장

스냅샷 설정이 길다고 생각하여 변경해줄 필요가 있다.

vim에서 수정은 i를 입력하여 수정이 가능하며 수정모드에서 esc :wq 입력으로 저장 후 나올 수 있다.

  • 900초 (15분) 동안 1회 이상의 변경이 있으면 데이터 저장
  • 300초 동안 10회 이상의 변경이 있으면 데이터 저장
  • 60초 동안 100회 이상의 변경이 있으면 데이터 저장

다음은 AOF 설정

다시 redis.conf 파일을 쭈욱 내리다 보면 APPEND ONLY MODE가 있다.

가운데 #가 없는 부분에 appendonly yes 부분이 설정 부분이다.(원래 기본설정은 no로 되어있으며 no를 yes로 바꿔주면 적용된다.)

설정이 적용되려면 redis를 재시작 해줘야 한다.

vim을 나오고

brew services restart redis

redis를 재시작하였다.

다시 데이터를 넣어주었다.

after2는 혹시나 해서 after 저장 후 15분 후에 넣어주었다. (RDB 설정이 15분에 1회 스냅샷)

컴퓨터를 재부팅하면...


재부팅 후에도 데이터가 남아있는게 확인되었다.

사실 RDB와 AOF를 둘 다 적용했기에 정확히 어떤 방식으로 저장이 된건지는 모르겠다. 두 방식 다 쓰는게 권장 되며 실제로 또 적용할 경우 둘 다 적용할 것이기에 크게 문제가 되진 않을 것 같다.


레퍼런스 :
https://inpa.tistory.com/entry/REDIS-%F0%9F%93%9A-%EB%8D%B0%EC%9D%B4%ED%84%B0-%EC%98%81%EA%B5%AC-%EC%A0%80%EC%9E%A5%ED%95%98%EB%8A%94-%EB%B0%A9%EB%B2%95-%EB%8D%B0%EC%9D%B4%ED%84%B0%EC%9D%98-%EC%98%81%EC%86%8D%EC%84%B1
https://jungwoong.tistory.com/82

profile
비전공자 뉴비입니다

0개의 댓글