如何强制 pymongo 关闭套接字?

How can I force pymongo to close sockets?

我目前从事分布式计算方面的工作。 我的工作人员 returns 通过将其插入到 mongoDB database.The 代码中得到的结果运行良好,但连接仍保持打开状态,此时我的系统 运行 没有套接字。 这是我的工人代码:

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,但他们必须处理超过 10000 个任务。

...
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 皮蒙戈 3.3 mongoDB3.2.10

可能发生的情况是,您创建一个客户端,插入一个文档,然后关闭客户端,每秒多次。 MongoClient 可能需要一两秒钟才能完成其关闭过程。 (MongoClient 为每个服务器启动一个后台线程,这些线程不会立即退出。)即使 MongoClient 完全关闭其套接字,MongoDB 服务器也需要几秒钟来清理与 TCP 连接相关的所有资源, OS 的网络层需要几分钟才能清理干净。 (参见 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:

Create this client once for each process, and reuse it for all operations. It is a common mistake to create a new client for each request, which is very inefficient.