공부내용공유

Redis Persistence 알아보기 (RDB, AOF) 본문

ComputerScience/DataBase

Redis Persistence 알아보기 (RDB, AOF)

forfun 2024. 8. 24. 16:27

서론


 

이전 글에 이어서 이번에는 redis의 persistence 기능을 공부하였다, Redis는 메모리를 활용함으로 높은 퍼포먼스를 낼 수 있지만, 서버가 도중에 꺼졌을 때, 특정 작업을 원복해야할 때 등등 다양한 시나리오에 대응하기 위해서는 persistence의 도움이 필요하다.

 

 

Redis는 AOF, RDB를 통해 persistence 기능을 지원하는데 각각 어떤식으로 작동하고 어떻게 사용하는지 정리할 예정이다.

 

 

본론


 

이번 글의 목차는

  • AOF란
  • RDB란
  • 무엇을 사용해야할까

으로 구성될 예정이다.

 

 

RDB(Redis DataBase)란?

 

스냅샷이란?

 

일단 SnapShot 이라는 개념을 간단히 알아보자. SnapShot은 Redis뿐만 아니라 다양한 소프트웨어에서 사용하는 기법으로 특정 시점에 데이터 저장 장치 혹은 소프트웨어(RDB, NoSQL DB, OS...)의 상태를 통채로 포착하여 파일로 저장하는 기술이다.

 

 

오류가 나서 복구를 해야하거나 특정 시점으로 되돌려야 할 때 저장한 스냅샷을 통해 특정 시점으로 상태, 데이터를 되돌릴 수 있는 것이다.SanpShotBackUp의 개념이 혼동될 수 있는데

  • SnapShot : 스냅샷은 데이터 복구에 필요한 메타 데이터만 저장하기 때문에 생성 속도, 복원 속도가 빠르고 비교적 적은 저장 공간 크기를 요구한다.
  • BackUp : 현재 데이터를 그대로 복사하기 때문에 똑같은 크기의 저장공간이 확보되어야 하고 시간이 오래걸린다.

 

 

Redis DataBase

RDB는 SnapShot 기법을 사용하여 persistence를 제공한다, 즉 특정 시점에 Redis에 저장되어 있는 데이터들을 캡쳐하여 저장하고 필요할 때 저장한 파일을 이용해 복구를 한다.

 

 

Redis 7.4.0 기준으로 아래 사진과 같은 명령어를 통해 RDB의 기본 설정 값을 확인할 수 있는데 해당 응답이 의미하는 것은

 

- save : blocking 방식으로 잠시 정지하고 SnapShot을 저장
- 3600 1 : 3600초동안 1개 이상의 데이터가 변경되는 경우
- 300 100 : 300초 동안 100개의 데이터가 변하는 경우
- 60 10000 : 60초 동안 10000개의 데이터가 변하는 경우

 

RDB가 작동하여 dump.rdb 파일에 데이터를 백업한다.

 

save, bgsave

 

설정중에 Save, BgSave 를 설정할 수 있는데

 

Save : 위에서 설명한 것처럼 Blocking 방식이다. 명령 처리를 잠시 멈추고 SnapShot을 뜨고 저장한다.
BgSave : fork를 통해 자식 프로세스를 만들어서 SanpShot을 뜨고 저장한다. (non-blocking)

 

 

Redis FAQ 에 따르면 OS에서 copy-on-write를 지원해주기 때문에 fork로 인한 메모리 사용 급증이 크진 않지만 page가 변경되면서 메모리 사용량이 커질 경우 Setting overcommit_memory 를 1로 설정함으로 메모리 할당을 더 optimistic하게 해줄 수 있다.

 

 

RDB 주기

 

그 아래 SnapShot 주기 설정 같은 경우는 or로 동작하며 사용자가 자신의 상황에 맞게 설정이 가능하다.

config set save "100 1"
config set "" -> RDB 사용 안함

 

만약 어느정도의 데이터 손실을 허용할 수 있다하면 주기를 늘려서 Redis 서버에 부담을 줄일 수 있고 손실을 허용할 수 없다고하면 주기를 매우 짧게 가져갈 수도 있다, 다만 이럴경우 서버에 부담이 많이 갈 것이고 Redis를 사용하는게 맞을까에 대한 고민도 필요할 것이다.

 

 

lastsave라는 커맨드를 통해 제일 최근에 RDB에 저장된 unix 시간을 가져올 수 있다.

 

 

AOF(Append Only File)란?

 

AOF는 Write를 수행할 때마다 해당 작업에 대한 log를 모두 저장하는 방식이다. 해당 로그를 통해 데이터 손실이 있거나 서버를 재시작할 때 데이터를 원하는 시점으로 재구성할 수 있다.

 

flush 주기

 

정확히는 wirte command를 aof_buffer에 저장을 하고 있다가 flush을 통해 디스크에 저장을 하는데

  • always : (매번 저장 데이터 손실률이 적지만 성능이 떨어진다.)
    • (매번 disk 작업도 한다면 사실상 일단 disk 기반 DB와 크게 다를게 있을까?)
  • everysec : (기본 설정) 적당한 성능과 안정성을 보장해준다.
  • no : OS에 위임을 하여 보통 수십초마다 flush를 하게 된다. (성능은 제일 좋지만 안정성이 떨어진다.)

 

 

rewrite

 

이렇게 모든 write command에 대해 로그를 저장하게 되면 로그를 저장하는 파일의 크기가 커질 수 밖에 없다, 일정 기준을 넘어가게 되면 OS 파일 사이즈의 제한에 걸릴수도 있고 추후 복구를 할 때 너무 오랜 시간이 걸릴 수 있다.

 

 

만약 특정 key에 대해서 10번의 업데이트가 일어났다고 하자, AOF 파일에는 10번의 커맨드가 모두 저장되어 있을 것이다, 여기서 rewrite를 할 때는 key의 최종 값만 저장을 하여 크기가 훨씬 더 작아진다, child 프로세스가 rewrite 작업을 수행하고 parent 프로세스는 계속 AOF 파일에 command를 저장한다, 그러다가 child 프로세스의 작업이 끝나면 현재 사용하던 AOF를 삭제하고 새로운 AOF 파일로 교체한다.

 

 

auto-aof-rewrite-percentage 명령어를 rewrite를 실행할 파일 크기의 시점을 정할 수 있는데 100으로 설정할 경우 설정할 당시 AOF 파일 사이즈의 100% 즉 2배가 될 때 rewite를 수행한다.

 

 

auto-aof-rewrite-min-size 명령어는 명령어 그대로 rewrite가 일어날 파일의 최소 사이즈를 정해준다. 즉 64mb로 설정했다면 파일 크기가 64mb를 넘을 때까지 rewrite를 수행하지 않는다.

 

 

무엇을 사용해야할까?

 

AOF는 모든 command를 저장하다보니 상대적으로 RDB보다 안정적이라 할 수 있지만 성능 측면에서 떨어질 수 있다, RDB도 snap shot을 만드는 주기에 따라 성능이 달라지겠지만 아래 redis.conf의 주석을 보면

Redis can create append-only base files in either RDB or AOF formats.
Using the RDB format is always faster and more efficient, and disabling it is only
supported for backward compatibility purposes.
aof-use-rdb-preamble yes

 

RDB의 성능이 효율적이고 빠르다고 하고있고 RDB 설정 default 값이 true임을 알 수 있다. (Redis 5.0.0 이후 버전을 사용하는 경우에는 기본 설정이 AOF, RDB를 동시에 사용하게 되어있다)

 

즉 데이터 손실을 감수할 수 있다면 RDB만 사용하고 없다면 RDB는 상황에 맞게 어느정도 여유있는 간격으로 설정하고 AOF를 같이 사용하되 상황에 맞게 주기를 설정하면 되지 않을까 싶다!

 

 

결론


이전글에 이어 Redis를 공부하면서 어떤 식으로 작동하는지 보다 더 자세하게 알게되었다, 업무에서 사용할 상황이 생기면
어떤 식으로 사용할건지 근거를 가지고 잘 설명할 수 있을것 같다!