원문: https://redislabs.com/blog/top-redis-headaches-for-devops-replication-buffer/
리플리케이션 버퍼는 슬레이브 레디스 서버가 마스터와 동기화하는 동안에 데이터를 보관하는 메모리 버퍼이다. 마스터 슬레이브간의 전체 동기화시, 동기화의 초기화 단계 동안의 변경된 데이터들은 마스터 서버의 리플리케이션 버퍼에 유지된다. 초기화 단계가 완료된 이후에, 버퍼 내의 내용들은 슬레이브로 보내어진다. 이러한 절차에서 사용될 수 있는 버퍼의 크기에는 제한이 있고, 최대값에 도달했을 때에는 리플리케이션이 다시 처음부터 시작된다. 이것에 대해서는 이전에 다른 포스트를 통해 언급했던 적이 있다 endless Redis replication loops. 이러한 현상이 발생하는 것을 방지하기 위해서, 버퍼의 초기 설정은 리플리케이션 절차가 처리되는 동안 예상되는 변경의 크기와 형태에 따라 적절하게 바꿔둘 필요가 있다. 예를 들어, 변경이 적고, 또는 각각의 변경이 작은 데이터 뿐이라면 작은 크기의 버퍼로도 괜찮을 것이다. 반면에, 매우 많은 변경이 있거나 각각의 변경이 매우 크다면, 큰 버퍼가 필요할 것이다. 좀 더 종합적인 해결책은 매우 큰 값으로 버퍼를 설정하는 것으로, 결국에는 버퍼를 다 써버리게 될 길거나 무거운 리플리케이션 처리의 가능성을 가능성을 상쇄시킬 수 있을 것이다 (앞서 설정한 버퍼 크기가 너무 작은 경우). 근본적으로 이러한 해결책은 문제에 직면한 특정 데이터베이스를 미세한 튜닝이 필요하다.
Redis 기본 설정
> config get client-output-buffer-limit
1) "client-output-buffer-limit"
2) "normal 1073741824 536870912 30 slave 268435456 67108864 60 pubsub 33554432 8388608 60"
여기서 설명한대로, 이 기본 설정은 256MB의 hard limit에 도달하거나, 또는 soft limit에 도달한 상태에서 60초 이상 유지될 때, 리플리케이션 연결을 중단시킬 것이다 (이것은 최초부터 시작하는 동기화를 발생시킨다). 많은 경우에, 특히 write
부하가 높고 슬레이브 서버로 충분히 대역폭이 확보되지 않은 상황이라면, 리플리케이션 프로세스는 절대 끝나지 않게 될 것이다. 이것은 마스터 레디스가 지속적으로 fork를 수행하고, 전체 데이터 셋의 스냅샷을 디스크로 남기려고 하는 등의 무한루프와 같은 상황으로 이어질 수 있으며, 3배 이상의 추가적인 메모리를 사용과 함께, 높은 수준의 I/O 오퍼레이션 또한 발생시킬 것이다. 또한, 이 무한루프 상황으로 슬레이브 서버는 절대 마스터 레디스를 따라잡고, 전체 동기화를 하지 못하는 상황이 된다.
간단한 해결책으로써, output slave buffer의 크기를 hard limit과 soft limit을 둘다 512MB로 설정하므로써 즉각적인 개선 결과를 얻을 수 있다:
> config set client-output-buffer-limit "slave 536870912 536870912 0"
대부분의 재설정과 마찬가지로, 다음의 사항을 이해하는 것은 중요하다.
이것으로 우리의 레디스 운영상의 가장 골칫거리 중 한 부분을 끝낼 수 있게 해주었다. 위에서 지적한 것과 같이, 리플리케이션 버퍼의 제한의 측면에서, 적절한 설정은 도움이 될 수 있다. 리플리케이션 타임아웃과 그것들을 적절히 처리하는 방법 등을 다루는 다음 포스트도 주의깊게 살펴보길 바란다.