我如何强制pymongo关闭套接字?

时间:2016-12-07 10:50:35

标签: python mongodb pymongo pymongo-3.x

我目前正致力于分布式计算。 我的工作人员通过将其插入到mongoDB数据库中来返回结果。代码运行良好,但连接仍然打开,我的系统用完了套接字。 这是我的工人代码:

def worker(elt):
    client=pymongo.MongoClient(MONGODB_URI)
    db = client.get_default_database()
    essaiElt = db['essaiElt']
    #compute here
    essaiElt.insert( elt.toDict())
    client.close()

使用此命令" netstat -anbo"我可以看到所有插座仍然打开(超过3000),最大工人数是14,但他们必须处理超过10 000个任务。

...
TCP 10.130.151.11:4999 10.130.137.128:27017 En attente 0
TCP 10.130.151.11:5000 10.130.137.128:27017 En attente 0

我已尝试设置超时但不会产生任何影响。

如何在不重启数据库的情况下关闭套接字?

Python 2.7.12 Pymongo 3.3 mongoDB 3.2.10

1 个答案:

答案 0 :(得分:0)

可能发生的事情是,您每秒多次创建客户端,插入文档和关闭客户端。 MongoClient可能需要一两秒才能完成其关闭过程。 (MongoClient为每个服务器启动一个后台线程,这些线程不会立即退出。)即使MongoClient完全关闭其套接字,MongoDB服务器也需要几秒钟来清理与TCP连接相关的所有资源,操作系统的网络层需要几分钟才能清理。 (参见Wikipedia's TCP entry中的TIME-WAIT状态。)

通常,您应该在Python进程的开头创建一个MongoClient,并在整个Python进程生命周期中使用一个MongoClient:

client = pymongo.MongoClient(MONGODB_URI)

def worker(elt):    
    db = client.get_default_database()
    essaiElt = db['essaiElt']
    #compute here
    essaiElt.insert( elt.toDict())

不要为每个操作创建一个新的MongoClient。永远不要关闭它。

另见the PyMongo FAQ

  

为每个流程创建一次此客户端,并将其重用于所有操作。为每个请求创建一个新客户端是一个常见的错误,这是非常低效的。