Redis pubsub导致太多文件打开错误

时间:2016-06-27 02:56:11

标签: python redis publish-subscribe

我有一台使用Redis和Socket.IO的服务器。如果用户连接到socket.IO,服务器将运行greenlet并订阅redis通道。如果用户断开连接,greenlet将取消订阅该频道。

经过大量连接和断开后,我在redis-cli中使用'client list'命令,我发现取消订阅的数量是加性的,它永远不会像其他命令那样关闭。它最终会导致“太多文件打开错误”enter image description here

我的代码是

class ListenMsgThreading(Greenlet):
    def __init__(self, app_eui, request_sid):
        Greenlet.__init__(self)
        self.ps = redis_db.pubsub()
        self.ps.subscribe('channel')

    def stop(self):
        self.ps.unsubscribe('channel')

    def run(self):
        for item in self.ps.listen():
            if item is not None:
                print(item)

我注意到原因可能是

  

超时仅适用于数字客户端,并且它不适用于发布/订阅客户端,因为发布/订阅连接是推式连接,因此空闲的客户端是常态。

我应该为unsubscribe命令实现超时吗?或者使用其他方法来停止订阅?

1 个答案:

答案 0 :(得分:1)

查看代码

https://github.com/andymccurdy/redis-py/blob/master/redis/client.py#L2281

我可以猜到这个问题。看起来PubSub对象检查subscribe命令上的连接池中的连接,但不会在unsubscribe上释放它。它应该在你的greenlet超出范围(del方法)时释放它 - 你是否因为某种原因将它们放在范围内以便它们不会被释放?这会导致内存问题......

但是,您可以尝试使用reset方法强制释放该连接,而不会影响范围问题。

self.ps.unsubscribe()
self.ps.reset()