简体   繁体   English

如何强制pymongo关闭套接字?

[英]How can I force pymongo to close sockets?

I'm currently working on distributed computing. 我目前正在从事分布式计算。 My workers returns its results by inserting it into a mongoDB database.The code works well,but the connection remains opened and at a moment my system run out of sockets. 我的工作人员通过将结果插入到mongoDB数据库中来返回结果。代码运行良好,但是连接保持打开状态,并且我的系统立即用尽了套接字。 Here is my worker code: 这是我的工作人员代码:

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

By using this command "netstat -anbo" I can see all sockets still opened (more than 3000), the max number of worker is 14 but they have to deal with more than 10 000 task. 通过使用此命令“ 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

I've tried to set timeouts but it doesn't have any effect. 我试图设置超时,但是没有任何效果。

How can I close sockets without restart my dataBase? 如何在不重新启动数据库的情况下关闭套接字?

Python 2.7.12 Pymongo 3.3 mongoDB 3.2.10 Python 2.7.12 Pymongo 3.3 mongoDB 3.2.10

What's likely happening is, you create a client, insert a document, and close the client, many times per second. 可能发生的情况是,您每秒创建一个客户端,插入一个文档,然后关闭客户端。 A MongoClient can take a second or two to complete its shutdown process. MongoClient可能需要一两秒钟才能完成其关闭过程。 (A MongoClient starts a background thread per server, and these threads don't exit instantly.) Even once the MongoClient has completely closed its sockets, the MongoDB server takes seconds to clean up all resources related to the TCP connection, and the OS's network layer takes minutes to clean up. (MongoClient在每个服务器上启动一个后台线程,并且这些线程不会立即退出。)即使MongoClient完全关闭了其套接字,MongoDB服务器也将花费几秒钟的时间清理与TCP连接和操作系统网络有关的所有资源。层需要几分钟的时间来清理。 (See the TIME-WAIT state in Wikipedia's TCP entry .) (请参阅Wikipedia的TCP条目中的TIME-WAIT状态。)

Generally, you should create one MongoClient at the beginning of your Python process, and use the one MongoClient throughout that Python process lifetime: 通常,您应该在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())

Don't create a new MongoClient per operation. 不要为每个操作创建一个新的MongoClient。 Never close it. 永远不要关闭它。

See also the PyMongo FAQ : 另请参阅PyMongo常见问题解答

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. 为每个请求创建一个新客户端是一个普遍的错误,这是非常低效的。

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

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