Database/Redis

[Redis] AOF 방식의 백업

꽁담 2020. 3. 4. 20:16

Redis AOF 백업 개념


Redis 는 백업을 위해 RDB 방식과 AOF 방식을 지원합니다.

이 중 AOF 방식에 대해 다뤄보겠습니다.

 

AOF 방식

AOF ( Append Only File ) 방식으로 명령이 실행될 때마다 해당 명령이 파일에 기록됩니다.

데이터 손실이 거의 없습니다.

* 거의라고 표현하는 이유는 명령이 실행되면 바로 작성하는게 아니라, 버퍼에 두었다가 주기적으로 파일에 쓰는 방식이기 때문입니다.

 

AOF 파일

기본값으로 appendonly.aof 파일에 기록됩니다.

조회 명령을 제외한 입력/수정/삭제 명령이 실행될 때마다 버퍼에 기록 후 파일로 동기화됩니다.

 

AOF Rewrite 기능

특정 시점에 데이터 전체를 다시 쓰는 기능(rewrite)이 있습니다.

파일이 너무 커지면 OS 파일 사이즈 제한에 걸리거나, 레디스 서버 시작 시 AOF 파일을 로드하는 시간이 많이 걸리기 때문입니다.

 

rewrite 를 하면 파일 사이즈가 작아집니다.

같은 Key 를 100번 수정하는 경우 AOF 에는 100번 수정한 내용이 모두 기록되지만, rewrite 를 하게 되면 최종 수정된 마지막 값만 남기 때문입니다.

예) INCR key가 1000번 수행되었다고 하면, 메모리에는 1000 하나만 남아있지만 AOF 파일에는 1000번이 기록되어 있습니다. rewrite 를 수행하면 이전 기록은 모두 사라지고 최종 데이터인 1000 값만 남아있습니다.

 

AOF 는 수정이 가능

text 파일이므로 수정이 가능합니다.

만약 명령어를 잘못 사용하여 데이터를 잘 못하여 모두 날린 경우, 해당 명령어를 AOF 파일에서 제거한 후 Redis 를 재부팅 하면 데이터 손실없이 DB 를 사용할 수 있습니다.

 

 

AOF 관련 redis.conf 파라미터


redis.conf 파일에서 AOF 관련 파라미터를 설정할 수 있습니다.

 

appendonly [ yes | no ]

yes 는 AOF 기능을 사용합니다. no 는 사용하지 않습니다.

레디스 서버 시작 시 yes 인 경우 AOF 파일을 읽고, no 는 AOF 파일이 있어도 읽지 않습니다.

 

appendfilename [ "filename" ]

AOF 파일명을 지정합니다.

경로는 지정할 수 없으며, 경로는 working directory 파라미터 값으로 결정됩니다.

 

appendfsync [ always | everysec | no ]

AOF 파일에 기록하는 시점을 정합니다.

always : 명령 실행 시 마다 AOF 파일에 기록합니다. 디스크 DB만큼 속도가 떨어지게 됩니다.

everysec : 1초마다 AOF 파일에 기록합니다. 1초 사이의 데이터가 유실될 수 있습니다.

no : AOF 파일에 기록하는 시점을 OS 가 지정합니다. 일반적으로 리눅스는 30초 간격으로 내려씁니다.

 

auto-aof-rewrite-percentage [ 0-100 ]

AOF 파일 사이즈가 숫자값 % 이상으로 커지면 rewrite 합니다.

% 의 기준은 레디스 서버가 시작할 시점의 AOF 파일 사이즈를 기준으로 합니다.

Rewrite 를 하면 rewrite 후 파일 사이즈를 기준으로 다시 계산합니다.

0 값인 경우 rewrite 를 하지 않습니다.

 

auto-aof-rewrite-min-size [ 64mb ]

AOF 파일 사이즈가 64mb 이하면 rewrite 를 하지 않습니다.

파일 크기가 작은 경우 rewrite 가 자주 발생하는 것을 방지합니다.

 

 

AOF Rewrite 동작 순서


 

1. 자식프로세스를 fork 합니다.

2. 자식 프로세스는 데이터를 새 AOF temp 파일에 작성합니다.

3. 부모 프로세스는 새로운 명령을 메모리 버퍼에 기록하면서 rewrite 작업이 실패해도 데이터를 보존하기 위해 현재 AOF 파일에도 작성합니다.

4. 자식프로세스가 fork된 시점의 데이터 쓰기가 완료되면 자식프로세스는 부모프로세스에 stop 시그널을 전송합니다.

5. 부모프로세스가 stop 시그널을 받으면, 자식프로세스가 작성하는 동안 발생한 데이터를 자식프로세스에 보냅니다.

6. 자식프로세스는 이 데이터를 AOF temp 파일에 작성합니다. 쓰기가 완료되면 파일을 닫고 부모프로세스에 완료 시그널을 보냅니다.

7. 부모프로세스는 AOF temp 파일을 열고 6단계를 진행하는 동안 추가로 발생한 데이터를 AOF temp 파일에 작성합니다.

8. 작성이 완료되면 현재 AOF 파일을 삭제하고 새 파일로 교체한 후, 새 파일에 쓰기를 시작합니다.

 

 

AOF Rewrite 시 로그


Rewrite 를 하면 로그파일에 아래와 같은 내용이 기록됩니다.

 

1
2
127.0.0.1:6379> BGREWRITEAOF
Background append only file rewriting started
cs

 

1
2
3
4
5
6
7
8
9
2753:M 04 Mar 2020 19:47:53.019 * Background append only file rewriting started by pid 2770
2753:M 04 Mar 2020 19:47:53.071 * AOF rewrite child asks to stop sending diffs.
2770:C 04 Mar 2020 19:47:53.071 * Parent agreed to stop sending diffs. Finalizing AOF...
2770:C 04 Mar 2020 19:47:53.071 * Concatenating 0.00 MB of AOF diff received from parent.
2770:C 04 Mar 2020 19:47:53.072 * SYNC append only file rewrite performed
2770:C 04 Mar 2020 19:47:53.072 * AOF rewrite: 0 MB of memory used by copy-on-write
2753:M 04 Mar 2020 19:47:53.095 * Background AOF rewrite terminated with success
2753:M 04 Mar 2020 19:47:53.095 * Residual parent diff successfully flushed to the rewritten AOF (0.00 MB)
2753:M 04 Mar 2020 19:47:53.095 * Background AOF rewrite finished successfully
cs

 

Line 1 : rewrite 를 할 2770 자식프로세스가 생성되었습니다.

Line 2 : AOF temp 파일에 쓰기작업이 완료되어 STOP 시그널을 부모프로세스에 전달했습니다.

Line 3, 4 : 부모프로세스는 STOP 시그널을 받은 후, 자식프로세스가 작성하는 동안 발생한 데이터를 자식프로세스에 보냅니다. 자식프로세스는 부모프로세스로부터 데이터를 받았습니다.

Line 5, 6 : 자식프로세스는 AOF temp 파일에 다시 내용을 작성합니다.

Line 7 : 자식프로세스가 작성을 완료하였습니다.

Line 8 : 부모프로세스는 AOF temp 파일에 추가로 발생한 데이터를 작성합니다.

Line 9 : AOF rewrite 작업이 완료되었습니다.

 

 

AOF 관련 Redis persistence 파라미터


info persistence 명령어로 aof 관련값을 확인할 수 있습니다.

 

1
2
3
4
5
6
7
8
9
127.0.0.1:6379> info persistence
aof_enabled:1
aof_rewrite_in_progress:0
aof_rewrite_scheduled:0
aof_last_rewrite_time_sec:0
aof_current_rewrite_time_sec:3
aof_last_bgrewrite_status:ok
aof_last_write_status:ok
aof_last_cow_size:344064
cs

 

aof_enabled [ 0 | 1 ]

AOF 기능이 활성화 되어있음을 나타냅니다.

 

aof_rewrite_in_progress [ 0 | 1 ]

rewrite 가 진행중인지를 나타냅니다.

 

aof_rewrite_scheduled [ 0 | 1 ]

진행중인 RDB 저장이 완료되면 AOF 다시 쓰기작업이 활성화 됩니다.

 

aof_last_rewrite_time

지난 번 rewrite 하는데 소요된 시간을 나타냅니다.

 

aof_current_rewrite_time_sec

rewrite 를 시작하고 현재까지 경과된 시간을 나타냅니다.

 

aof_last_bgrewrite_status [ ok | err ]

마지막 rewrite 가 정상적으로 받아졌는지를 나타냅니다.

폴더 경로등이 삭제되어 rewrite 파일을 만들지 못하면 err 값으로 출력됩니다.

 

aof_last_write_status [ ok | err ]

AOF 파일에 마지막 write 작업이 정상적으로 진행되었는지를 나타냅니다.

 

aof_last_cow_size

마지막 rewrite 작업 시 복사 할당 크기를 나타냅니다. (byte)