Redis publish/subscribe 기능을 사용하여 Python 2.7 서비스를 빌드하려고합니다. 나는 redis-py 2.10.3을 클라이언트로하여 우분투 12.04에서 redis 2.8.17을 사용합니다. 불행히도 내 서비스가 기억을 새고있는 것 같습니다. 메모리 소비는 서비스가 수신/소비/처리하는 메시지의 양에 비례하여 증가하는 것처럼 보입니다.Redis pub/sub를 사용하는 Python 서비스에서 메모리 누수 디버깅
내 기본 가입 루프를 장식하여 도구 memory_profiler을 사용하여 디버깅을 시도했습니다. 계속해서 출력물을 출력하게하기 위해받은 100 번째 메시지를 모두 출력하도록 변경했습니다. 출력은 다음과 같습니다.
Line # Mem usage Increment Line Contents
================================================
62 39.3 MiB 0.0 MiB @memory_profiler.profile
63 def _listen(self, callback):
64 40.1 MiB 0.7 MiB for _ in self.redis_pubsub.listen():
65 40.1 MiB 0.0 MiB self.count += 1
66 40.1 MiB 0.0 MiB self._consume(callback)
67 40.1 MiB 0.0 MiB if self.count == 100:
68 40.1 MiB 0.0 MiB self.count = 0
69 40.1 MiB 0.0 MiB break
70 40.1 MiB 0.0 MiB gc.collect()
서비스에 푸시 된 메시지 100 개당 비슷한 증가를보고합니다. 콜백 함수는 실제로 응용 프로그램 일을하는 함수입니다. 따라서 65 행은 앱 코드에 이상이있는 경우 실제로 메모리가 증가 할 것으로 예상됩니다.
결과로 나가는 클라이언트를 의심스럽게 만들었습니다. pympler.asizeof를 사용하여 self.redis_pubsub 및 redis.StrictRedis 객체의 크기를 확인했습니다. 이러한 객체는 처음에는 작으며 서비스가 메시지를 수신 할 때 전혀 증가하지 않습니다.
또한 pympler.muppy 및 pympler.summarize를 사용하여 누출 된 개체를 찾으려고 할 때 증가하는 개체 수 또는 누적 메모리는보고하지 않습니다. 또한 메모리 소비량과 성장량의 합계는 Linux에서 제공하는 수치와 유사하지 않습니다.
나는 막혔다. 아무도 무슨 일이 벌어지고 있을지도 모르겠다. 어떻게 더 디버깅 할 수 있을지에 대한 아이디어가 있습니까?
메모리 누수가 발생 했습니까? 그 증거는 무엇입니까? –
좋은 질문입니다. 몇 시간 동안 메시지를 계속 생성하면 메모리가 적어도 500MB까지 재생되지 않습니다 (수명이 다할 때까지 테스트해야합니다). 내 예제를 끝에 gc.collect()로 업데이트하여 적어도 강제로 수행 할 수 없음을 보여줍니다. – mdoverhag
솔직히 말해서, 나는 redis 클라이언트가 단지 100 개의 메시지를받는 것에서 700KB의 메모리를 사용해야하는 이유에 대해 머리를 감쌀 수 없습니다. 또는 내가 도구가 작동하는 방법을 모르기 때문에 ungrounded이고 false 인 memory_profile 데이터에서 결론을 이끌어 낼 수 있습니다. – mdoverhag