Слишком большое потребление ОЗУ (40 ГБ +) для одновременных DNS-запросов (Python3 concurrent.futures)
У меня есть список из 30 миллионов строк, и я хочу выполнить запрос DNS ко всем из них с помощью Py thon. Я не понимаю, как эта операция может получить интенсивную память. Я предполагаю, что потоки завершат работу после выполнения задания, а также есть тайм-аут в 1 минуту ({'dns_request_timeout': 1}).
Вот краткий обзор ресурсов машины при запуске сценария:
Мой код выглядит следующим образом:
# -*- coding: utf-8 -*-
import dns.resolver
import concurrent.futures
from pprint import pprint
from json import json
bucket = json.load(open('30_million_strings.json','r'))
def _dns_query(target, **kwargs):
global bucket
resolv = dns.resolver.Resolver()
resolv.timeout = kwargs['function']['dns_request_timeout']
try:
resolv.query(target + '.com', kwargs['function']['query_type'])
with open('out.txt', 'a') as f:
f.write(target + '\n')
except Exception:
pass
def run(**kwargs):
global bucket
temp_locals = locals()
pprint({k: v for k, v in temp_locals.items()})
with concurrent.futures.ThreadPoolExecutor(max_workers=kwargs['concurrency']['threads']) as executor:
future_to_element = dict()
for element in bucket:
future = executor.submit(kwargs['function']['name'], element, **kwargs)
future_to_element[future] = element
for future in concurrent.futures.as_completed(future_to_element):
result = future_to_element[future]
run(function={'name': _dns_query, 'dns_request_timeout': 1, 'query_type': 'MX'},
concurrency={'threads': 15})
1 ответ
Попробуй это:
def sure_ok(future):
try:
with open('out.txt', 'a') as f:
f.write(str(future.result()[0]) + '\n')
except:
pass
with concurrent.futures.ThreadPoolExecutor(max_workers=2500):
for element in json.load(open('30_million_strings.json','r')):
resolv = dns.resolver.Resolver()
resolv.timeout = 1
future = executor.submit(resolv.query, target + '.com', 'MX')
future.add_done_callback(sure_ok)
Удалить global bucket
как это избыточно, и не нужно.
удалить ссылку на более 30 миллионов фьючерсов в словаре, также избыточно.
также вы, вероятно, не используете достаточно новую версию concurrent.futures
: