简体   繁体   English

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

[英]Redis pubsub cause Too Many Files Open Error

I have a server used Redis and Socket.IO. 我有一台服务器使用Redis和Socket.IO。 If a user connect to the socket.IO, server will run a greenlet and subscribe to redis channel. 如果用户连接到socket.IO,则服务器将运行greenlet并订阅redis通道。 If the user disconnect, the greenlet will unsubscribe the channel. 如果用户断开连接,则绿色按钮将取消订阅该频道。

After a lot of connection and disconnection, I use 'client list' command in redis-cli, I found that the number of unsubscribe is additive and it will never closed like other command. 经过大量的连接和断开连接后,我在redis-cli中使用了“ client list”命令,我发现取消订阅的数量是可加的,并且永远不会像其他命令一样关闭。 And it will finally cause 'Too Many Files Open Error' 它将最终导致“打开太多文件错误” 在此处输入图片说明

My Code is 我的代码是

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)

I notice that the reason may be 我注意到原因可能是

timeout only applies to number clients and it does not apply to Pub/Sub clients, since a Pub/Sub connection is a push style connection so a client that is idle is the norm. 超时仅适用于数字客户端,不适用于Pub / Sub客户端,因为Pub / Sub连接是推式连接,因此处于空闲状态的客户端是常态。

Should I implement the timeout for unsubscribe command? 我应该对取消订阅命令实施超时吗? Or use other method to stop subscribe? 还是使用其他方法停止订阅?

Looking at the code 看代码

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

I can guess at the issue. 我可以猜测这个问题。 It looks like the PubSub object checks a connection out of the connection pool on the subscribe command, but doesn't release it on unsubscribe . 它看起来像PubSub的对象检查就出来了连接池的连接subscribe命令,但不会释放它unsubscribe It SHOULD release it when your greenlet goes out of scope (the del method)- are you holding them in scope for some reason so that they don't get freed? 当您的greenlet超出范围时,它应该释放它( del方法)-您是否出于某种原因将它们保留在范围内,以免它们被释放? This will lead to memory issues either way... 这两种方式都会导致内存问题...

however, you could try using the reset method to force release that connection without messing with scope issues. 但是,您可以尝试使用reset方法强制释放该连接,而不会弄乱范围问题。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM