레디스 Persistance

레디스에서 AOF랑 RDB를 동시에 사용하고 싶은데, 잘 안되서 공식 사이트를 열심히 보면서 정리하다가 보니 번역을 하고 있더군요. 허헛..;;

첨에는 혼자 정리하는거라 마구 적다가, 후반부에는 지쳐서 대충 한부분도 없지않은것 같습니다. 혼자 보는 것도 좋은데 누군가에겐 도움이 되지 싶어 올립니다.

의견이 있으시면 알려주시어요~^^

Redis Persistance

  • 모드가 2개 존재함
  • RDB / AOF
    1. RDB는 특정한 시점의 데이터베이스의 스냅샷.
    2. AOF는 모든 쓰기 명령에 대한 로그를 남김.
  • 영속성 옵션을 모두 꺼도됨. 근데 나 처럼 redis를 디비 대용으로 쓰는 사람들은 그렇게 안하것지.ㅋ
  • AOF랑 RDB를 섞어서 사용하는 것도 가능. 근데 주의해야될게, 레디스가 AOF로 재시작 되면 원본 데이터 셋을 다시 구축함. 왜냐하면 AOF는 거의 완벽한 백업을 보장해야 하니까.
  • RDB랑 AOF는 트레이드 오프가 있다.

RDB 좋은점.

  • 컴팩트사이즈의 파일 한개로 된 레디스 데이터. RDB파일은 백업에 완벽히 적합함. 24시간 마다 백업해서 매일 매일의 스냅샷을 30일 동안 저장하거나 할수 있고, 장애/재해시 복구하기 편함.
  • 재해복구에 베리굿. 파일 사이즈가 컴팩트하니깐 데이터 센터나 Amazon S3같은데 전송하기에 적합.
  • RDB는 레디스의 성능을 최대화함. (이유는 생략. ㅋ )
  • RDB는 데이터가 클때에 재시작시 AOF보다 빠르게 재시작 가능.

RDB 나쁜점.

  • 데이터 유실을 최소화 하는데에는 좋지않아.
  • RDB는 자식 프로세스를 사용해서 디스크에 백업하기 위해서 fork()를 사용해야됨. Fork()는 데이터가 크면 시간을 잡아먹음. 그래서 몇 밀리세컨드에서 일초가 넘게 클라이언트의 지연이 있을 수 있음. (데이터는 큰데 CPU가 그레이트하게 좋지는 않을 때), AOF도 fork()를 사용함. 근데 얼마나 자주 로그를 남길지 니가 조절가능 – 안정성에 대해서는 아무런 트레이드 오프없음. (그러니깐 지연이 안일어난다는 의미)

AOF 좋은점

  • 매우 많이 안정적이다. : 다양한 fsync정책을 사용가능. fsync 안하기. 매초마다 fsync하기.(디폴트) 모든 쿼리마다 fsync 하기. (별로 안다양한데..ㅋ) 디폴트만 사용해도 성능은 그레잇함. (fsync는 백그라운드 스레드로 실행됨. 메인쓰레드가 무거워지면, no fsync가 작동. ) 그렇지만, 일초동안 쌓인 양의 데이터 유실이 있을 수 있음.
  • AOF로그는 append only임, 그러니깐 피씨의 전원이 나가서 꺼지더라도 나중에 파일 탐색이나, 충돌 같은 문제가 안생김. 만약에 로그를 쓰다가 반만 써졌다고 해도(디스크가 꽉차거나 이런저런 이유들로) redis-check-aof 툴로 쉽게 고칠 수 있음.
  • 로그가 너무 많을 때에 자동적으로 백그라운드에서 AOF 다시 쓰기 가능. rewrite는 완전히 안전함.
  • AOF는 모든 명령이 로그로 남고, 알아보기 쉬운 포맷으로 되어 있음. 만약에 잘못해서 flushall로 데이터를 다 날렸으면. aof파일에서 그부분만 지우고 서버를 재시작하면 다시 살아남!! (@charsyam님께서 알려주신 바로는 이게 가능한 것은 다음 번 rewrite가 일어나기 전 까지임. 왜냐면 rewrite가 일어나면 AOF를 최적화 하기 때문.)

AOF 나쁜점.

  • AOF파일은 RDB보다 파일 용량이 크다.
  • AOF는 RDB보다 느려질 수 있다. 그렇지만 fsync를 꺼버리면 높은 부하에서도 RDB보다 빠르긴 함. 그렇긴해도 RDB는 엄청난 부하에도 맥시멈 latency를 보장해줌.
  • 과거에 특정 명령어에서 버그가 있었음. (BRPOPLPUSH 같은 블러킹 명령어였음) 자기네들이 테스트할때는 OK였다고함. 고칠려고 많은 노력을 햇음. 그리고 실제 세계에서는 본적없다고 함.

오케이, 그럼 나는 뭘 쓰면 돼?

PostgreSQL같은 데이터 안정성을 원한다면 말야. 둘 다 쓰는거임. ㅎㅎㅎ 너가 데이터에 신경을 곤두세우고는 있지만, 그냥 단순히 RDB만 쓰고 있으면, 재난이든 머든 단 몇분일지 몰라도 데이터가 날아가는 걸 볼 수 있을 꺼야. OTL 그리고 AOF만 쓰는 유저들도 많은데, 우리는 이것을 권장하지 않아. 왜냐면 데이터 베이스 백업으로는 RDB만한게 없으니깐.

노트 : 머 이런 이유들로 나중에 우리는 AOF랑 RDB랑 합칠꺼야(롱~~~~텀 플랜임.)

스냅샷찍기 (Snapshotting)

디폴트로 레디스는 데이터 셋의 스냅샷을 디스크로 남겨. dump.rdb라는 바이너리 파일로 말이지. 이건 설정 파일에서 설정 가능해. 데이터셋의 최소 N초동안 최소 M의 변화가 있을 때 저장하도록 말야. 물론 수동으로 SAVE 나 BGSAVE 명령어를 날려서 저장하는 것도 가능.

save 60 1000

이 전략은 스냅샷찍기라고 알려져 있어.

어떻게 작동하나?

레디스가 데이터셋을 디스크로 덤프해야할 필요가 있을 때, 무슨일이 일어나냐면:

  • 레디스가 fork함. 그럼 이제 부모랑 자식 프로세스가 있는거지.
  • 자식프로세스가 데이터 셋을 임시 RDB파일에다 쓰기 시작해
  • 자식프로세스가 새로운 RDB파일을 다쓰면 옛날꺼랑 교체!

이 방법은 copy-on-write semantics 에서 가져왔는데 redis가 득 좀 봤지.ㅋ

Append-only File

스냅샷만 찍는건 매우 베리 안정적이지 않아. Redis를 정지 시켜버리거나, 파워 라인이 끊어지거나, 니가 실수로 kill -9 를 사용하거나 해서 최신의 데이터가 그대로 날아가 버리고 말지. 이런 상황이 별거 아닌 어플리케이션이 있는 반면, 100% 안정적이어야 하는 경우도 있지. 근데 100% 안정적인 옵션은 레디스에 없어.

append-only file은 최대-안정화 전력을 위한 레디스의 대안이야. 1.1버전부터 있었지. 설정 파일에서 AOF를 켤 수 있어.

appendonly yes

이제부터, 데이터 셋을 바꾸는 모든 명령어를 AOF에 붙이게 될꺼야. 만약에 니가 재시작을 하게되면, Redis는 AOF를 다시 실행해 볼꺼고 상태를 재조정 하게 될꺼야.

로그 rewriting

아마도 예측이 되겠지만, 많은 명령이 수행 되면 될수록 AOF도 점점 커질꺼야. 너가 하나의 카운트를 100번 증가시키면, 너는 데이터 셋의 단지 하나의 키만 데이터 셋에 유지하는 것이지만, 너의 AOF에는 100개의 엔트리가 들어가게 되지. 99개의 엔트리는 필요 없는것이야. 현재의 상태로 다시 되돌릴때에는 말이지.

그래서 레디스는 재밌는 기능을 제공해주고 있는데, AOF를 클라이언트에 대한 서비스의 중지없이 백그라운드로 재구축할 수 있어. 너가 BGREWRITEAOF를 실행하면, 레디스는 현재의 메모리에 있는 데이터셋으로 재구축 할 수 있게끔하는 최단의 명령어열을 AOF에 쓰게 될거야. 만약에 니가 redis2.2버전에서 AOF를 사용하고 있다면 BGREWRITEAOF를 시시때때로 사용해야돼. 2.4부터는 트리거를 걸 수 있어서 자동으로 할 수 있어.

append only file은 얼마나 안정적임?

얼마나 자주 fsync를 할지 설정할 수 있어. 여기에는 3가지 옵션이 있지.

  • 매번 fsync하기 – 커맨드가 실행될 때마다 AOF에 추가. 겁나, 매우, 베리 베리 느림. 겁나 안전함.
  • 1초 마다 fsync 하기 – 충분히 빠르다. (2.4에서는 스냅샷 만큼 빠름), 그래도 재난일 일어나면 1초만큼의 데이터는 날라감.
  • fsync안함. – 그냥 데이터를 넣기만 함. 가장 빠르지만 덜 안전한 방법.

추천 하는 정책은(디폴트) 1초마다 fsysnc하는거야. 빠르기도하고 꽤 안전하지. 매번 fsync하는 건 실제사용하기엔 너무 느려. (2.0에서 개선되긴 했지만 말여.) – fsync보다 빠르거나 그걸 빠르게 하는 방법은 없더라고.

내 AOF가 망가졌는데 우짜면 되노?!

AOF파일에 쓰는중에 서버에서 문제가 생기면, 파일이 깨지고 그건 redis에서 읽을 수 가 없지. 그 때는 아래에 나와 있는대로 하면 고칠 수 있을 거야.

  • AOF파일의 백업본을 만든다.
  • redis-check-aof(레디스의 bin 폴더에 있음) 툴로 원본파일을 고친다.

    $ redis-check-aof --fix

  • 옵션으로 diff -u 를 사용해서 어디가 잘 못된건지 찾아본다.

  • 고쳐진 파일로 서버를 재시작한다.

어떻게 작동하나?

로그 덧붙여 쓰기(log rewriting)는 스냅샷찍기에서 사용한 copy-on-write 트릭을 동일하게 사용함.

  • 레디스가 포크함. 그럼 이제 부모와 자식 프로세스가 생긴다.
  • 자식 프로세스는 새로운 AOF의 임시파일을 만든다.
  • 부모는 새로들어오는 명령들을 메모리 버퍼에 계속 쌓는다.(근데 동시에 원본 AOF파일에 계속 쓴다. 그러니 rewriting이 실패해도 안심하시요.)
  • 자식 프로세스가 rewriting을 끝내면, 부모 프로세스에서 신호를 보내고, 메모리 버퍼에 있던 것들을 자녀 프로세스가 생성한 파일에 모두 더한다.
  • 오호! 이제 레디스가 자동적으로 이전 파일하고 새로운 파일의 이름을 바꿔 치기한다. 그리고 새로운 파일에 새로운 데이터를 덧쓰기 시작한다.

나는 지금 dump.rdb 스냅샷을 쓰고 있는데 AOF로 어떻게 바꿈?

2.0하고 2.2가 해야하는 절차가 다르다. 니가 생각한대로 2.2가 좀 더 간단하고 재시작이 필요읍따.

Redis >= 2.2

  • dump.rdb를 백업한다.
  • 백업한 파일을 안전한 곳으로 이동/전송 시킨다.
  • 2개의 커맨드를 실행 시킨다.
  • redis-cli config set appendonly yes
  • redis-cli config set save ""
  • 니 데이터베이스가 같은 수의 키를 유지하고 있는지 확인한다. (확인은 알아서…ㅎㅎ)
  • 새로 들어오는 데이터들이 append-only-file에 추가되는지 확인한다.

첫번째 CONFIG 명령어는 Append Only File을 사용가능하게 해줌. 그리고 AOF를 사용하기 위해 Redis는 dump를 초기화 시키는 것을 막을 것이다. 그리고 나서 파일을 열고 들어오는 쿼리들을 기록할 것이다.

두번째 CONFIG 명령어는 스냅샷을 찍는것을 끄는 명령이다. 이것은 옵션으로서, 원한다면 둘다 켜놓을 수 있다.

중요 redis.conf를 수정해야 된다는걸 꼭 기억해라. 안그러면 서버를 재시작 했을 때 원래의 설정으로 대돌아간다.

Redis 2.0은 생략합니다.

AOF와 RDB의 상호작용.(interaction)

Redis >= 2.4 에서는 RDB 스냅샷이 작동 중일때 또는 BGSSAVE가 작동 중일때 에는 AOF rewrite 트리거를 피하도록 했다. 2개의 무거운 백드라운드가 동시에 실행되는 것을 막기 위함임. 스냅샷을 남기는 도중에 유저가 BGREWRITEAOF커맨드를 실행했을 때 서버는 OK라는 상태코드-작업이 스케줄링 되었다는 뜻-로 응답할것이고, rewrite는 스냅샷 찍는게 완료된후 실행될 것이다. AOF랑 RDB둘다 유효로 되어 있는 경우, 레디스가 재시작되면 AOF파일이 재구축 된다.

데이터 백업하기

이 섹션을 시작하기 전에, 다음의 문장을 정확히 읽고 확인해보라.

너의 데이터 베이스를 확실히 백업해라

디스크가 깨지거나, 클라우드에 있는 인스턴스가 없어지거나, 기타등등..: 백업이 없다는게 의미하는건 데이터가 /dev/null 로 사라지게 될 큰 위험을 지고 있다는 것이야! 레디스는 데이터 백업에 베리 친절해. 데이터 베이스가 작동중에도 너는 RDB로 스냅샷을 뜰 수 있지:RDB는 한번 만들어지면 절대 수정되지 않아, 그리고 만드는 중에는 임의의 이름을 사용하다가 스냅샷이 끝나고 나서야 마침내 이름을 변경하지!

이것이 의미하는것은 이거야. RDB파일을 카피하는 것은 완전 안전하다는 것이지. 서버가 운용중일 때에도 말이지! 다음에 나오는 건 우리가 추천하는 것들이야:

  • 너의 서버에 하나의 디렉토리에 매시간동안 스냅샷을 만드는 Cron을 만들고 잡을 돌려라, 그리고 일별 스냅샷은 다른 디렉토리에 저장해.
  • 매시간 Cron 잡 스크립트를 실행시키고, find 커맨드를 사용해서 오래된 스냅샷을 지워버려. 예를 들자면 이런거야. 48시간 동안 시간별 스냅샷을 만들고, 그리고 일별 스냅샷을 한두달 정도 만드는거지. 스냅샷의 이름은 시간, 날짜 정보를 넣어서 시간대별로 알 수 있게 해둬.
  • 최소한 매일 한번정도는 RDB스냅샷을 외부의 너의 데이터 센터로 전송시켜 아니면 최소한 다른 물리적인 redis머신으로 이동시켜.

재해 복구

재해 복구는 레디스에서는 기본적으로 백업이랑 같은 스토리야. 여기서 플러스로 각각의 백업들을 많은 다른 외부 데이터 센터로 전송시키는 것이 필요하지. 이 방법을 사용하면 대재앙이 일어나서 레디스가 돌고 있는 메인 데이터 센터에 영향이 갈때에도 안전하다고! 스타트업에 있거나 돈이 별로 없는 수많은 레디스 유저들을 위해서 우리는 매우 흥미로운 재해 복구 테크닉을 알려줄거야. 그건 돈 별로 안들어..ㅋ

  • Amazon S3나 비스무리한 서비스는 재해 복구 시스템으로 제격이지. 간단히 매일/매시 마다 RDB스냅샷을 S3로 보내는거야.(암호화된 폼으로). gpg -c 를 쓰면 암호화 시킬 수 있어. 데이터 안정성을 올리기 위해서 멀티로 스토리지 서비스를 사용하는 것도 추천이야.

  • 너의 스냅샷을 SCP로 멀리있는 서버로 전송해. 이건 진짜 간단하고 안전한방식이야: 작은 VPS를 얻어서 – 좀 멀리 있는 놈으로 – 거기에 ssh를 설치하고, ssh 클라이언트 키를 설정하는거지 암호없이, 그리고 나서 authorized_keys파일에 추가해. 너는 이제 백업파일을 전송할수 있어. 최소한 2개의 VPS를 얻는게 베스트야!

시스템은 쉽게 고장난 다는것을 이해는건 참으로 중요해. 최소한 전송이 끝났는지는 파일 사이즈를 체크하던지 해서 절대적으로 확인해야해! 그리고 가능하다면 SHA1암호화 방식을 사용해 너의 VPS에 말이지. 너는 독립된 경고 시스템이 필요할 지도 모르겠어. 어떤 이유로 최신 백업이 제대로 동작 하지 않을 때를 위해서 말이지.

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다