[입 개발] Redis Replication 에서 maxmemory 정책은 어떻게 적용될까?

제가 존경하는 @babokim 님이 저에게 다음과 같은 질문을 주셨습니다.

 “cache에서 master/slave 구조에서 궁금한게 cache에서 데이터를 빼는 정책(time 또는 hit)이 master/slave 별로 차이가 날 것 같은데(time, hit 수 등) 이런 경우 어떻게 되나요? master에서 메모리에서 데이터를 뺄때 slave에도 빼도록 명령을 주나요?”

여기서 먼저 짚고 넘어가야 할 것이, Redis에서 Master/Slave 연결시에 이런 설정들을 Sync 하지 않는다는 점입니다.  이로 인해서 Master 와 Slave 가 서로 다른 정책을 가질 수 가 있습니다. 그로 인해서 몇가지 정리하면 다음과 같습니다.

1] Master에서 maxmemory-policy 정책으로 인해서 사라지는 key 는 propagateExpire 함수를 통해서 DEL Command 가 Slave로 전달되게 됩니다. 그로 인해서 Master에서 Expire 되거나 LRU로 사라지는 키는 Slave에서도 사라집니다.

2] 여기서 문제가, Slave의 정책에 따라서 Slave에서도 데이터가 사라질 수 있습니다. 이로 인해서 Consistency 문제가 발생할 수 있습니다. 즉 Master와 Sync가 되고 데이터를 Replication 받을 때, 자신의 정책으로 키가 사라지게 됩니다.

즉, 1],2]를 통해서 Redis Replication 실행전에 항상 서버의 구성이나, maxmemory 정책을 일치시켜두는 것이 상당히 중요합니다.

일치시키는 것보다 slave 의 maxmemory를 0으로 셋팅해서 정책이 동작하지 않도록 하는 것이 더 좋아보입니다. 다만 기본적으로 redis.conf에 별다른 내용이 없으면 64bit에서는 0으로 설정됩니다.

 

[추가: 2013-01-19] 여기에 몇 일전에 패치를 냈는데, 결론부터 말하자면, 받아들여지지는 않았습니다. 사실 패치가 받아들여지는 것도 중요하지만 더 중요한 것은 커미터의 생각이 어떻가? 입니다. @antirez의 의견은, 실제 redis의 경우에 캐시모드로만 사용하면서 read 부하를 낮추기 위해서 read 용 슬레이브를 사용하는 곳이 많은데, 여기서 보면, 장비들이나 부하여부에 따라서 메모리 사용이 달라져서 슬레이브에서 자신만의 maxmemory 정책의 적용이 필요하다고 합니다. 이걸 강제로 막으면, 더 이상 이런 용도에서 사용이 되기 힘들다고, 결국 이전에 사용하는 사람들에 대해서도  호환성(Compatibilty 라고 부르죠?)이 필요한 상황이라고 합니다. 다만, 이런게 좀 자기가 보기에도 이상해 보인다고 하긴 하네요. 요런데서 배우는 것들이 좋은게 많은 것 같습니다.