2016-12-07 4 views
0

В настоящее время я работаю над распределенными вычислениями. Мои работники возвращают свои результаты, вставляя их в базу данных mongoDB. Код работает хорошо, но соединение остается открытым, и в какой-то момент моя система заканчивается сокетами. Вот мой рабочий код:Как я могу заставить pymongo закрыть розетки?

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

+0

Как долго занимает раздел «вычислить здесь» для выполнения, пожалуйста? Включает ли один процесс Python много документов в базу данных или только один, прежде чем процесс завершится? –

+0

Как долго занимает раздел «вычислить здесь» для выполнения, пожалуйста? На самом деле он пуст. Выполняет ли один процесс Python много документов в базе данных или только один, прежде чем процесс завершится? Работнику управляют библиотеки pp (параллельный питон) Таким образом, он получает задание, создает сокет, вставляет элемент, закрывает сокет и захватывает другую задачу, чтобы сделать то же самое снова. Таким образом, один рабочий может создать много сокетов. –

ответ

0

Что, вероятно, происходит это, вы создаете клиент, вставьте документ и закрыть клиент, много раз в секунду. MongoClient может занять второй или два, чтобы завершить процесс завершения работы. (MongoClient запускает фоновый поток на сервер, и эти потоки не выводятся мгновенно.) Даже когда MongoClient полностью закрыл свои сокеты, сервер MongoDB занимает секунды, чтобы очистить все ресурсы, связанные с TCP-соединением, и сеть ОС для очистки требуется несколько минут. (См состояние TIME-WAIT в Wikipedia's TCP entry.)

Как правило, вы должны создать один MongoClient в начале вашего процесса Python, и использовать один MongoClient на протяжении всего этого процесса Python жизни:

client = pymongo.MongoClient(MONGODB_URI) 

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

Дон» t создать новый MongoClient за операцию. Никогда не закрывайте его.

Смотрите также the PyMongo FAQ:

Создание этого клиента один раз для каждого процесса, и использовать его для всех операций. Общей ошибкой является создание нового клиента для каждого запроса, что очень неэффективно.

+0

«Никогда не закрывай». - Когда он закрывается? –

+1

Автоматически закрывается при выходе из процесса Python. До этого не было причин закрывать MongoClient. –

+0

Это ценная информация! Вы говорите, что разработчики 'pymongo' подвергают метод' .close' из-за тщательности или «никогда» преувеличением, и у него есть законные варианты использования? –

Смежные вопросы