调试使用Redis pub / sub的Python服务中的内存泄漏

时间:2014-12-04 13:16:34

标签: python python-2.7 memory-leaks redis redis-py

我正在尝试使用Redis发布/订阅功能构建Python 2.7服务。我在Ubuntu 12.04上使用redis 2.8.17,使用redis-py 2.10.3作为客户端。不幸的是,我的服务似乎在泄漏记忆。内存消耗似乎随着服务接收/消耗/处理的消息量而增加linearI-ish。

我尝试使用工具memory_profiler通过修改我的主订阅循环来调试它。为了让它连续打印输出,我改变它以退出它收到的每一百条消息。输出如下:

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行就是我实际期望内存增加的地方..

输出让我怀疑redis客户端所以我还使用pympler.asizeof检查了self.redis_pubsub和redis.StrictRedis对象的大小。这些对象在开始时很小,并且在服务接收消息时根本不会增加。

此外,当尝试使用pympler.muppy和pympler.summarize查找泄漏对象时,它不报告任何增长的对象计数或累积内存。此外,内存消耗和增长的总数与Linux中top的数字并不相同。

我被卡住了,有人知道可能会发生什么,或者对我如何进一步调试有任何想法?

1 个答案:

答案 0 :(得分:0)

我花了几个小时在pub/sub设置中调试同一个问题。确实存在内存泄漏,我在发布消息时无法找到避免它的方法。我的转变是使用multiprocessing在单独的进程上运行发布部分。这对我有用,因为我每隔几秒发布一次消息,所以这是一个合理的权衡。

没有泄漏的替代方案是tornadis