번역 페이지

https://redis.io/topics/persistence


용어 설명

 아래 번역글에서 사용되는 용어들에 대해서 간단히 설명을 합니다. 

 Persistence : 영속성이라고 번역되며 데이터를 생성한 프로그램의 실행이 종료되더라도 사라지지 않는 데이터의 특성

 Durability : 지속성이라고 하며 성공적으로 수행된 트랜잭션은 영원히 반영되어야 함을 의미한다.

 RDB : .rdb 형태의 레디스의 데이터 셋을 스냅샷 형태 저장하는 방식

 AOF : Append Only File로 입력된 operator를 파일에 추가해서 저장하는 방식

 fsync : 파일의 내부 상태를 장치와 동기화시키는 함수 (버퍼에 있는 데이터를 파일로 옮깁니다.) 


 이 페이지는 레디스의 persistence에 대한 기술적인 설명을 제공합니다. 

 모든 레디스 유저들에게 제안된 내용입니다. 

 레디스의 persistence와 durability가 제공하는 보장에 대한 자세한 내용은 링크 를 참조하세요

Redis Persistence(영속성)

 레디스는 영속성 옵션을 다양하게 제공합니다. 

 ▶ RDB 영속성은 명시된 간격마다 dateset의 해당 시점의 스냅샷을 수행합니다. 

 ▶ AOF 영속성은 서버로 수신된 모든 쓰기 작업을 기록하고 서버 재시작 시 수행돼서 원래의 데이터 셋을

     재구축합니다.

     command들은 추가 전용 방식으로 Redis 프로토콜과 동일한 형식으로 기록됩니다. 

     레디스는 로그가 너무 커지면 백그라운드에서 로그를 rewrite(재작성) 할 수 있습니다.

 ▶ 서버가 수행 중인 동안에만 데이터를 존재하게 하려면 영속성을 완전히 비활성화할 수 있습니다. 

 ▶ 동일한 인스턴스 안에서 AOF와 RDB를 결합해서 사용할 수 있습니다. 이 경우에는 Redis가 재시작될 때 AOF파일이

     가장 완벽한 보장이므로 원본 데이터 셋을 재구성하는 데 사용됩니다. 

이해해야 될 가장 중요한 것은 RDB와 AOF 영속 성간의 서로 다른 절충점입니다. RDB부터 시작합니다. 

RDB의 장점

 ▶ RDB는 레디스 데이터의 단일 시점의 표현에 대한 매우 작은 하나의 파일입니다. RDB는 백업에 완벽합니다.

     예를 들면 최근 24시간 동안 매시간마다 RDB파일을 archive 하고 30일 동안 매일 RDB 스냅샷을

     저장하려고 할 수 있습니다. 이것은 재난상황에서 데이터 셋의 다른 버전을 쉽게 복원할 수 있습니다. 

 ▶ RDB은 멀리 있는 데이터센터나 아마존 S3로 전송할 수 있는 하나의 콤팩트한 파일 이어서 재난 복구에 매우

     적합합니다.(암호화 가능)

 ▶ RDB를 사용하면 영속성을 유지하기 위해서 레디스의 부모 프로세스가 수행할 작업은 영속성 작업을 수행할

     자식 프로세스를 forking 하는 일뿐이라서 레디스의 성능을 최대화합니다. 

     부모 인스턴스는 디스크 I/O를 수행하지 않습니다. 

 ▶ RDB는 AOF와 비교해서 큰 데이터 셋으로 더 빠르게 재시작됩니다. 

RDB의 단점

 ▶ RDB는 레디스의 작동이 멈춘 경우 데이터 손실의 가능성을 최소화해야 한다면 좋은 선택이 아닙니다. 

     RDB가 생성되는 다른 저장 지점을 설정할 수 있습니다.

     (예를 들어 최소 5분과 데이터셋에 100번 쓰기 후에 다양한 저장 지점을 가질 수 있습니다.)

     그러나 일반적으로 최소한 5분마다 RDB 스냅샷이 생성되고 어떤 이유로든 올바른 종료 없이 레디스가 작동을 

     멈춘다면 최근의 몇 분의 데이터를 잃어버릴 준비를 해야 합니다. 

 ▶ RDB는 자식 프로세스를 사용해서 디스크에 영속성을 유지하려면 자주 fork()해야 합니다. 

     Fork()는 데이터 셋이 큰 경우 많은 시간이 소비될 수 있고 만약에서 데이터 셋이 매우 크고 CPU의 성능이 좋지

     않다면 몇 밀리초 또는 1초 동안 레디스의 클라이언트 서비스를 멈추게 할 수도 있습니다.

     AOF도 Fork()가 필요하지만 durability의 어떠한 성능 감소 없이 로그를 rewrite 하는 빈도를 수정할 수 있습니다. 

 

AOF의 장점

 ▶ AOF를 사용하는 레디스는 훨씬 durable 합니다. 다양한 fsync 정책을 가질 수 있습니다

    : fsync 전혀 없음, 매 초당 fsync, 모든 쿼리에 fsync

    기본 정책인 초당 fsync의 쓰기 성능은 우수하지만 1초 분량의 데이터가 손실될 수 있습니다. 

 ▶ AOF 로그는 추가 전용이어서 정전이 발생해도 seeks나 데이터 오염 문제가 발생하지 않습니다. 

    어떠한 이유로 로그가 절반만 작성된 command도 redis-check-aof 툴로 쉽게 고칠 수 있습니다.

 ▶ 레디스는 AOF이 너무 커졌을 때 백그라운드에서 자동으로 재작성할 수 있습니다. 

    레디스가 이전 파일에 계속 추가되는 동안 재작성이 완벽히 안전하며 현재의 데이터 셋을 생성하는데

    필요한 최소한의 작업들로 새로운 파일이 생성되고 두 번째 파일이 준비되면 두 개의 파일을 switch 하고

    새로운 파일에 로그를 기록하기 시작합니다. 

 ▶ AOF는 이해와 분석하기 쉬운 형식으로 모든 작업의 로그를 가집니다. AOF 파일을 쉽게 내보낼 수 있습니다.

    예를 들면 FLUSHALL command를 사용해서 실수로 모든 것을 flush 하더라도 그동안에 로그 rewrite가 수행되지

    않은 경우 서버를 멈추고 최신 입력된 명령을 제거한 후 레디스를 다시 시작하는 것만으로 데이터 셋을

    저장할 수 있습니다.

AOF의 단점

 ▶ AOF 파일은 일반적으로 동일한 데이터 셋의 RDB 파일보다 큽니다. 

 ▶ AOF는 정밀한 fsync 정책에서는 RDB보다 느릴 수 있습니다. 일반적으로 매 초마다 fsync가 수행되는 방식은 여전히

    성능이 좋고 fsync를 비활성화하면 높은 부하에서도 RDB만큼 빠릅니다. 

    RDB는 엄청난 쓰기 부하에서도 최대 지연에 대해서 속도 보장을 제공할 수 있습니다. 

 ▶ 과거에는 특정 command안에서 드물게 버그가 발생해서 (BRPOPLPUSH같은 블로킹을 포함하는 것들) AOF가 다시

    로드될 때 완벽한 데이터셋을 만들어 내지 못했습니다.

 

무엇을 사용하면 될까요?

 일반적으로 PostgreSQL이 제공하는 것과 비슷한 수준의 데이터 안정성을 원한다면 두 가지 영속성 방식을 모두

 사용해야 합니다.

 만약에 재난상황에서 몇 분의 데이터가 손실되어도 괜찮다면 RDB만 사용하면 됩니다. 

 많은 사용자들이 AOF만 홀로 사용하지만 권장하지 않습니다.  RDB의 스냅샷을 생성하는 것은 데이터 베이스 백업,

 빠른 재시작 및 AOF 엔진 안의 버그가 있는 경우에 좋은 대안이기 때문입니다.

 Note : 이러한 모든 이유로 추후에 AOF와 RDB를 하나의 영속성 모델로 통합할 것입니다.(장기 계획)

 다음 섹션에서는 두 가지 영속성 모델에 대해서 자세한 내용을 설명합니다. 

 

Snapshotting

 레디스는 기본적으로 dump.rdb라고 부르는 바이너리 파일 안에 데이터셋을 저장합니다. 

 데이터 세트에 N초마다 M개 이상의 변경사항이 있는 경우 저장하도록 설정하거나 SAVE 또는 BGSAVE 명령을

 수동으로 호출할 수 있습니다.

 예를 들면 이 설정 구성은 60초마다 1000개의 키들이 변경되면 디스크의 데이터 세트를 자동으로 덤프 하도록 합니다.

save 60 1000

 이 전략은 스냅샷이라고 부릅니다. 

 작동원리 : 레디스가 데이터 세트를 디스크에 덤프 할 때 일어나는 일입니다. 

  • 레디스는 fork를 통해서 자식 프로세스를 생성합니다. 
  • 자식 프로세스는 임시 RDB파일에 데이터 세트를 작성하기 시작합니다. 
  • 자식 프로세스가 새로운 RDB파일 작성이 끝나면 이전의 것과 변경합니다. 

  이 방식을 사용하면 레디스는 copy-on-write 용법을 활용할 수 있습니다. 

 

Append-only file

 snapshotting은 durable이 떨어집니다. 만약 정전 또는 실수로 인스턴스에 kill -9를 실행으로 수행 중인 레디스가 멈추면

 레디스에 작성된 최신의 데이터를 잃을 것입니다. 

 일부 응용프로그램에서는 문제가 아니지만 완전한 durability가 필요한 경우에는 snapshotting은 선택할 수 없습니다. 

 append-only file은 완전한 durable 전략을 위한 대안입니다.  version 1.1부터 사용할 수 있습니다. 

 구성 파일 안에서 AOF을 켤 수 있습니다. 

appendonly yes

 지금부터는 레디스가 dateset을 변경하는 command를 수신할 때마다 AOF에 추가됩니다. 

 레디스를 재시작할 때 상태를 재구성하는 AOF가 수행됩니다. 

Log rewriting

 예상하듯이 쓰기 작업이 수행되면서 AOF의 크기가 커집니다. 

 예를 들어 100회 동안 카운터를 증가시켰다면 dataset에는 최종 값에 해당하는 하나의 키만 들어 있지만

 AOF에는 100개의 항목이 있고 99개는 현재의 상태를 재구성하는데 필요하지 않습니다. 

 그래서 레디스는 흥미로운 기능을 지원합니다.

 클라이언트에 대한 서비스 중단 없이 백그라운드에서 AOF를 재구성할 수 있습니다. 

 BGREWRITEOF를 레디스에 요청할 때마다 메모리에서 현재의 dataset을 재구성하는데 필요한 최소한의 명형

 시퀀스를 작성합니다. 

 만약 레디스 2.2 버전에서 AOF를 사용하는 경우 때때로 BGREWRITEAOF 실행해야 합니다.

 레디스 2.4에서는 rewriting을 자동으로 발동시킬 수 있습니다.(자세한 정보는 2.4 버전의 구성파일 참조)

AOF는 얼마나 내구성이 좋은가?

 레디스가 디스크의 데이터에 fsync를 얼마나 수행할지 설정할 수 있습니다. 세 가지 옵션이 있습니다. 

 ▶ appendfsync alway : 매번 새로운 command가 AOF에 추가될 때마다 fsync 수행. 매우 매우 느림, 매우 안전

 ▶ appendfsync everysec : fsync 매 초마다 수행. 충분히 빠름(2.4 버전에서는 스냅숏만큼 빠름)                             

     재난 발생 시 1초의 데이터를 잃을 수 있습니다. 

 ▶ appendfsync no : fsync를 사용하지 않음. 운영체제에 의해서 다루어짐. 빠르지만 안정성이 떨어짐 

     일반적으로 이 설정으로 리눅스는 30초마다 데이터를 flush 합니다. 그러나 커널의 튜닝에 따라서 달라집니다.

 제안(기본)되는 정책은 매 초마다 fsync를 하는 것입니다. 이것은 매우 빠르며 안전합니다. 

 alway정책은 실제로 매우 느리지만 group commit을 지원합니다. 그래서 레디스에 여러 개의 병렬 쓰기는

 하나의 fsync 작업으로 수행됩니다.

 

AOF가 잘리면 어떻게 해야 할까요?

 AOF 파일이 작성되는 동안 서버가 커지거나 AOF파일 작성 시점에 저장공간이 가득 찬 경우 가능합니다.

 이런 일이 발생해도 AOF에는 dataset의 특정 시점의 데이터가  (AOF가 기본 설정이라면 1초 전 데이터 일 수 있음)

 저장되어 있지만 AOF의 마지막 명령어를 잘릴 수 있습니다.

 최근의 레디스 버전은 AOF를 로딩할 수 있지만 파일 마지막의 잘못된 형식의 명령은 제거됩니다. 

 이러한 경우 서버는 다음과 같은 로그를 발생시킵니다. 

* Reading RDB preamble from AOF file...
* Reading the remaining AOF tail...
# !!! Warning: short read while loading the AOF file !!!
# !!! Truncating the AOF at offset 439 !!!
# AOF loaded anyway because aof-load-truncated is enabled

원한다면 이런 경우가 발생하면 레디스를 강제로 중단하도록 설정을 변경할 수 있습니다. 

그러나 기본 설정은 재시작 후에 가용성을 보장하기 위해서 파일의 마지막 명령어가 잘못된 형식이라도 이것을

 무시하고 계속 수행되도록 하는 것입니다.

 ( 가용성 : IT에서는 서비스를 지속적으로 제공하는 것을 말함 )

 이전 버전의 레디스는 복구되지 않을 수 있고 다음 단계를 수행해야 할 수 있습니다

 ▶ AOF파일의 백업 파일을 생성합니다.

 ▶ 레디스에서 제공하는 redis-check-aof 툴을 사용해서 원본 파일을 수정합니다. 

$ redis-check-aof --fix

 ▶ 두 파일의 차이를 확인하려면 diff -u를 사용하세요

 ▶ 수정된 파일로 서버를 재시작합니다.

 

AOF 파일이 손상되면 어떻게 하나요?

 AOF파일이 단순히 잘린 것이 아니고 중간에 잘못된 바이트 순서로 손상된 경우에는 복잡해집니다. 

 레디스는 시작 시 오류를 발생시키고 중단될 것입니다.

* Reading the remaining AOF tail...
# Bad file format reading the append only file: make a backup of your AOF file, then use ./redis-check-aof --fix <filename>

 가장 좋은 해결방법은 --fix 옵션 없이 redis-check-aof 툴을 실행 한 다음 문제점을 확인하고

 파일 안이 해당하는 오프셋으로 이동해서 파일을 수동으로 복구할 수 있는지 확인하는 것입니다. 

 AOF는 레디스 프로토콜과 같은 형식을 사용해서 수동으로 수정하는 것은 매우 간단합니다.

 그렇지 않으면 파일을 툴로 수정하도록 할 수 있지만 이렇게 하면 AOF의 유효하지 않은 부분에서 파일 끝까지의

 부분이 제거될 수 있으며 만약에 파일 시작 부분에 손상이 발생한 경우 대량의 데이터 손실 발생합니다.

 

rewrite 동작 방식

 로그 rewriting은 snapshotting에서 사용한 copy-on-write 트릭을 사용합니다. 

 ▶ 레디스는 fork를 통해서 자식 프로세스를 생성합니다.

 ▶ 자식 프로세스는 임시 파일에 새로운 AOF를 작성하기 시작합니다. 

 ▶ 부모 프로세스는 인 메모리 버퍼에 새로운 변경 사항을 축적합니다.

     (동시에 이전 AOF파일에 새로운 변경사항을 저장하기 때문에 rewrite가 실패해도 안전합니다.)

 ▶ 자식 프로세스의 rewring파일 작성이 끝나면 부모 클래스는 신호를 받고 자식 프로세스가 생성한 AOF파일 끝에 

     인 메모리 버퍼에 축적한 내용을 추가합니다. 

 ▶ 이제 레디스는 원자적(atomically)으로 새로운 파일의 이름을 이전 파일의 이름으로 변경하고 새로운 파일에

     새로운 데이터를 추가하기 시작합니다.  

 

dump.rdb를 사용중인 경우에 AOF로 변경하는 방법 

 레디스 2.0과 2.2는 서로 다른 방식을 따릅니다. 짐작하듯이 레디스 2.2에서는 더 간단하고 다시 시작할 필요가

 없습니다.

 Redis >= 2.2

 ▶ 최신의 dump.rdb파일의 백업을 생성합니다. 

 ▶ 안전한 곳으로 백업을 이동시킵니다. 

 ▶ 두 명령어를 실행 시킵니다.

 ▶ redis-cli config set appendonly yes

 ▶ redis-cli config set save ""

 ▶ 데이터 베이스에 포함된 키와 동일한 키를 가지는지 확인하세요

 ▶ 쓰기 작업이 append only file에 올바르게 추가되는지 확인하세요

 첫번째 config 명령어는 append only file을 활성화합니다. 

 활성화 작업을 위해서 레디스는 첫 dump를 생성하려고 block합니다. 그러고 나서 그 파일을 쓰기 위해서 연 다음에

 다음의 모든 쓰기 쿼리를 추가하기 시작할 것입니다.

 두번째 config 명령어는 snapshotting 영속성을 끄는데 사용됩니다. 이것은 선택사항입니다.

 원한다면 두 가지 영속성 모두를 활성화 할 수 있습니다. 

 중요사항 : AOF를 키려면 redis.conf를 수정 해야 합니다. 그렇지 않으면 서버가 재시작 될 때 설정 변경사항은

               손실되며 서버는 이전 설정으로 다시 시작 될 것입니다.

 Redis 2.0

 ▶ 최신의 dump.rdb 파일의 백업을 생성합니다. 

 ▶ 안전한 곳으로 백업을 이동시킵니다. 

 ▶ 데이터 베이스에 대한 모든 쓰기 작업을 중단합니다.

 ▶ Redis-cli BGREWRITEAOF를 실행합니다. append only file이 생성됩니다. 

 ▶ AOF파일 생성이 끝나면 서버를 중단 시킵니다. 

 ▶ Redis.conf의 append only file 영속성을 활성화 합니다. 

 ▶ 서버를 재시작 합니다.

 ▶ 데이터 베이스에 포함된 키와 동일한 키를 가지는지 확인하세요

 ▶ 쓰기 작업이 append only file에 올바르게 추가되는지 확인하세요

 

AOF와 RDB간이 상호작용

 레디스 2.4 이상인 경우에는 RDB 스냅샷이 이미 수행중일 때 AOF rewrite의 발동이나 AOF rewrite가 수행중일 때

 BGSAVE를 허용하지 않습니다. 

 이것은 두개의 백그라운드 프로세스가 동시에 많은 디스크 I/O를 수행하는 것을 방지합니다. 

 스냅샷이 수행중일 때 사용자가 서버에 BGREWRITEAOF를 사용해서 명시적인 요청하면 작업이 예약되었음을 알리는

 OK 상태 코드를 응답하고 스냅샷이 완료되면 rewrite가 시작됩니다. 

 AOF와 RDB가 동시에 활성화 되어 있고 레디스가 재시작 하는 경우에는 AOF파일이 가장 완벽한 보장되므로 dataset을 

 재구성하는데 사용됩니다. 

 

레디스 데이터 백업 

 이 섹션을 시작하기 전에 이 문장을 읽도록 하세요 : 데이터 베이스 백업을 확인하세요

 디스크가 고장나거나 클라우드 인스턴스가 사라지는 등으로 백업이 없다면 데이터가 사라질 위험이 큽니다. 

 레디스는 수행되는 동안 RDB파일 복사가 가능하기 때문에 데이터 백업에 매우 친화적입니다. 

 RDB는 한번 생성되면 수정되지 않고 생성되는 동안 임시이름을 사용하고 오직 새로운 스냅샷이 완료 될 때만 

 Rename을 사용해서 원자적으로 이름을 바꿉니다. 

 이것은 서버가 수행되는 동안 RDB 복사가 완벽히 안전하다는 것을 의미합니다. 

 다음은 우리가 제안하는 내용입니다. 

 ▶ 서버에서 cron job을 생성해서 한 디렉토리에 RDB파일을 시간마다 다른 디렉토리에는 일별로 스냅샷을 생성하세요

 ▶ Cron 스크립트가 수행될 때마다 너무 오래된 스냅샷이 삭제되도록 find 명령어를 호출 하세요

     (리눅스의 find 명령어로 파일을 삭제 할 수 있습니다.)

     예를 들면 최근 48시간의 시간별 스냅샷 파일과 1~2달의 일별 스냅샷 파일을 가질 수 있습니다.

     데이터 및 시간 정보를 사용해서 스냅샷 이름을 지정하세요

 ▶ 하루에 최소 한번은 RDB 스냅샷을 레디스가 수행중인 물리머신의 외부또는 데이터 센터 외부로 전송 해야 합니다.

 만약 AOF 영속성만 활성화 한 상태로 레디스를 수행중이라면 백업을 생성하기 위해서 AOF를 복사 할 수 있습니다. 

 AOF 파일의 마지막 부분이 잘릴 수 있지만 레디스는 그것을 읽을 수 있습니다. (이전 섹션 참조)

+ Recent posts