Redis 가 디스크에 데이터를 쓰는 방법
지속성은 SSD(Solid-State Disk)와 같이 내구성이 뛰어난 스토리지에 데이터를 기록하는 것을 말합니다. Redis는 다양한 지속성 옵션을 제공합니다.
- RDB(Redis Database): RDB 지속성은 지정된 간격으로 데이터 세트의 특정 시점 스냅샷을 수행합니다.
- AOF(파일만 추가): AOF 지속성은 서버가 수신한 모든 쓰기 작업을 기록합니다. 그런 다음 서버 시작 시 이러한 작업을 다시 재생하여 원래 데이터 세트를 재구성할 수 있습니다. 명령은 Redis 프로토콜 자체와 동일한 형식으로 기록됩니다.
- 지속성 없음: 지속성을 완전히 비활성화할 수 있습니다. 이는 캐싱할 때 사용하기도 합니다.
- RDB + AOF: AOF와 RDB를 동일한 인스턴스에서 모두 결합할 수도 있습니다.
RDB 장점
- Compactness(소형성) : RDB 파일은 특정 시점의 Redis 데이터를 매우 소형의 단일 파일로 제공합니다. 이러한 소형성은 백업 및 보관 목적으로 이상적입니다.
- 배업 유연성 : RDB를 사용하면 최신 24시간 동안 매 시간 파일을 보관하고, 30일 동안 매일 스냅샷을 저장하는 등 백업 일정을 쉽게 설정할 수 있습니다. 이러한 유연성은 재해 발생 시 데이터 복원을 용이하게 해줍니다.
- 재해 복구 : RDB 파일은 재해 복구를 위해 탁원한 해결책으로써, 단일 소형 파일로서 원격 데이터 센터로 쉽게 전송하거나 Amazon S3와 같은 클라우드 저장소에 저장할 수 있습니다. 선택적으로 암호화하여 보안을 강화할 수 도 있습니다.
- 성능 최적화 : RDB는 Redis 성능을 최대화 하고, 디스크 I/O 작업을 부모 프로세스가 수행하지 않도록 하여 Redis 성능에 최소한의 영향을 미치도록 합니다.
- 빠른 재시작 : 대용량 데이터 세트의 경우 AOF와 비교하여 RDB를 사용하면 빠른 재시작이 가능합니다. RDB는 데이터를 단일 소형 파일에 기록하므로 재시작 프로세스가 빠르고 효율적 입니다.
- 복제 지원 : RDB는 재시작 및 장애 조치 후 복제본에서 부분적인 재동기화를 지원합니다. 이 기능은 Redis 복제의 탄력성과 신뢰성을 향상시키며, 본제본이 마스터 노드와 데이터를 효과적으로 복구하고 동기화 할 수 있도록 합니다.
RDB 단점
- 데이터 손실 가능성: Redis 가 작동을 중지할 경우, 데이터 손실 가능성을 최소화해야 하는 경우에는 RDB가 적합하지 않습니다. RDB는 여러 가지 저장 지점을 구성할 수 있지만(예: 최소 다섯 분마다 데이터 집합에 대해 100회 이상의 쓰기 작업후), 일반적으로 다섯 분마 또는 그 이상마다 RDB 스냅샷을 생성합니다. 따라서 Redis가 올바른 종료 없이 중지되는 경우 최신 데이터의 몇 분을 잃을 수 있습니다.
- fork() 사용 : RDB는 디스크에 데이터를 기록하기 위해 자식 프로세스를 사용하기 때문에 fork()를 자주 사용해야 합니다. 데이터 집합이 크면 fork() 가 시간이 많이 소요될 수 있으며, 데이터 집합이 매우 크거나 CPU 성능이 좋지 않으면 Redis 가 일부 밀리초 또는 초 단위로 클라이언트 서비스를 중지할 수 없습니다. AOF도 fork()를 사용하지만 덜 자주 발생하며, 내구성에 대한 어떠한 트레이드 오프 없이 로그를 얼마나 자주 다시 작성할지를 조정할 수 있습니다.
AOF 장점
- 내구성 향상 : AOF를 사용하면 Redis가 훨신 내구성이 높아집니다. 다양한 fsync정책을 사용할 수 있습니다. fsync 전혀 없음, 매초 마다 fsync 하기, 모든 쿼리하다 fsync 하기 등, 기본 정책으로 매 초하마다 fsync하는 경우에도 쓰기 성능이 여전히 훌륭합니다. fsync는 백그라운드 스레드를 사용하여 수해되며, 메인 스레드는 fsync가 진행 중이 아닐 때 쓰기를 위해 노력합니다. 따라서 1초 분량의 쓰기만 손실할 수 있습니다.
- AOF 로그의 안정성 : AOF 로그는 증가만 가능한 로그이므로 검색이 없으며, 전원 장애가 발생할 경우 손상 문제가 없습니다. 심지어 로그가 어떤 이유로 인해 반즘 쓰여진 명령으로 끝난다 해도(디스크가 가득 찬 경우 등), redis-check-aof 도구를 사용하여 쉽게 수정할 수 있습니다.
- 작동 재작성: Redis는 AOF가 너무 커질 때 자동으로 백그라운드에서 재작성할 수 있습니다. 재작성은 완전히 안전하며, Redis가 이전 파일에 계속 추가하는 동안 현재 데이터 집합을 생성하는 데 필요한 최소한의 작업 집합으로 완전히 새로운 파일이 생성되며, 두 번재 파일이 준비되면 Redis가 두 파일을 교체하고 새 파일에 추가를 시작합니다.
- 쉬운 이해와 파싱: AOF에는 각각의 작업이 쉽게 이해하고 구문 분석할 수 있는 형식으로 하나씩 기록됩니다. 심지어 FLUSHALL 명령을 실수로 실행했더라도, 로그를 제작성하는 동안 아무 작업을 수행하지 않는다면 서버를 중지하고 최신 명령을 제거한 다음 Redis를 다시 시작함으로써 데이터 집합을 저장할 수 있습니다.
AOF 단점
- AOF 파일 크기 : 동일한 데이터 집합에 대한 AOF 파일은 일반적으로 동등한 RDB 파일 보다 큽니다. 이는 AOF 파일이 각 쓰기 작업을 기록하기 떄문입니다.
- 성능 : AOF는 정확한 fsync 정책에 따라 RDB보다 느릴 수 있습니다. 일반적으로 fsync를 1초마다 설정하면 성능이 여전히 매우 높지만, fsync를 비활성화하면 높은 부하에서도 RDB와 정확히 같은 속도를 제공할 수 있습니다. 그럼에도 불구하고, RDB는 엄청난 쓰기 부하가 발생하는 경우에도 최대 지연에 대한 더 많은 보장을 제공할 수 있습니다.
Redis < 7.0 이전버전
- Redis 7.0 이전 버전에서는 AOF가 리라이트 중에 데이터베이스에 쓰기가 발생하면 많은 메모리를 사용할 수 있습니다. 이러한 쓰기는 메모리에 버퍼링되어 새 AOF 파일의 끝에 기록도비니다. 리라이트 중에 도착하는 모든 쓰기 명령은 디스크에 두 번 기록됩니다. Redis는 리라이트가 끝날 때 새 AOF파일로의 쓰기와 fsyncing을 멈출 수 있습니다.
그래서 무엇을 사용해야 할까?
일반적으로 두 지속성 방법을 모두 사용해야 하는 경우는 PostgreSQL이 제공하는 데이터 안정성 수준과 유사한 수준의 데이터 안정성을 워하는 경우입니다.
데이터에 대한 중요성은 높지만 재해 발생 시 몇 분 동안의 데이터 손실은 감수할 수 있는 경우에는 RDB만 사용하는 것이 좋습니다.
AOF만 사용하는 사용자들도 많지만, AOF 엔진의 버그 발생 시 RDB 스냅샷을 가지고 있는 것이 데이터베이스 백업, 더 빠른 재시작, 그리고 안정성을 고려할 때 훌륭한 아이디어라고 생각하며 AOF만 사용하는 것을 권장하지 않습니다.
스냅샷팅
스냅샷팅은 Redis가 기본적으로 데이터 집합의 스냅샷을 이진 파일은 dump.rdb로 디스크에 저장하는 방식입니다. Redis를 구성하여 데이터 집합에 변경 사항이 있을 때마다 디스크에 저장하는 방식입니다. Redis를 구성하여 데이터 집합에 변경 사항이 있을 때마다 N초마다 스냅샵을 저장하거나, 수동으로 SAVE 또는 BGSAVE 명령을 호출할 수 있습니다. 예를 들어, 다음 구성은 Redis가 데이터 집합에 변경사항이 있을 때마다 적어도 1000개의 키가 변경되면 매60초마다 데이터 집합을 자동으로 디스크에 덤프하는 것입니다
save 60 1000
이 전략은 스냅샷팅이라도 알려져 있습니다.
이것이 작동하는 방식은 다음과 같습니다:
Redis가 데이터 집합을 디스크에 덤프해야 될 때:
- Redis는 fork 합니다. 이제 부무와 식 프로세스가 있습니다.
- 자식은 데이터 집합을 임시 RDB 파일에 쓰기를 시작합니다.
- 자식이 새로운 RDB 파일 쓰기를 완료하면, 이를 이진 파일로 대체합니다.
이 방법을 통해 Redis는 복사 시에 쓰기 의미론(copy-on-write semantics)을 활용할 수 있습니다.
AOF (Append-only file)
AOF (Append-only file)
추가 기록 파일(AOF)은 Redis의 대안적이고 완전히 내구성이 있는 전략입니다. 이는 서버가 받는 모든 쓰기 작업이 파일에 로그로 기록되어 데이터에 완전한 내구성을 제공합니다. 스냅샷팅이 데이터 집합의 스냅샷을 주기적으로 저장하는 반면, AOF는 모든 쓰기 작업을 로그에 기록하여 예상치 못한 충돌 또는 장애에 강력한 내성을 제공합니다.
AOF를 사용하는 경우:
- Redis가 받는 모든 쓰기 작업이 AOF 파일에 기록됩니다.
- 서버가 예기치 않게 중지되거나 시스템이 충돌해도, Redis는 AOF 파일에서 기록된 작업을 다시 재생함으로써 데이터 집합을 복구할 수 있습니다.
- AOF는 전원 손실이나 인스턴스 종료와 같은 급격한 상황에서도 데이터가 손실되지 않도록 보장합니다.
- AOF는 데이터 안전성과 성능 사이의 균형을 맞추a기 위해 다양한 fsync 정책으로 구성할 수 있습니다.
AOF를 활성화하려면 Redis 구성 파일에서 설정할 수 있습니다. 이렇게 하면 Redis가 AOF 지속성 메커니즘을 사용하게 됩니다:
appendonly yes
AOF를 활성화하면 Redis가 지속적으로 쓰기 작업을 AOF 파일에 추가하여 데이터에 내구성과 신뢰성을 제공합니다.
Redis는 이제부터 데이터 집합을 변경하는 명령(예: SET)을 받을 때마다 해당 명령을 AOF에 추가합니다. Redis를 다시 시작하면 AOF를 재생하여 상태를 다시 구축합니다.
Redis 7.0.0부터 Redis는 다중 부분 AOF 메커니즘을 사용합니다. 즉, 원래의 단일 AOF 파일이 기본 파일(최대 하나)과 증분 파일(하나 이상)로 분할됩니다. 기본 파일은 AOF가 다시 쓰여질 때 존재하는 데이터의 초기( RDB 또는 AOF 형식) 스냅샷을 나타냅니다. 증분 파일에는 마지막 기본 AOF 파일이 생성된 이후의 증분 변경 사항이 포함됩니다. 이러한 모든 파일은 별도의 디렉터리에 넣어지고 매니페스트 파일에 의해 추적됩니다.
로그 재작성
AOF가 쓰기 작업이 수행됨에 따라 점점 커집니다. 예를 들어, 카운터를 100번 증가시키는 경우, 데이터 집합에는 최종 값이 포함된 단일 키가 있지만 AOF에는 100개의 항목이 있습니다. 이 중 99개의 항목은 현재 상태를 재구축하는 데 필요하지 않습니다.
리라이트는 완전히 안전합니다. Redis가 이전 파일에 계속 추가하는 동안 현재 데이터 집합을 만드는 데 필요한 최소한의 작업 집합으로 완전히 새로운 파일이 생성되며, 이 두 번째 파일이 준비되면 Redis가 두 파일을 전환하여 새 파일에 추가를 시작합니다.
따라서 Redis는 흥미로운 기능을 지원합니다: 클라이언트에게 서비스를 중단하지 않고 배경에서 AOF를 다시 작성할 수 있습니다. BGREWRITEAOF를 실행하면 Redis가 메모리에 있는 현재 데이터 집합을 재구성하는 데 필요한 가장 짧은 명령 순서를 작성합니다. Redis 2.2를 사용하는 경우 AOF를 사용 중이라면 시간이 지남에 따라 가끔 BGREWRITEAOF를 실행해야 합니다. Redis 2.4부터는 로그 다시 쓰기를 자동으로 트리거할 수 있습니다(자세한 정보는 예제 구성 파일을 참조하십시오).
Redis 7.0.0부터 AOF 다시 쓰기가 예약되면 Redis 부모 프로세스는 계속 쓰기를 계속하기 위해 새로운 증분 AOF 파일을 엽니다. 자식 프로세스는 리라이트 로직을 실행하고 새로운 기본 AOF를 생성합니다. Redis는 새로 생성된 기본 파일과 증분 파일을 추적하기 위해 임시 매니페스트 파일을 사용합니다. 준비되면 Redis는 이러한 임시 매니페스트 파일을 원자적 교체 작업을 수행하여 적용합니다. AOF 리라이트가 반복되는 실패와 재시도의 경우 많은 증분 파일이 생성되는 문제를 피하기 위해 Redis는 AOF 리라이트 제한 메커니즘을 도입하여 실패한 AOF 리라이트가 점차적으로 느리게 재시도되도록 보장합니다.